// 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 'package:flutter/scheduler.dart' show timeDilation;

final Map<int, Color> m2SwatchColors = <int, Color>{
  50: const Color(0xfff2e7fe),
  100: const Color(0xffd7b7fd),
  200: const Color(0xffbb86fc),
  300: const Color(0xff9e55fc),
  400: const Color(0xff7f22fd),
  500: const Color(0xff6200ee),
  600: const Color(0xff4b00d1),
  700: const Color(0xff3700b3),
  800: const Color(0xff270096),
  900: const Color(0xff270096),
};
final MaterialColor m2Swatch = MaterialColor(m2SwatchColors[500]!.value, m2SwatchColors);

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  static const String _title = 'Density Test';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(title: _title, home: MyHomePage());
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class OptionModel extends ChangeNotifier {
  double get size => _size;
  double _size = 1.0;
  set size(double size) {
    if (size != _size) {
      _size = size;
      notifyListeners();
    }
  }

  VisualDensity get density => _density;
  VisualDensity _density = VisualDensity.standard;
  set density(VisualDensity density) {
    if (density != _density) {
      _density = density;
      notifyListeners();
    }
  }

  bool get enable => _enable;
  bool _enable = true;
  set enable(bool enable) {
    if (enable != _enable) {
      _enable = enable;
      notifyListeners();
    }
  }

  bool get slowAnimations => _slowAnimations;
  bool _slowAnimations = false;
  set slowAnimations(bool slowAnimations) {
    if (slowAnimations != _slowAnimations) {
      _slowAnimations = slowAnimations;
      notifyListeners();
    }
  }

  bool get rtl => _rtl;
  bool _rtl = false;
  set rtl(bool rtl) {
    if (rtl != _rtl) {
      _rtl = rtl;
      notifyListeners();
    }
  }

  bool get longText => _longText;
  bool _longText = false;

  void reset() {
    final defaultModel = OptionModel();
    _size = defaultModel.size;
    _enable = defaultModel.enable;
    _slowAnimations = defaultModel.slowAnimations;
    _longText = defaultModel.longText;
    _density = defaultModel.density;
    _rtl = defaultModel.rtl;
    notifyListeners();
  }
}

class LabeledCheckbox extends StatelessWidget {
  const LabeledCheckbox({super.key, required this.label, this.onChanged, this.value});

  final String label;
  final ValueChanged<bool?>? onChanged;
  final bool? value;

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        Checkbox(onChanged: onChanged, value: value),
        Text(label),
      ],
    );
  }
}

class Options extends StatefulWidget {
  const Options(this.model, {super.key});

  final OptionModel model;

  @override
  State<Options> createState() => _OptionsState();
}

class _OptionsState extends State<Options> {
  @override
  void initState() {
    super.initState();
    widget.model.addListener(_modelChanged);
  }

  @override
  void didUpdateWidget(Options oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.model != oldWidget.model) {
      oldWidget.model.removeListener(_modelChanged);
      widget.model.addListener(_modelChanged);
    }
  }

  @override
  void dispose() {
    super.dispose();
    widget.model.removeListener(_modelChanged);
  }

  void _modelChanged() {
    setState(() {});
  }

  double sliderValue = 0.0;

  String _densityToProfile(VisualDensity density) {
    return switch (density) {
      VisualDensity.standard => 'standard',
      VisualDensity.compact => 'compact',
      VisualDensity.comfortable => 'comfortable',
      _ => 'custom',
    };
  }

  VisualDensity _profileToDensity(String? profile) {
    return switch (profile) {
      'standard' => VisualDensity.standard,
      'comfortable' => VisualDensity.comfortable,
      'compact' => VisualDensity.compact,
      'custom' || _ => widget.model.density,
    };
  }

  @override
  Widget build(BuildContext context) {
    final SliderThemeData controlTheme = SliderTheme.of(context).copyWith(
      thumbColor: Colors.grey[50],
      activeTickMarkColor: Colors.deepPurple[200],
      activeTrackColor: Colors.deepPurple[300],
      inactiveTrackColor: Colors.grey[50],
    );

    return Padding(
      padding: const EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 10.0),
      child: Builder(
        builder: (BuildContext context) {
          return DefaultTextStyle(
            style: TextStyle(color: Colors.grey[50]),
            child: Column(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(
                    children: <Widget>[
                      const Text('Text Scale'),
                      Expanded(
                        child: SliderTheme(
                          data: controlTheme,
                          child: Slider(
                            label: '${widget.model.size}',
                            min: 0.5,
                            max: 3.0,
                            onChanged: (double value) {
                              widget.model.size = value;
                            },
                            value: widget.model.size,
                          ),
                        ),
                      ),
                      Text(
                        widget.model.size.toStringAsFixed(3),
                        style: TextStyle(color: Colors.grey[50]),
                      ),
                    ],
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(
                    children: <Widget>[
                      const Text('X Density'),
                      Expanded(
                        child: SliderTheme(
                          data: controlTheme,
                          child: Slider(
                            label: widget.model.density.horizontal.toStringAsFixed(1),
                            min: VisualDensity.minimumDensity,
                            max: VisualDensity.maximumDensity,
                            onChanged: (double value) {
                              widget.model.density = widget.model.density.copyWith(
                                horizontal: value,
                                vertical: widget.model.density.vertical,
                              );
                            },
                            value: widget.model.density.horizontal,
                          ),
                        ),
                      ),
                      Text(
                        widget.model.density.horizontal.toStringAsFixed(3),
                        style: TextStyle(color: Colors.grey[50]),
                      ),
                    ],
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Row(
                    children: <Widget>[
                      const Text('Y Density'),
                      Expanded(
                        child: SliderTheme(
                          data: controlTheme,
                          child: Slider(
                            label: widget.model.density.vertical.toStringAsFixed(1),
                            min: VisualDensity.minimumDensity,
                            max: VisualDensity.maximumDensity,
                            onChanged: (double value) {
                              widget.model.density = widget.model.density.copyWith(
                                horizontal: widget.model.density.horizontal,
                                vertical: value,
                              );
                            },
                            value: widget.model.density.vertical,
                          ),
                        ),
                      ),
                      Text(
                        widget.model.density.vertical.toStringAsFixed(3),
                        style: TextStyle(color: Colors.grey[50]),
                      ),
                    ],
                  ),
                ),
                Wrap(
                  alignment: WrapAlignment.center,
                  crossAxisAlignment: WrapCrossAlignment.center,
                  children: <Widget>[
                    Theme(
                      data: Theme.of(context).copyWith(canvasColor: Colors.grey[600]),
                      child: DropdownButton<String>(
                        style: TextStyle(color: Colors.grey[50]),
                        isDense: true,
                        onChanged: (String? value) {
                          widget.model.density = _profileToDensity(value);
                        },
                        items: const <DropdownMenuItem<String>>[
                          DropdownMenuItem<String>(value: 'standard', child: Text('Standard')),
                          DropdownMenuItem<String>(
                            value: 'comfortable',
                            child: Text('Comfortable'),
                          ),
                          DropdownMenuItem<String>(value: 'compact', child: Text('Compact')),
                          DropdownMenuItem<String>(value: 'custom', child: Text('Custom')),
                        ],
                        value: _densityToProfile(widget.model.density),
                      ),
                    ),
                    LabeledCheckbox(
                      label: 'Enabled',
                      onChanged: (bool? checked) {
                        widget.model.enable = checked ?? false;
                      },
                      value: widget.model.enable,
                    ),
                    LabeledCheckbox(
                      label: 'Slow',
                      onChanged: (bool? checked) {
                        widget.model.slowAnimations = checked ?? false;
                        Future<void>.delayed(const Duration(milliseconds: 150)).then((_) {
                          if (widget.model.slowAnimations) {
                            timeDilation = 20.0;
                          } else {
                            timeDilation = 1.0;
                          }
                        });
                      },
                      value: widget.model.slowAnimations,
                    ),
                    LabeledCheckbox(
                      label: 'RTL',
                      onChanged: (bool? checked) {
                        widget.model.rtl = checked ?? false;
                      },
                      value: widget.model.rtl,
                    ),
                    MaterialButton(
                      onPressed: () {
                        widget.model.reset();
                        sliderValue = 0.0;
                      },
                      child: Text('Reset', style: TextStyle(color: Colors.grey[50])),
                    ),
                  ],
                ),
              ],
            ),
          );
        },
      ),
    );
  }
}

class _ControlTile extends StatelessWidget {
  const _ControlTile({required this.label, required this.child});

  final String label;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: <Widget>[
            Align(
              alignment: AlignmentDirectional.topStart,
              child: Text(label, textAlign: TextAlign.start),
            ),
            child,
          ],
        ),
      ),
    );
  }
}

class _MyHomePageState extends State<MyHomePage> {
  static final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  final OptionModel _model = OptionModel();
  final TextEditingController textController = TextEditingController();

  @override
  void initState() {
    super.initState();
    _model.addListener(_modelChanged);
  }

  @override
  void dispose() {
    super.dispose();
    _model.removeListener(_modelChanged);
  }

  void _modelChanged() {
    setState(() {});
  }

  double sliderValue = 0.0;
  List<bool> checkboxValues = <bool>[false, false, false, false];
  List<IconData> iconValues = <IconData>[Icons.arrow_back, Icons.play_arrow, Icons.arrow_forward];
  List<String> chipValues = <String>['Potato', 'Computer'];
  int radioValue = 0;

  @override
  Widget build(BuildContext context) {
    final theme = ThemeData(primarySwatch: m2Swatch);
    final Widget label = Text(_model.rtl ? 'اضغط علي' : 'Press Me');
    textController.text = _model.rtl
        ? 'يعتمد القرار الجيد على المعرفة وليس على الأرقام.'
        : 'A good decision is based on knowledge and not on numbers.';

    final tiles = <Widget>[
      _ControlTile(
        label: _model.rtl ? 'حقل النص' : 'List Tile',
        child: SizedBox(
          width: 400,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ListTile(
                title: Text(
                  _model.rtl ? 'هذا عنوان طويل نسبيا' : 'This is a relatively long title',
                ),
                onTap: () {},
              ),
              ListTile(
                title: Text(_model.rtl ? 'هذا عنوان قصير' : 'This is a short title'),
                subtitle: Text(
                  _model.rtl ? 'هذا عنوان فرعي مناسب.' : 'This is an appropriate subtitle.',
                ),
                trailing: const Icon(Icons.check_box),
                onTap: () {},
              ),
              ListTile(
                title: Text(_model.rtl ? 'هذا عنوان قصير' : 'This is a short title'),
                subtitle: Text(
                  _model.rtl ? 'هذا عنوان فرعي مناسب.' : 'This is an appropriate subtitle.',
                ),
                leading: const Icon(Icons.check_box),
                dense: true,
                onTap: () {},
              ),
              ListTile(
                title: Text(_model.rtl ? 'هذا عنوان قصير' : 'This is a short title'),
                subtitle: Text(
                  _model.rtl ? 'هذا عنوان فرعي مناسب.' : 'This is an appropriate subtitle.',
                ),
                dense: true,
                leading: const Icon(Icons.add_box),
                trailing: const Icon(Icons.check_box),
                onTap: () {},
              ),
              ListTile(
                title: Text(_model.rtl ? 'هذا عنوان قصير' : 'This is a short title'),
                subtitle: Text(
                  _model.rtl ? 'هذا عنوان فرعي مناسب.' : 'This is an appropriate subtitle.',
                ),
                isThreeLine: true,
                leading: const Icon(Icons.add_box),
                trailing: const Icon(Icons.check_box),
                onTap: () {},
              ),
            ],
          ),
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'حقل النص' : 'Text Field',
        child: SizedBox(
          width: 300,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextField(
                controller: textController,
                decoration: const InputDecoration(
                  hintText: 'Hint',
                  helperText: 'Helper',
                  labelText: 'Label',
                  border: OutlineInputBorder(),
                ),
              ),
              TextField(controller: textController),
              TextField(controller: textController, maxLines: 3),
            ],
          ),
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'رقائق' : 'Chips',
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List<Widget>.generate(chipValues.length, (int index) {
            return InputChip(
              onPressed: _model.enable ? () {} : null,
              onDeleted: _model.enable ? () {} : null,
              label: Text(chipValues[index]),
              deleteIcon: const Icon(Icons.delete),
              avatar: const Icon(Icons.play_arrow),
            );
          }),
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'زر المواد' : 'Material Button',
        child: MaterialButton(
          color: m2Swatch[200],
          onPressed: _model.enable ? () {} : null,
          child: label,
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'زر مسطح' : 'Text Button',
        child: TextButton(
          style: TextButton.styleFrom(
            foregroundColor: Colors.white,
            backgroundColor: m2Swatch[200],
          ),
          onPressed: _model.enable ? () {} : null,
          child: label,
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'أثارت زر' : 'Elevated Button',
        child: ElevatedButton(
          style: TextButton.styleFrom(backgroundColor: m2Swatch[200]),
          onPressed: _model.enable ? () {} : null,
          child: label,
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'زر المخطط التفصيلي' : 'Outlined Button',
        child: OutlinedButton(onPressed: _model.enable ? () {} : null, child: label),
      ),
      _ControlTile(
        label: _model.rtl ? 'خانات الاختيار' : 'Checkboxes',
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List<Widget>.generate(checkboxValues.length, (int index) {
            return Checkbox(
              onChanged: _model.enable
                  ? (bool? value) {
                      setState(() {
                        checkboxValues[index] = value ?? false;
                      });
                    }
                  : null,
              value: checkboxValues[index],
            );
          }),
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'زر الراديو' : 'Radio Button',
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List<Widget>.generate(4, (int index) {
            return Radio<int>(
              onChanged: _model.enable
                  ? (int? value) {
                      setState(() {
                        radioValue = value!;
                      });
                    }
                  : null,
              groupValue: radioValue,
              value: index,
            );
          }),
        ),
      ),
      _ControlTile(
        label: _model.rtl ? 'زر الأيقونة' : 'Icon Button',
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: List<Widget>.generate(iconValues.length, (int index) {
            return IconButton(
              onPressed: _model.enable ? () {} : null,
              icon: Icon(iconValues[index]),
            );
          }),
        ),
      ),
    ];

    return SafeArea(
      child: Theme(
        data: theme,
        child: Scaffold(
          key: scaffoldKey,
          appBar: AppBar(
            title: const Text('Density'),
            bottom: PreferredSize(
              preferredSize: const Size.fromHeight(220.0),
              child: Options(_model),
            ),
            backgroundColor: const Color(0xff323232),
          ),
          body: DefaultTextStyle(
            style: const TextStyle(
              color: Colors.black,
              fontSize: 14.0,
              fontFamily: 'Roboto',
              fontStyle: FontStyle.normal,
            ),
            child: Theme(
              data: Theme.of(context).copyWith(visualDensity: _model.density),
              child: Directionality(
                textDirection: _model.rtl ? TextDirection.rtl : TextDirection.ltr,
                child: Builder(
                  builder: (BuildContext context) {
                    final MediaQueryData mediaQueryData = MediaQuery.of(context);
                    return MediaQuery(
                      data: mediaQueryData.copyWith(textScaler: TextScaler.linear(_model.size)),
                      child: SizedBox.expand(child: ListView(children: tiles)),
                    );
                  },
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
