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

class CardModel {
  CardModel(this.value, this.size, this.color);
  int value;
  Size size;
  Color color;
  String get label => 'Card $value';
  Key get key => ObjectKey(this);
}

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

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

class PageViewAppState extends State<PageViewApp> {
  @override
  void initState() {
    super.initState();
    const cardSizes = <Size>[
      Size(100.0, 300.0),
      Size(300.0, 100.0),
      Size(200.0, 400.0),
      Size(400.0, 400.0),
      Size(300.0, 400.0),
    ];

    cardModels = List<CardModel>.generate(cardSizes.length, (int i) {
      final Color? color = Color.lerp(
        Colors.red.shade300,
        Colors.blue.shade900,
        i / cardSizes.length,
      );
      return CardModel(i, cardSizes[i], color!);
    });
  }

  static const TextStyle cardLabelStyle = TextStyle(
    color: Colors.white,
    fontSize: 18.0,
    fontWeight: FontWeight.bold,
  );

  List<CardModel> cardModels = <CardModel>[];
  Size pageSize = const Size(200.0, 200.0);
  Axis scrollDirection = Axis.horizontal;
  bool itemsWrap = false;

  Widget buildCard(CardModel cardModel) {
    final Widget card = Card(
      color: cardModel.color,
      child: Container(
        width: cardModel.size.width,
        height: cardModel.size.height,
        padding: const EdgeInsets.all(8.0),
        child: Center(child: Text(cardModel.label, style: cardLabelStyle)),
      ),
    );

    final constraints = (scrollDirection == Axis.vertical)
        ? BoxConstraints.tightFor(height: pageSize.height)
        : BoxConstraints.tightFor(width: pageSize.width);

    return Container(
      key: cardModel.key,
      constraints: constraints,
      child: Center(child: card),
    );
  }

  void switchScrollDirection() {
    setState(() {
      scrollDirection = flipAxis(scrollDirection);
    });
  }

  void toggleItemsWrap() {
    setState(() {
      itemsWrap = !itemsWrap;
    });
  }

  Widget _buildDrawer() {
    return Drawer(
      child: ListView(
        children: <Widget>[
          const DrawerHeader(child: Center(child: Text('Options'))),
          ListTile(
            leading: const Icon(Icons.more_horiz),
            selected: scrollDirection == Axis.horizontal,
            trailing: const Text('Horizontal Layout'),
            onTap: switchScrollDirection,
          ),
          ListTile(
            leading: const Icon(Icons.more_vert),
            selected: scrollDirection == Axis.vertical,
            trailing: const Text('Vertical Layout'),
            onTap: switchScrollDirection,
          ),
          ListTile(
            onTap: toggleItemsWrap,
            title: const Text('Scrolling wraps around'),
            // TODO(abarth): Actually make this checkbox change this value.
            trailing: Checkbox(value: itemsWrap, onChanged: null),
          ),
        ],
      ),
    );
  }

  AppBar _buildAppBar() {
    return AppBar(title: const Text('PageView'), actions: <Widget>[Text(scrollDirection.name)]);
  }

  Widget _buildBody(BuildContext context) {
    return PageView(
      // TODO(abarth): itemsWrap: itemsWrap,
      scrollDirection: scrollDirection,
      children: cardModels.map<Widget>(buildCard).toList(),
    );
  }

  @override
  Widget build(BuildContext context) {
    return IconTheme(
      data: const IconThemeData(color: Colors.white),
      child: Scaffold(appBar: _buildAppBar(), drawer: _buildDrawer(), body: _buildBody(context)),
    );
  }
}

void main() {
  runApp(const MaterialApp(title: 'PageView', home: PageViewApp()));
}
