// Copyright 2015 The Vanadium 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/widgets.dart';
import 'package:flutter/material.dart';

import '../models/all.dart' as model;
import '../stores/store.dart';
import '../styles/common.dart' as style;

import 'slideshow.dart';

// SlideListPage is the full page view of the list of slides for a deck.
class SlideListPage extends StatelessComponent {
  final String deckId;
  final String title;
  Store _store = new Store.singleton();

  SlideListPage(this.deckId, this.title);
  Widget build(BuildContext context) {
    return new Scaffold(
        toolBar: new ToolBar(
            left: new IconButton(
                icon: 'navigation/arrow_back',
                onPressed: () => Navigator.of(context).pop()),
            center: new Text(title)),
        floatingActionButton: _buildPresentFab(context),
        body: new Material(child: new SlideList(deckId)));
  }

  _buildPresentFab(BuildContext context) {
    return new FloatingActionButton(
        child: new Icon(icon: 'navigation/arrow_forward'), onPressed: () async {
      model.PresentationAdvertisement presentation =
          await _store.startPresentation(deckId);
      Navigator.of(context).push(new MaterialPageRoute(
          builder: (context) => new SlideshowPage(deckId)));
    });
  }
}

// SlideList is scrollable list view of slides for a deck.
class SlideList extends StatefulComponent {
  final String deckId;
  SlideList(this.deckId);

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

class _SlideListState extends State<SlideList> {
  Store _store = new Store.singleton();
  List<model.Slide> _slides = new List<model.Slide>();

  void updateSlides(List<model.Slide> slides) {
    setState(() {
      _slides = slides;
    });
  }

  @override
  void initState() {
    super.initState();
    _store.getAllSlides(config.deckId).then(updateSlides);
    // TODO(aghassemi): Gracefully handle when deck is deleted while in this view.
  }

  Widget build(BuildContext context) {
    return new ScrollableList(
        itemExtent: style.Size.listHeight,
        items: _slides,
        itemBuilder: (context, value, index) =>
            _buildSlide(context, index.toString(), value, onTap: () {
              _store.setCurrSlideNum(config.deckId, index);
              Navigator.of(context).push(new MaterialPageRoute(
                  builder: (context) => new SlideshowPage(config.deckId)));
            }));
  }
}

// TODO(aghassemi): Is this approach okay? Check with Flutter team.
// Builder gets called a lot by the ScrollableList and building RawImage
// is expensive so we cache.
// Expando is a weak map so this does not effect GC.
Expando<Widget> _weakSlideCache = new Expando<Widget>();
Widget _buildSlide(BuildContext context, String key, model.Slide slideData,
    {Function onTap}) {
  var cachedWidget = _weakSlideCache[slideData];
  if (cachedWidget != null) {
    return cachedWidget;
  }

  var thumbnail = new RawImage(
      height: style.Size.listHeight,
      bytes: new Uint8List.fromList(slideData.image),
      fit: ImageFit.cover);

  thumbnail = new Flexible(child: thumbnail);

  var title = new Text('Slide $key', style: style.Text.subtitleStyle);
  var notes = new Text(
      'This is the teaser slide. It should be memorable and descriptive');
  var titleAndNotes = new Flexible(
      child: new Container(
          child: new Column([title, notes], alignItems: FlexAlignItems.start),
          padding: style.Spacing.normalPadding));

  var card = new Container(
      child: new Card(child: new Row([thumbnail, titleAndNotes])),
      margin: style.Spacing.listItemMargin);

  var listItem = new InkWell(key: new Key(key), child: card, onTap: onTap);

  _weakSlideCache[slideData] = listItem;
  return listItem;
}
