// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

part of fitness;

class FitnessItemList extends StatelessComponent {
  FitnessItemList({ Key key, this.items, this.onDismissed }) : super(key: key) {
    assert(items != null);
    assert(onDismissed != null);
  }

  final List<FitnessItem> items;
  final FitnessItemHandler onDismissed;

  Widget build(BuildContext context) {
    return new ScrollableList<FitnessItem>(
      padding: const EdgeDims.all(4.0),
      items: items,
      itemExtent: kFitnessItemHeight,
      itemBuilder: (BuildContext context, FitnessItem item, int index) => item.toRow(onDismissed: onDismissed)
    );
  }
}

class DialogMenuItem extends StatelessComponent {
  DialogMenuItem(this.children, { Key key, this.onPressed }) : super(key: key);

  List<Widget> children;
  Function onPressed;

  Widget build(BuildContext context) {
    return new Container(
      height: 48.0,
      child: new InkWell(
        onTap: onPressed,
        child: new Padding(
          padding: const EdgeDims.symmetric(horizontal: 16.0),
          child: new Row(children)
        )
      )
    );
  }
}

class FeedFragment extends StatefulComponent {
  FeedFragment({ this.userData, this.onItemCreated, this.onItemDeleted });

  final UserData userData;
  final FitnessItemHandler onItemCreated;
  final FitnessItemHandler onItemDeleted;

  FeedFragmentState createState() => new FeedFragmentState();
}

class FeedFragmentState extends State<FeedFragment> {
  FitnessMode _fitnessMode = FitnessMode.feed;

  void _handleFitnessModeChange(FitnessMode value) {
    setState(() {
      _fitnessMode = value;
    });
    Navigator.pop(context);
  }

  Widget _buildDrawer() {
    return new Drawer(
      child: new Block(<Widget>[
        new DrawerHeader(child: new Text('Fitness')),
        new DrawerItem(
          icon: 'action/view_list',
          onPressed: () => _handleFitnessModeChange(FitnessMode.feed),
          selected: _fitnessMode == FitnessMode.feed,
          child: new Text('Feed')),
        new DrawerItem(
          icon: 'action/assessment',
          onPressed: () => _handleFitnessModeChange(FitnessMode.chart),
          selected: _fitnessMode == FitnessMode.chart,
          child: new Text('Chart')),
        new DrawerDivider(),
        new DrawerItem(
          icon: 'action/settings',
          onPressed: _handleShowSettings,
          child: new Text('Settings')),
        new DrawerItem(
          icon: 'action/help',
          child: new Text('Help & Feedback'))
      ])
    );
  }

  void _handleShowSettings() {
    Navigator.popAndPushNamed(context, '/settings');
  }

  // TODO(jackson): We should be localizing
  String get fitnessModeTitle {
    switch(_fitnessMode) {
      case FitnessMode.feed: return "Feed";
      case FitnessMode.chart: return "Chart";
    }
  }

  Widget buildToolBar() {
    return new ToolBar(
      center: new Text(fitnessModeTitle)
    );
  }

  void _handleItemDismissed(FitnessItem item) {
    config.onItemDeleted(item);
    Scaffold.of(context).showSnackBar(new SnackBar(
      content: new Text("Item deleted."),
      actions: <SnackBarAction>[
        new SnackBarAction(label: "UNDO", onPressed: () {
          config.onItemCreated(item);
        }),
      ]
    ));
  }

  Widget buildChart() {
    double startX;
    double endX;
    double startY;
    double endY;
    List<Point> dataSet = new List<Point>();
    for (FitnessItem item in config.userData.items) {
      if (item is Measurement) {
          double x = item.when.millisecondsSinceEpoch.toDouble();
          double y = item.weight;
          if (startX == null || startX > x)
            startX = x;
          if (endX == null || endX < x)
          endX = x;
          if (startY == null || startY > y)
            startY = y;
          if (endY == null || endY < y)
            endY = y;
          dataSet.add(new Point(x, y));
      }
    }
    if (config.userData.goalWeight != null && config.userData.goalWeight > 0.0) {
      startY = math.min(startY, config.userData.goalWeight);
      endY = math.max(endY, config.userData.goalWeight);
    }
    playfair.ChartData data = new playfair.ChartData(
      startX: startX,
      startY: startY,
      endX: endX,
      endY: endY,
      dataSet: dataSet,
      numHorizontalGridlines: 5,
      roundToPlaces: 1,
      indicatorLine: config.userData.goalWeight,
      indicatorText: "GOAL WEIGHT"
    );
    return new playfair.Chart(data: data);
  }

  Widget buildBody() {
    TextStyle style = Theme.of(context).text.title;
    if (config.userData == null)
      return new Container();
    if (config.userData.items.length == 0) {
      return new Row(
        <Widget>[new Text("No data yet.\nAdd some!", style: style)],
        justifyContent: FlexJustifyContent.center
      );
    }
    switch (_fitnessMode) {
      case FitnessMode.feed:
        return new FitnessItemList(
          items: config.userData.items.reversed.toList(),
          onDismissed: _handleItemDismissed
        );
      case FitnessMode.chart:
        return new Container(
          padding: const EdgeDims.all(20.0),
          child: buildChart()
        );
    }
  }

  void _handleActionButtonPressed() {
    showDialog(context: context, child: new AddItemDialog()).then((routeName) {
      if (routeName != null)
        Navigator.pushNamed(context, routeName);
    });
  }

  Widget buildFloatingActionButton() {
    switch (_fitnessMode) {
      case FitnessMode.feed:
        return new FloatingActionButton(
          child: new Icon(icon: 'content/add'),
          onPressed: _handleActionButtonPressed
        );
      case FitnessMode.chart:
        return null;
    }
  }

  Widget build(BuildContext context) {
    return new Scaffold(
      toolBar: buildToolBar(),
      body: buildBody(),
      floatingActionButton: buildFloatingActionButton(),
      drawer: _buildDrawer()
    );
  }
}

class AddItemDialog extends StatefulComponent {
  AddItemDialogState createState() => new AddItemDialogState();
}

class AddItemDialogState extends State<AddItemDialog> {
  // TODO(jackson): Internationalize
  static final Map<String, String> _labels = <String, String>{
    '/measurements/new': 'Measure',
    '/meals/new': 'Eat',
  };

  String _addItemRoute = _labels.keys.first;

  void _handleAddItemRouteChanged(String routeName) {
    setState(() {
        _addItemRoute = routeName;
    });
  }

  Widget build(BuildContext context) {
    List<Widget> menuItems = <Widget>[];
    for (String routeName in _labels.keys) {
      menuItems.add(new DialogMenuItem(<Widget>[
        new Flexible(child: new Text(_labels[routeName])),
        new Radio<String>(value: routeName, groupValue: _addItemRoute, onChanged: _handleAddItemRouteChanged),
      ], onPressed: () => _handleAddItemRouteChanged(routeName)));
    }
    return new Dialog(
      title: new Text("What are you doing?"),
      content: new Block(menuItems),
      actions: <Widget>[
        new FlatButton(
          child: new Text('CANCEL'),
          onPressed: () {
            Navigator.pop(context);
          }
        ),
        new FlatButton(
          child: new Text('ADD'),
          onPressed: () {
            Navigator.pop(context, _addItemRoute);
          }
        ),
      ]
    );
  }
}
