// 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';

enum BannerDemoAction {
  reset,
  showMultipleActions,
  showLeading,
}

class BannerDemo extends StatefulWidget {
  const BannerDemo({ Key? key }) : super(key: key);

  static const String routeName = '/material/banner';

  @override
  State<BannerDemo> createState() => _BannerDemoState();
}

class _BannerDemoState extends State<BannerDemo> {
  static const int _numItems = 20;
  bool _displayBanner = true;
  bool _showMultipleActions = true;
  bool _showLeading = true;

  void handleDemoAction(BannerDemoAction action) {
    setState(() {
      switch (action) {
        case BannerDemoAction.reset:
          _displayBanner = true;
          _showMultipleActions = true;
          _showLeading = true;
          break;
        case BannerDemoAction.showMultipleActions:
          _showMultipleActions = !_showMultipleActions;
          break;
        case BannerDemoAction.showLeading:
          _showLeading = !_showLeading;
          break;
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final Widget banner = MaterialBanner(
      content: const Text('Your password was updated on your other device. Please sign in again.'),
      leading: _showLeading ? const CircleAvatar(child: Icon(Icons.access_alarm)) : null,
      actions: <Widget>[
        TextButton(
          child: const Text('SIGN IN'),
          onPressed: () {
            setState(() {
              _displayBanner = false;
            });
          },
        ),
        if (_showMultipleActions)
          TextButton(
            child: const Text('DISMISS'),
            onPressed: () {
              setState(() {
                _displayBanner = false;
              });
            },
          ),
      ],
    );

    return Scaffold(
      appBar: AppBar(
        title: const Text('Banner'),
        actions: <Widget>[
          MaterialDemoDocumentationButton(BannerDemo.routeName),
          PopupMenuButton<BannerDemoAction>(
            onSelected: handleDemoAction,
            itemBuilder: (BuildContext context) => <PopupMenuEntry<BannerDemoAction>>[
              const PopupMenuItem<BannerDemoAction>(
                value: BannerDemoAction.reset,
                child: Text('Reset the banner'),
              ),
              const PopupMenuDivider(),
              CheckedPopupMenuItem<BannerDemoAction>(
                value: BannerDemoAction.showMultipleActions,
                checked: _showMultipleActions,
                child: const Text('Multiple actions'),
              ),
              CheckedPopupMenuItem<BannerDemoAction>(
                value: BannerDemoAction.showLeading,
                checked: _showLeading,
                child: const Text('Leading icon'),
              ),
            ],
          ),
        ],
      ),
      body: ListView.builder(itemCount: _displayBanner ? _numItems + 1 : _numItems, itemBuilder: (BuildContext context, int index) {
        if (index == 0 && _displayBanner) {
          return banner;
        }
        return ListTile(title: Text('Item ${_displayBanner ? index : index + 1}'),);
      }),
    );
  }
}
