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

import 'package:flutter/material.dart';

class CardModel {
  CardModel(this.value, this.height) :
    textController = TextEditingController(text: 'Item $value');

  int value;
  double height;
  int get color => ((value % 9) + 1) * 100;
  final TextEditingController textController;
  Key get key => ObjectKey(this);
}

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

  @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 = <CardModel>[];
  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 Function() 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,
      ),
    );
  }

  AppBar _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.headline6),
      ),
    );
  }

  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;
      case DismissDirection.vertical:
      case DismissDirection.up:
      case DismissDirection.down:
      case DismissDirection.none:
        backgroundMessage = 'Unsupported dismissDirection';
        break;
    }

    // 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);
    }

    // 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.headline6;

    // 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(shaderCallback: _createShader, child: cardCollection),
        ],
      );
    }

    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(const MaterialApp(
    title: 'Cards',
    home: CardCollection(),
  ));
}
