// Copyright 2015 The Chromium 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(
    new ComplexLayoutApp()
  );
}

class ComplexLayoutApp extends StatefulWidget {
  @override
  ComplexLayoutAppState createState() => new ComplexLayoutAppState();

  static ComplexLayoutAppState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<ComplexLayoutAppState>());
}

class ComplexLayoutAppState extends State<ComplexLayoutApp> {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      theme: lightTheme ? new ThemeData.light() : new ThemeData.dark(),
      title: 'Advanced Layout',
      routes: <String, WidgetBuilder>{
        '/': (BuildContext context) => new ComplexLayout(),
      }
    );
  }

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

class ComplexLayout extends StatefulWidget {
  ComplexLayout({ Key key }) : super(key: key);

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

  static ComplexLayoutState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<ComplexLayoutState>());

}

class FancyItemDelegate extends LazyBlockDelegate {
  @override
  Widget buildItem(BuildContext context, int index) {
    if (index % 2 == 0)
      return new FancyImageItem(index, key: new Key("Item $index"));
    else
      return new FancyGalleryItem(index, key: new Key("Item $index"));
  }

  @override
  bool shouldRebuild(FancyItemDelegate oldDelegate) => false;
}

class ComplexLayoutState extends State<ComplexLayout> {
  @override
  Widget build(BuildContext context) {

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Advanced Layout'),
        actions: <Widget>[
          new IconButton(
            icon: Icons.create,
            tooltip: 'Search',
            onPressed: () {
              print("Pressed search");
            }
          ),
          new TopBarMenu()
        ]
      ),
      body: new Column(
        children: <Widget>[
          new Flexible(
            child: new LazyBlock(
              key: new Key("main-scroll"),
              delegate: new FancyItemDelegate()
            )
          ),
          new BottomBar()
        ]
      ),
      drawer: new GalleryDrawer()
    );
  }
}

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

class MenuItemWithIcon extends StatelessWidget {
  MenuItemWithIcon(this.icon, this.title, this.subtitle);

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

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

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

  final int index;

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

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

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

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

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

class IconWithText extends StatelessWidget {
  IconWithText(this.icon, this.title);

  final IconData icon;
  final String title;

  @override
  Widget build(BuildContext context) {
    return new Row(
      mainAxisAlignment: MainAxisAlignment.collapse,
      children: <Widget>[
        new IconButton(icon: icon, onPressed: () { print("Pressed $title button"); } ),
        new Text(title)
      ]
    );
  }
}

class MiniIconWithText extends StatelessWidget {
  MiniIconWithText(this.icon, this.title);

  final IconData icon;
  final String title;

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

class FatDivider extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 8.0,
      decoration: new BoxDecoration(
        backgroundColor: Theme.of(context).dividerColor
      )
    );
  }
}

class UserHeader extends StatelessWidget {
  UserHeader(this.userName);

  final String userName;

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

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

class ItemImageBox extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Padding(
      padding: new EdgeInsets.all(8.0),
      child: new Card(
        child: new Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            new Stack(
              children: <Widget>[
                new SizedBox(
                  height: 230.0,
                  child: new AssetImage(
                    name: "packages/flutter_gallery_assets/top_10_australian_beaches.png"
                  )
                ),
                new Theme(
                  data: new ThemeData.dark(),
                  child: new Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      new IconButton(icon: Icons.edit, onPressed: () { print("Pressed edit button"); }),
                      new IconButton(icon: Icons.zoom_in, onPressed: () { print("Pressed zoom button"); })
                    ]
                  )
                ),
                new Positioned(
                  bottom: 4.0,
                  left: 4.0,
                  child: new Container(
                    decoration: new BoxDecoration(
                      backgroundColor: Colors.black54,
                      borderRadius: 2.0
                    ),
                    padding: new EdgeInsets.all(4.0),
                    child: new RichText(
                      text: new TextSpan(
                        style: new TextStyle(color: Colors.white),
                        children: <TextSpan>[
                          new TextSpan(
                            text: "Photo by "
                          ),
                          new TextSpan(
                            style: new TextStyle(fontWeight: FontWeight.bold),
                            text: "Magic Mike"
                          )
                        ]
                      )
                    )
                  )
                )
              ]
            )
            ,
            new Padding(
              padding: new EdgeInsets.all(8.0),
              child: new Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                children: <Widget>[
                  new Text("Where can you find that amazing sunset?", style: Theme.of(context).textTheme.body2),
                  new Text("The sun sets over stinson beach", style: Theme.of(context).textTheme.body1),
                  new Text("flutter.io/amazingsunsets", style: Theme.of(context).textTheme.caption)
                ]
              )
            )
          ]
        )
      )
    );
  }
}

class ItemGalleryBox extends StatelessWidget {
  ItemGalleryBox(this.index);

  final int index;

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

    return new SizedBox(
      height: 200.0,
      child: new TabBarSelection<String>(
        values: tabNames,
        child: new Column(
          children: <Widget>[
            new Flexible(
              child: new TabBarView(
                children: tabNames.map((String tabName) {
                  return new Container(
                    key: new Key("Tab $index - $tabName"),
                    child: new Padding(
                      padding: new EdgeInsets.all(8.0),
                      child: new Card(
                        child: new Column(
                          children: <Widget>[
                            new Flexible(
                              child: new Container(
                                decoration: new BoxDecoration(
                                  backgroundColor: Theme.of(context).primaryColor
                                ),
                                child: new Center(
                                  child: new Text(tabName, style: Theme.of(context).textTheme.headline.copyWith(color: Colors.white))
                                )
                              )
                            ),
                            new Row(
                              children: <Widget>[
                                new IconButton(
                                  icon: Icons.share,
                                  onPressed: () { print("Pressed share"); }
                                ),
                                new IconButton(
                                  icon: Icons.event,
                                  onPressed: () { print("Pressed event"); }
                                ),
                                new Flexible(
                                  child: new Padding(
                                    padding: new EdgeInsets.only(left: 8.0),
                                    child: new Text("This is item $tabName")
                                  )
                                )
                              ]
                            )
                          ]
                        )
                      )
                    )
                  );
                }).toList()
              )
            ),
            new Container(
              child: new TabPageSelector<String>()
            )
          ]
        )
      )
    );
  }
}

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

class BottomBarButton extends StatelessWidget {
  BottomBarButton(this.icon, this.title);

  final IconData icon;
  final String title;

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

class GalleryDrawer extends StatelessWidget {
  GalleryDrawer({ Key key }) : super(key: key);

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

  void _toggleAnimationSpeed(BuildContext context) {
    ComplexLayoutApp.of(context).setState(() {
      timeDilation = (timeDilation != 1.0) ? 1.0 : 5.0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Drawer(
      child: new Block(
        children: <Widget>[
          new FancyDrawerHeader(),
          new DrawerItem(
            icon: Icons.brightness_5,
            onPressed: () { _changeTheme(context, true); },
            selected: ComplexLayoutApp.of(context).lightTheme,
            child: new Row(
              children: <Widget>[
                new Flexible(child: new Text('Light')),
                new Radio<bool>(
                  value: true,
                  groupValue: ComplexLayoutApp.of(context).lightTheme,
                  onChanged: (bool value) { _changeTheme(context, value); }
                )
              ]
            )
          ),
          new DrawerItem(
            icon: Icons.brightness_7,
            onPressed: () { _changeTheme(context, false); },
            selected: !ComplexLayoutApp.of(context).lightTheme,
            child: new Row(
              children: <Widget>[
                new Flexible(child: new Text('Dark')),
                new Radio<bool>(
                  value: false,
                  groupValue: ComplexLayoutApp.of(context).lightTheme,
                  onChanged: (bool value) { _changeTheme(context, value); }
                )
              ]
            )
          ),
          new Divider(),
          new DrawerItem(
            icon: Icons.hourglass_empty,
            selected: timeDilation != 1.0,
            onPressed: () { _toggleAnimationSpeed(context); },
            child: new Row(
              children: <Widget>[
                new Flexible(child: new Text('Animate Slowly')),
                new Checkbox(
                  value: timeDilation != 1.0,
                  onChanged: (bool value) { _toggleAnimationSpeed(context); }
                )
              ]
            )
          )
        ]
      )
    );
  }
}

class FancyDrawerHeader extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      decoration: new BoxDecoration(
        backgroundColor: Colors.purple[500]
      ),
      height: 200.0
    );
  }
}
