// 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 '../../gallery/demo.dart';

class IconsDemo extends StatefulWidget {
  static const String routeName = '/material/icons';

  @override
  IconsDemoState createState() => IconsDemoState();
}

class IconsDemoState extends State<IconsDemo> {
  static final List<MaterialColor> iconColors = <MaterialColor>[
    Colors.red,
    Colors.pink,
    Colors.purple,
    Colors.deepPurple,
    Colors.indigo,
    Colors.blue,
    Colors.lightBlue,
    Colors.cyan,
    Colors.teal,
    Colors.green,
    Colors.lightGreen,
    Colors.lime,
    Colors.yellow,
    Colors.amber,
    Colors.orange,
    Colors.deepOrange,
    Colors.brown,
    Colors.grey,
    Colors.blueGrey,
  ];

  int iconColorIndex = 8; // teal

  Color get iconColor => iconColors[iconColorIndex];

  void handleIconButtonPress() {
    setState(() {
      iconColorIndex = (iconColorIndex + 1) % iconColors.length;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Icons'),
        actions: <Widget>[MaterialDemoDocumentationButton(IconsDemo.routeName)],
      ),
      body: IconTheme(
        data: IconThemeData(color: iconColor),
        child: SafeArea(
          top: false,
          bottom: false,
          child: Scrollbar(
            child: ListView(
              padding: const EdgeInsets.all(24.0),
              children: <Widget>[
                _IconsDemoCard(handleIconButtonPress, Icons.face), // direction-agnostic icon
                const SizedBox(height: 24.0),
                _IconsDemoCard(handleIconButtonPress, Icons.battery_unknown), // direction-aware icon
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class _IconsDemoCard extends StatelessWidget {
  const _IconsDemoCard(this.handleIconButtonPress, this.icon);

  final VoidCallback handleIconButtonPress;
  final IconData icon;

  Widget _buildIconButton(double iconSize, IconData icon, bool enabled) {
    return IconButton(
      icon: Icon(icon),
      iconSize: iconSize,
      tooltip: "${enabled ? 'Enabled' : 'Disabled'} icon button",
      onPressed: enabled ? handleIconButtonPress : null,
    );
  }

  Widget _centeredText(String label) =>
    Padding(
      // Match the default padding of IconButton.
      padding: const EdgeInsets.all(8.0),
      child: Text(label, textAlign: TextAlign.center),
    );

  TableRow _buildIconRow(double size) {
    return TableRow(
      children: <Widget> [
        _centeredText('${size.floor().toString()} ${icon.toString()}'),
        _buildIconButton(size, icon, true),
        _buildIconButton(size, icon, false),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    final TextStyle textStyle = theme.textTheme.subtitle1.copyWith(color: theme.textTheme.caption.color);
    return Card(
      child: DefaultTextStyle(
        style: textStyle,
        child: Semantics(
          explicitChildNodes: true,
          child: Table(
            defaultVerticalAlignment: TableCellVerticalAlignment.middle,
            children: <TableRow> [
              TableRow(
                children: <Widget> [
                  _centeredText('Size ${icon.toString()}'),
                  _centeredText('Enabled ${icon.toString()}'),
                  _centeredText('Disabled ${icon.toString()}'),
                ]
              ),
              _buildIconRow(18.0),
              _buildIconRow(24.0),
              _buildIconRow(36.0),
              _buildIconRow(48.0),
            ],
          ),
        ),
      ),
    );
  }
}
