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

/// Flutter code sample for [MaterialApp].

void main() {
  runApp(const MaterialAppExample());
}

enum AnimationStyles { defaultStyle, custom, none }

const List<(AnimationStyles, String)> animationStyleSegments = <(AnimationStyles, String)>[
  (AnimationStyles.defaultStyle, 'Default'),
  (AnimationStyles.custom, 'Custom'),
  (AnimationStyles.none, 'None'),
];

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

  @override
  State<MaterialAppExample> createState() => _MaterialAppExampleState();
}

class _MaterialAppExampleState extends State<MaterialAppExample> {
  Set<AnimationStyles> _animationStyleSelection = <AnimationStyles>{AnimationStyles.defaultStyle};
  AnimationStyle? _animationStyle;
  bool isDarkTheme = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      themeAnimationStyle: _animationStyle,
      themeMode: isDarkTheme ? ThemeMode.dark : ThemeMode.light,
      theme: ThemeData(colorSchemeSeed: Colors.green),
      darkTheme: ThemeData(colorSchemeSeed: Colors.green, brightness: Brightness.dark),
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SegmentedButton<AnimationStyles>(
                selected: _animationStyleSelection,
                onSelectionChanged: (Set<AnimationStyles> styles) {
                  setState(() {
                    _animationStyleSelection = styles;
                    switch (styles.first) {
                      case AnimationStyles.defaultStyle:
                        _animationStyle = null;
                      case AnimationStyles.custom:
                        _animationStyle = const AnimationStyle(
                          curve: Easing.emphasizedAccelerate,
                          duration: Duration(seconds: 1),
                        );
                      case AnimationStyles.none:
                        _animationStyle = AnimationStyle.noAnimation;
                    }
                  });
                },
                segments: animationStyleSegments.map<ButtonSegment<AnimationStyles>>((
                  (AnimationStyles, String) shirt,
                ) {
                  return ButtonSegment<AnimationStyles>(value: shirt.$1, label: Text(shirt.$2));
                }).toList(),
              ),
              const SizedBox(height: 10),
              OutlinedButton.icon(
                onPressed: () {
                  setState(() {
                    isDarkTheme = !isDarkTheme;
                  });
                },
                icon: Icon(isDarkTheme ? Icons.wb_sunny : Icons.nightlight_round),
                label: const Text('Switch Theme Mode'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
