// 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 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart' show debugDumpRenderTree;

class CardModel {
  CardModel(this.value, this.height) {
    textController = TextEditingController(text: 'Item $value');
  }
  int value;
  double height;
  int get color => ((value % 9) + 1) * 100;
  TextEditingController textController;
  Key get key => ObjectKey(this);
}

class CardCollection extends StatefulWidget {
  @override
  CardCollectionState createState() => CardCollectionState();
}

class CardCollectionState extends State<CardCollection> {

  static const TextStyle cardLabelStyle =
    TextStyle(color: Colors.white, fontSize: 18.0, fontWeight: FontWeight.bold);

  // TODO(hansmuller): need a local image asset
  static const String _sunshineURL = 'http://www.walltor.com/images/wallpaper/good-morning-sunshine-58540.jpg';

  static const double kCardMargins = 8.0;
  static const double kFixedCardHeight = 100.0;
  static const List<double> _cardHeights = <double>[
    48.0, 63.0, 85.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
    48.0, 63.0, 85.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
    48.0, 63.0, 85.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
  ];

  MaterialColor _primaryColor = Colors.deepPurple;
  List<CardModel> _cardModels;
  DismissDirection _dismissDirection = DismissDirection.horizontal;
  TextAlign _textAlign = TextAlign.center;
  bool _editable = false;
  bool _fixedSizeCards = false;
  bool _sunshine = false;
  bool _varyFontSizes = false;

  void _updateCardSizes() {
    if (_fixedSizeCards)
      return;
    _cardModels = List<CardModel>.generate(
      _cardModels.length,
      (int i) {
        _cardModels[i].height = _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i];
        return _cardModels[i];
      },
    );
  }

  void _initVariableSizedCardModels() {
    _cardModels = List<CardModel>.generate(
      _cardHeights.length,
      (int i) => CardModel(i, _editable ? max(_cardHeights[i], 60.0) : _cardHeights[i]),
    );
  }

  void _initFixedSizedCardModels() {
    const int cardCount = 27;
    _cardModels = List<CardModel>.generate(
      cardCount,
      (int i) => CardModel(i, kFixedCardHeight),
    );
  }

  void _initCardModels() {
    if (_fixedSizeCards)
      _initFixedSizedCardModels();
    else
      _initVariableSizedCardModels();
  }

  @override
  void initState() {
    super.initState();
    _initCardModels();
  }

  void dismissCard(CardModel card) {
    if (_cardModels.contains(card)) {
      setState(() {
        _cardModels.remove(card);
      });
    }
  }

  Widget _buildDrawer() {
    return Drawer(
      child: IconTheme(
        data: const IconThemeData(color: Colors.black),
        child: ListView(
          children: <Widget>[
            const DrawerHeader(child: Center(child: Text('Options'))),
            buildDrawerCheckbox('Make card labels editable', _editable, _toggleEditable),
            buildDrawerCheckbox('Fixed size cards', _fixedSizeCards, _toggleFixedSizeCards),
            buildDrawerCheckbox('Let the sun shine', _sunshine, _toggleSunshine),
            buildDrawerCheckbox('Vary font sizes', _varyFontSizes, _toggleVaryFontSizes, enabled: !_editable),
            const Divider(),
            buildDrawerColorRadioItem('Deep Purple', Colors.deepPurple, _primaryColor, _selectColor),
            buildDrawerColorRadioItem('Green', Colors.green, _primaryColor, _selectColor),
            buildDrawerColorRadioItem('Amber', Colors.amber, _primaryColor, _selectColor),
            buildDrawerColorRadioItem('Teal', Colors.teal, _primaryColor, _selectColor),
            const Divider(),
            buildDrawerDirectionRadioItem('Dismiss horizontally', DismissDirection.horizontal, _dismissDirection, _changeDismissDirection, icon: Icons.code),
            buildDrawerDirectionRadioItem('Dismiss left', DismissDirection.endToStart, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_back),
            buildDrawerDirectionRadioItem('Dismiss right', DismissDirection.startToEnd, _dismissDirection, _changeDismissDirection, icon: Icons.arrow_forward),
            const Divider(),
            buildFontRadioItem('Left-align text', TextAlign.left, _textAlign, _changeTextAlign, icon: Icons.format_align_left, enabled: !_editable),
            buildFontRadioItem('Center-align text', TextAlign.center, _textAlign, _changeTextAlign, icon: Icons.format_align_center, enabled: !_editable),
            buildFontRadioItem('Right-align text', TextAlign.right, _textAlign, _changeTextAlign, icon: Icons.format_align_right, enabled: !_editable),
            const Divider(),
            ListTile(
              leading: const Icon(Icons.dvr),
              onTap: () { debugDumpApp(); debugDumpRenderTree(); },
              title: const Text('Dump App to Console'),
            ),
          ],
        ),
      ),
    );
  }

  String _dismissDirectionText(DismissDirection direction) {
    final String s = direction.toString();
    return "dismiss ${s.substring(s.indexOf('.') + 1)}";
  }

  void _toggleEditable() {
    setState(() {
      _editable = !_editable;
      _updateCardSizes();
    });
  }

  void _toggleFixedSizeCards() {
    setState(() {
      _fixedSizeCards = !_fixedSizeCards;
      _initCardModels();
    });
  }

  void _toggleSunshine() {
    setState(() {
      _sunshine = !_sunshine;
    });
  }

  void _toggleVaryFontSizes() {
    setState(() {
      _varyFontSizes = !_varyFontSizes;
    });
  }

  void _selectColor(MaterialColor selection) {
    setState(() {
      _primaryColor = selection;
    });
  }

  void _changeDismissDirection(DismissDirection newDismissDirection) {
    setState(() {
      _dismissDirection = newDismissDirection;
    });
  }

  void _changeTextAlign(TextAlign newTextAlign) {
    setState(() {
      _textAlign = newTextAlign;
    });
  }

  Widget buildDrawerCheckbox(String label, bool value, void callback(), { bool enabled = true }) {
    return ListTile(
      onTap: enabled ? callback : null,
      title: Text(label),
      trailing: Checkbox(
        value: value,
        onChanged: enabled ? (_) { callback(); } : null,
      ),
    );
  }

  Widget buildDrawerColorRadioItem(String label, MaterialColor itemValue, MaterialColor currentValue, ValueChanged<MaterialColor> onChanged, { IconData icon, bool enabled = true }) {
    return ListTile(
      leading: Icon(icon),
      title: Text(label),
      onTap: enabled ? () { onChanged(itemValue); } : null,
      trailing: Radio<MaterialColor>(
        value: itemValue,
        groupValue: currentValue,
        onChanged: enabled ? onChanged : null,
      ),
    );
  }

  Widget buildDrawerDirectionRadioItem(String label, DismissDirection itemValue, DismissDirection currentValue, ValueChanged<DismissDirection> onChanged, { IconData icon, bool enabled = true }) {
    return ListTile(
      leading: Icon(icon),
      title: Text(label),
      onTap: enabled ? () { onChanged(itemValue); } : null,
      trailing: Radio<DismissDirection>(
        value: itemValue,
        groupValue: currentValue,
        onChanged: enabled ? onChanged : null,
      ),
    );
  }

  Widget buildFontRadioItem(String label, TextAlign itemValue, TextAlign currentValue, ValueChanged<TextAlign> onChanged, { IconData icon, bool enabled = true }) {
    return ListTile(
      leading: Icon(icon),
      title: Text(label),
      onTap: enabled ? () { onChanged(itemValue); } : null,
      trailing: Radio<TextAlign>(
        value: itemValue,
        groupValue: currentValue,
        onChanged: enabled ? onChanged : null,
      ),
    );
  }

  Widget _buildAppBar(BuildContext context) {
    return AppBar(
      actions: <Widget>[
        Text(_dismissDirectionText(_dismissDirection)),
      ],
      flexibleSpace: Container(
        padding: const EdgeInsets.only(left: 72.0),
        height: 128.0,
        alignment: const Alignment(-1.0, 0.5),
        child: Text('Swipe Away: ${_cardModels.length}', style: Theme.of(context).primaryTextTheme.title),
      ),
    );
  }

  Widget _buildCard(BuildContext context, int index) {
    final CardModel cardModel = _cardModels[index];
    final Widget card = Dismissible(
      key: ObjectKey(cardModel),
      direction: _dismissDirection,
      onDismissed: (DismissDirection direction) { dismissCard(cardModel); },
      child: Card(
        color: _primaryColor[cardModel.color],
        child: Container(
          height: cardModel.height,
          padding: const EdgeInsets.all(kCardMargins),
          child: _editable ?
            Center(
              child: TextField(
                key: GlobalObjectKey(cardModel),
                controller: cardModel.textController,
              ),
            )
          : DefaultTextStyle.merge(
              style: cardLabelStyle.copyWith(
                fontSize: _varyFontSizes ? 5.0 + index : null
              ),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.stretch,
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  Text(cardModel.textController.text, textAlign: _textAlign),
                ],
              ),
            ),
        ),
      ),
    );

    String backgroundMessage;
    switch (_dismissDirection) {
      case DismissDirection.horizontal:
        backgroundMessage = 'Swipe in either direction';
        break;
      case DismissDirection.endToStart:
        backgroundMessage = 'Swipe left to dismiss';
        break;
      case DismissDirection.startToEnd:
        backgroundMessage = 'Swipe right to dismiss';
        break;
      default:
        backgroundMessage = 'Unsupported dismissDirection';
    }

    // TODO(abarth): This icon is wrong in RTL.
    Widget leftArrowIcon = const Icon(Icons.arrow_back, size: 36.0);
    if (_dismissDirection == DismissDirection.startToEnd)
      leftArrowIcon = Opacity(opacity: 0.1, child: leftArrowIcon);

      // TODO(abarth): This icon is wrong in RTL.
    Widget rightArrowIcon = const Icon(Icons.arrow_forward, size: 36.0);
    if (_dismissDirection == DismissDirection.endToStart)
      rightArrowIcon = Opacity(opacity: 0.1, child: rightArrowIcon);

    final ThemeData theme = Theme.of(context);
    final TextStyle backgroundTextStyle = theme.primaryTextTheme.title;

    // The background Widget appears behind the Dismissible card when the card
    // moves to the left or right. The Positioned widget ensures that the
    // size of the background,card Stack will be based only on the card. The
    // Viewport ensures that when the card's resize animation occurs, the
    // background (text and icons) will just be clipped, not resized.
    final Widget background = Positioned.fill(
      child: Container(
        margin: const EdgeInsets.all(4.0),
        child: SingleChildScrollView(
          child: Container(
            height: cardModel.height,
            color: theme.primaryColor,
            child: Row(
              children: <Widget>[
                leftArrowIcon,
                Expanded(
                  child: Text(backgroundMessage,
                    style: backgroundTextStyle,
                    textAlign: TextAlign.center,
                  ),
                ),
                rightArrowIcon,
              ],
            ),
          ),
        ),
      ),
    );

    return IconTheme(
      key: cardModel.key,
      data: const IconThemeData(color: Colors.white),
      child: Stack(children: <Widget>[background, card]),
    );
  }

  Shader _createShader(Rect bounds) {
    return const LinearGradient(
        begin: Alignment.topCenter,
        end: Alignment.bottomCenter,
        colors: <Color>[Color(0x00FFFFFF), Color(0xFFFFFFFF)],
        stops: <double>[0.1, 0.35],
    )
    .createShader(bounds);
  }

  @override
  Widget build(BuildContext context) {
    Widget cardCollection = ListView.builder(
      itemExtent: _fixedSizeCards ? kFixedCardHeight : null,
      itemCount: _cardModels.length,
      itemBuilder: _buildCard,
    );

    if (_sunshine) {
      cardCollection = Stack(
        children: <Widget>[
          Column(children: <Widget>[Image.network(_sunshineURL)]),
          ShaderMask(child: cardCollection, shaderCallback: _createShader),
        ],
      );
    }

    final Widget body = Container(
      padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 8.0),
      color: _primaryColor.shade50,
      child: cardCollection,
    );

    return Theme(
      data: ThemeData(
        primarySwatch: _primaryColor,
      ),
      child: Scaffold(
        appBar: _buildAppBar(context),
        drawer: _buildDrawer(),
        body: body,
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    title: 'Cards',
    home: CardCollection(),
  ));
}
