// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation;

void main() {
  runApp(
    const ComplexLayoutApp()
  );
}

enum ScrollMode { complex, tile }

class ComplexLayoutApp extends StatefulWidget {
  const ComplexLayoutApp({super.key});

  @override
  ComplexLayoutAppState createState() => ComplexLayoutAppState();

  static ComplexLayoutAppState? of(BuildContext context) => context.findAncestorStateOfType<ComplexLayoutAppState>();
}

class ComplexLayoutAppState extends State<ComplexLayoutApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: lightTheme ? ThemeData.light() : ThemeData.dark(),
      title: 'Advanced Layout',
      home: scrollMode == ScrollMode.complex ? const ComplexLayout() : const TileScrollLayout());
  }

  bool _lightTheme = true;
  bool get lightTheme => _lightTheme;
  set lightTheme(bool value) {
    setState(() {
      _lightTheme = value;
    });
  }

  ScrollMode _scrollMode = ScrollMode.complex;
  ScrollMode get scrollMode => _scrollMode;
  set scrollMode(ScrollMode mode) {
    setState(() {
      _scrollMode = mode;
    });
  }

  void toggleAnimationSpeed() {
    setState(() {
      timeDilation = (timeDilation != 1.0) ? 1.0 : 5.0;
    });
  }
}

class TileScrollLayout extends StatelessWidget {
  const TileScrollLayout({ super.key });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Tile Scrolling Layout')),
      body: ListView.builder(
        key: const Key('tiles-scroll'),
        itemCount: 200,
        itemBuilder: (BuildContext context, int index) {
          return Padding(
            padding: const EdgeInsets.all(5.0),
            child: Material(
              elevation: (index % 5 + 1).toDouble(),
              color: Colors.white,
              child: const IconBar(),
            ),
          );
        },
      ),
      drawer: const GalleryDrawer(),
    );
  }
}

class ComplexLayout extends StatefulWidget {
  const ComplexLayout({ super.key });

  @override
  ComplexLayoutState createState() => ComplexLayoutState();

  static ComplexLayoutState? of(BuildContext context) => context.findAncestorStateOfType<ComplexLayoutState>();
}

class ComplexLayoutState extends State<ComplexLayout> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Advanced Layout'),
        actions: <Widget>[
          IconButton(
            icon: const Icon(Icons.create),
            tooltip: 'Search',
            onPressed: () {
              print('Pressed search');
            },
          ),
          const TopBarMenu(),
        ],
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: ListView.builder(
              key: const Key('complex-scroll'), // this key is used by the driver test
              controller: ScrollController(),  // So that the scroll offset can be tracked
              itemBuilder: (BuildContext context, int index) {
                if (index.isEven) {
                  return FancyImageItem(index, key: PageStorageKey<int>(index));
                } else {
                  return FancyGalleryItem(index, key: PageStorageKey<int>(index));
                }
              },
            ),
          ),
          const BottomBar(),
        ],
      ),
      drawer: const GalleryDrawer(),
    );
  }
}

class TopBarMenu extends StatelessWidget {
  const TopBarMenu({super.key});

  @override
  Widget build(BuildContext context) {
    return PopupMenuButton<String>(
      onSelected: (String value) { print('Selected: $value'); },
      itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
        const PopupMenuItem<String>(
          value: 'Friends',
          child: MenuItemWithIcon(Icons.people, 'Friends', '5 new'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.event, 'Events', '12 upcoming'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.group, 'Groups', '14'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.image, 'Pictures', '12'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.near_me, 'Nearby', '33'),
        ),
        const PopupMenuItem<String>(
          value: 'Friends',
          child: MenuItemWithIcon(Icons.people, 'Friends', '5'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.event, 'Events', '12'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.group, 'Groups', '14'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.image, 'Pictures', '12'),
        ),
        const PopupMenuItem<String>(
          value: 'Events',
          child: MenuItemWithIcon(Icons.near_me, 'Nearby', '33'),
        ),
      ],
    );
  }
}

class MenuItemWithIcon extends StatelessWidget {
  const MenuItemWithIcon(this.icon, this.title, this.subtitle, {super.key});

  final IconData icon;
  final String title;
  final String subtitle;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        Icon(icon),
        Padding(
          padding: const EdgeInsets.only(left: 8.0, right: 8.0),
          child: Text(title),
        ),
        Text(subtitle, style: Theme.of(context).textTheme.caption),
      ],
    );
  }
}

class FancyImageItem extends StatelessWidget {
  const FancyImageItem(this.index, {super.key});

  final int index;

  @override
  Widget build(BuildContext context) {
    return ListBody(
      children: <Widget>[
        UserHeader('Ali Connors $index'),
        const ItemDescription(),
        const ItemImageBox(),
        const InfoBar(),
        const Padding(
          padding: EdgeInsets.symmetric(horizontal: 8.0),
          child: Divider(),
        ),
        const IconBar(),
        const FatDivider(),
      ],
    );
  }
}

class FancyGalleryItem extends StatelessWidget {
  const FancyGalleryItem(this.index, {super.key});

  final int index;
  @override
  Widget build(BuildContext context) {
    return ListBody(
      children: <Widget>[
        const UserHeader('Ali Connors'),
        ItemGalleryBox(index),
        const InfoBar(),
        const Padding(
          padding: EdgeInsets.symmetric(horizontal: 8.0),
          child: Divider(),
        ),
        const IconBar(),
        const FatDivider(),
      ],
    );
  }
}

class InfoBar extends StatelessWidget {
  const InfoBar({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          const MiniIconWithText(Icons.thumb_up, '42'),
          Text('3 Comments', style: Theme.of(context).textTheme.caption),
        ],
      ),
    );
  }
}

class IconBar extends StatelessWidget {
  const IconBar({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.only(left: 16.0, right: 16.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: const <Widget>[
          IconWithText(Icons.thumb_up, 'Like'),
          IconWithText(Icons.comment, 'Comment'),
          IconWithText(Icons.share, 'Share'),
        ],
      ),
    );
  }
}

class IconWithText extends StatelessWidget {
  const IconWithText(this.icon, this.title, {super.key});

  final IconData icon;
  final String title;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        IconButton(
          icon: Icon(icon),
          onPressed: () { print('Pressed $title button'); },
        ),
        Text(title),
      ],
    );
  }
}

class MiniIconWithText extends StatelessWidget {
  const MiniIconWithText(this.icon, this.title, {super.key});

  final IconData icon;
  final String title;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.only(right: 8.0),
          child: Container(
            width: 16.0,
            height: 16.0,
            decoration: BoxDecoration(
              color: Theme.of(context).primaryColor,
              shape: BoxShape.circle,
            ),
            child: Icon(icon, color: Colors.white, size: 12.0),
          ),
        ),
        Text(title, style: Theme.of(context).textTheme.caption),
      ],
    );
  }
}

class FatDivider extends StatelessWidget {
  const FatDivider({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 8.0,
      color: Theme.of(context).dividerColor,
    );
  }
}

class UserHeader extends StatelessWidget {
  const UserHeader(this.userName, {super.key});

  final String userName;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          const Padding(
            padding: EdgeInsets.only(right: 8.0),
            child: Image(
              image: AssetImage('packages/flutter_gallery_assets/people/square/ali.png'),
              width: 32.0,
              height: 32.0,
            ),
          ),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                RichText(text: TextSpan(
                  style: Theme.of(context).textTheme.bodyText2,
                  children: <TextSpan>[
                    TextSpan(text: userName, style: const TextStyle(fontWeight: FontWeight.bold)),
                    const TextSpan(text: ' shared a new '),
                    const TextSpan(text: 'photo', style: TextStyle(fontWeight: FontWeight.bold)),
                  ],
                )),
                Row(
                  children: <Widget>[
                    Text('Yesterday at 11:55 • ', style: Theme.of(context).textTheme.caption),
                    Icon(Icons.people, size: 16.0, color: Theme.of(context).textTheme.caption!.color),
                  ],
                ),
              ],
            ),
          ),
          const TopBarMenu(),
        ],
      ),
    );
  }
}

class ItemDescription extends StatelessWidget {
  const ItemDescription({super.key});

  @override
  Widget build(BuildContext context) {
    return const Padding(
      padding: EdgeInsets.all(8.0),
      child: Text('Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'),
    );
  }
}

class ItemImageBox extends StatelessWidget {
  const ItemImageBox({super.key});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Card(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            Stack(
              children: <Widget>[
                const SizedBox(
                  height: 230.0,
                  child: Image(
                    image: AssetImage('packages/flutter_gallery_assets/places/india_chettinad_silk_maker.png')
                  ),
                ),
                Theme(
                  data: ThemeData.dark(),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      IconButton(
                        icon: const Icon(Icons.edit),
                        onPressed: () { print('Pressed edit button'); },
                      ),
                      IconButton(
                        icon: const Icon(Icons.zoom_in),
                        onPressed: () { print('Pressed zoom button'); },
                      ),
                    ],
                  ),
                ),
                Positioned(
                  bottom: 4.0,
                  left: 4.0,
                  child: Container(
                    decoration: BoxDecoration(
                      color: Colors.black54,
                      borderRadius: BorderRadius.circular(2.0),
                    ),
                    padding: const EdgeInsets.all(4.0),
                    child: RichText(
                      text: const TextSpan(
                        style: TextStyle(color: Colors.white),
                        children: <TextSpan>[
                          TextSpan(
                            text: 'Photo by '
                          ),
                          TextSpan(
                            style: TextStyle(fontWeight: FontWeight.bold),
                            text: 'Chris Godley',
                          ),
                        ],
                      ),
                    ),
                  ),
                ),
              ],
            )
            ,
            Padding(
              padding: const EdgeInsets.all(8.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  Text('Artisans of Southern India', style: Theme.of(context).textTheme.bodyText1),
                  Text('Silk Spinners', style: Theme.of(context).textTheme.bodyText2),
                  Text('Sivaganga, Tamil Nadu', style: Theme.of(context).textTheme.caption),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ItemGalleryBox extends StatelessWidget {
  const ItemGalleryBox(this.index, {super.key});

  final int index;

  @override
  Widget build(BuildContext context) {
    final List<String> tabNames = <String>[
      'A', 'B', 'C', 'D',
    ];

    return SizedBox(
      height: 200.0,
      child: DefaultTabController(
        length: tabNames.length,
        child: Column(
          children: <Widget>[
            Expanded(
              child: TabBarView(
                children: tabNames.map<Widget>((String tabName) {
                  return Container(
                    key: PageStorageKey<String>(tabName),
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Card(
                        child: Column(
                          children: <Widget>[
                            Expanded(
                              child: Container(
                                color: Theme.of(context).primaryColor,
                                child: Center(
                                  child: Text(tabName, style: Theme.of(context).textTheme.headline5!.copyWith(color: Colors.white)),
                                ),
                              ),
                            ),
                            Row(
                              children: <Widget>[
                                IconButton(
                                  icon: const Icon(Icons.share),
                                  onPressed: () { print('Pressed share'); },
                                ),
                                IconButton(
                                  icon: const Icon(Icons.event),
                                  onPressed: () { print('Pressed event'); },
                                ),
                                Expanded(
                                  child: Padding(
                                    padding: const EdgeInsets.only(left: 8.0),
                                    child: Text('This is item $tabName'),
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  );
                }).toList(),
              ),
            ),
            const TabPageSelector(),
          ],
        ),
      ),
    );
  }
}

class BottomBar extends StatelessWidget {
  const BottomBar({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        border: Border(
          top: BorderSide(
            color: Theme.of(context).dividerColor,
          ),
        ),
      ),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: const <Widget>[
          BottomBarButton(Icons.new_releases, 'News'),
          BottomBarButton(Icons.people, 'Requests'),
          BottomBarButton(Icons.chat, 'Messenger'),
          BottomBarButton(Icons.bookmark, 'Bookmark'),
          BottomBarButton(Icons.alarm, 'Alarm'),
        ],
      ),
    );
  }
}

class BottomBarButton extends StatelessWidget {
  const BottomBarButton(this.icon, this.title, {super.key});

  final IconData icon;
  final String title;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: <Widget>[
          IconButton(
            icon: Icon(icon),
            onPressed: () { print('Pressed: $title'); },
          ),
          Text(title, style: Theme.of(context).textTheme.caption),
        ],
      ),
    );
  }
}

class GalleryDrawer extends StatelessWidget {
  const GalleryDrawer({ super.key });

  void _changeTheme(BuildContext context, bool value) {
    ComplexLayoutApp.of(context)?.lightTheme = value;
  }

  void _changeScrollMode(BuildContext context, ScrollMode mode) {
    ComplexLayoutApp.of(context)?.scrollMode = mode;
  }

  @override
  Widget build(BuildContext context) {
    final ScrollMode currentMode = ComplexLayoutApp.of(context)!.scrollMode;
    return Drawer(
      // Note: for real apps, see the Gallery material Drawer demo. More
      // typically, a drawer would have a fixed header with a scrolling body
      // below it.
      child: ListView(
        key: const PageStorageKey<String>('gallery-drawer'),
        padding: EdgeInsets.zero,
        children: <Widget>[
          const FancyDrawerHeader(),
          ListTile(
            key: const Key('scroll-switcher'),
            title: const Text('Scroll Mode'),
            onTap: () {
              _changeScrollMode(context, currentMode == ScrollMode.complex ? ScrollMode.tile : ScrollMode.complex);
             Navigator.pop(context);
            },
            trailing: Text(currentMode == ScrollMode.complex ? 'Tile' : 'Complex'),
          ),
          ListTile(
            leading: const Icon(Icons.brightness_5),
            title: const Text('Light'),
            onTap: () { _changeTheme(context, true); },
            selected: ComplexLayoutApp.of(context)!.lightTheme,
            trailing: Radio<bool>(
              value: true,
              groupValue: ComplexLayoutApp.of(context)!.lightTheme,
              onChanged: (bool? value) { _changeTheme(context, value!); },
            ),
          ),
          ListTile(
            leading: const Icon(Icons.brightness_7),
            title: const Text('Dark'),
            onTap: () { _changeTheme(context, false); },
            selected: !ComplexLayoutApp.of(context)!.lightTheme,
            trailing: Radio<bool>(
              value: false,
              groupValue: ComplexLayoutApp.of(context)!.lightTheme,
              onChanged: (bool? value) { _changeTheme(context, value!); },
            ),
          ),
          const Divider(),
          ListTile(
            leading: const Icon(Icons.hourglass_empty),
            title: const Text('Animate Slowly'),
            selected: timeDilation != 1.0,
            onTap: () { ComplexLayoutApp.of(context)!.toggleAnimationSpeed(); },
            trailing: Checkbox(
              value: timeDilation != 1.0,
              onChanged: (bool? value) { ComplexLayoutApp.of(context)!.toggleAnimationSpeed(); },
            ),
          ),
        ],
      ),
    );
  }
}

class FancyDrawerHeader extends StatelessWidget {
  const FancyDrawerHeader({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.purple,
      height: 200.0,
      child: const SafeArea(
        bottom: false,
        child: Placeholder(),
      ),
    );
  }
}
