// 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 '../logic/card.dart' as logic_card;
import 'card.dart' as component_card;
import 'draggable.dart' show Draggable;
import 'util.dart' as util;

import 'dart:math' as math;
import 'package:sky/widgets.dart';
import 'package:sky/material.dart' as material;

enum Orientation { vert, horz, fan, show1, suit }
enum DropType {
  none,
  card,
  card_collection
  // I can see that both would be nice, but I'm not sure how to do that yet.
}

typedef void AcceptCb(dynamic data, List<logic_card.Card> cards);

const double DEFAULT_WIDTH = 200.0;
const double DEFAULT_CARD_HEIGHT = 60.0;
const double DEFAULT_CARD_WIDTH = 60.0;

const double CARD_MARGIN = 3.0; // transparent
const double WHITE_LINE_HEIGHT = 2.0; // white
const double WHITE_LINE_MARGIN = 4.0; // each side

class CardCollectionComponent extends StatefulComponent {
  List<logic_card.Card> cards;
  Orientation orientation;
  bool faceUp;
  AcceptCb acceptCallback;
  bool dragChildren;
  DropType acceptType;
  Comparator<logic_card.Card> comparator;
  double width;
  double widthCard;
  double heightCard;
  var backgroundColor;
  var altColor;

  String status = 'bar';

  CardCollectionComponent(
      this.cards, this.faceUp, this.orientation,
      {this.dragChildren: false,
      this.acceptType: DropType.none,
      this.acceptCallback: null,
      this.comparator: null,
      this.width: DEFAULT_WIDTH,
      this.widthCard: DEFAULT_CARD_WIDTH,
      this.heightCard: DEFAULT_CARD_HEIGHT,
      this.backgroundColor,
      this.altColor}) {
    if (this.backgroundColor == null) {
      backgroundColor = material.Colors.grey[500];
    }
    if (this.altColor == null) {
      altColor = material.Colors.grey[600];
    }
  }

  void syncConstructorArguments(CardCollectionComponent other) {
    cards = other.cards;
    orientation = other.orientation;
    faceUp = other.faceUp;
    acceptCallback = other.acceptCallback;
    dragChildren = other.dragChildren;
    acceptType = other.acceptType;
    comparator = other.comparator;
    width = other.width;
    widthCard = other.widthCard;
    heightCard = other.heightCard;
    backgroundColor = other.backgroundColor;
    altColor = other.altColor;
  }

  bool _handleWillAccept(dynamic data) {
    print('will accept?');
    print(data);
    return true;
  }

  void _handleAccept(component_card.Card data) {
    print('accept');
    setState(() {
      status = 'ACCEPT ${data.card.toString()}';
      acceptCallback(data.card, this.cards);
    });
  }

  void _handleAcceptMultiple(CardCollectionComponent data) {
    print('acceptMulti');
    setState(() {
      status = 'ACCEPT multi: ${data.cards.toString()}';
      acceptCallback(data.cards, this.cards);
    });
  }

  List<logic_card.Card> get _sortedCards {
    assert(this.comparator != null);
    List<logic_card.Card> cs = new List<logic_card.Card>();
    cs.addAll(this.cards);
    cs.sort(comparator);
    return cs;
  }

  // returns null if it's up to the container (like a Flex) to figure this out.
  double get desiredHeight {
    switch (this.orientation) {
      case Orientation.vert:
        return null;
      case Orientation.horz:
      case Orientation.fan:
      case Orientation.show1:
        return _produceRowHeight;
      case Orientation.suit:
        return _produceRowHeight * 4 + _whiteLineHeight * 3;
      default:
        assert(false);
        return null;
    }
  }

  // returns null if it's up to the container (like a Flex) to figure this out.
  double get desiredWidth {
    switch (this.orientation) {
      case Orientation.vert:
      case Orientation.show1:
        return widthCard;
      case Orientation.horz:
      case Orientation.fan:
      case Orientation.suit:
        return this.width;
      default:
        assert(false);
        return null;
    }
  }

  double get _produceRowHeight => heightCard + CARD_MARGIN * 2;
  Widget _produceRow(List<Widget> cardWidgets, {emptyBackgroundImage: ""}) {
    if (cardWidgets.length == 0) {
      // Just return a centered background image.
      return new Container(
          decoration: new BoxDecoration(backgroundColor: this.backgroundColor),
          height: _produceRowHeight,
          width: this.width,
          child: new Center(
              child: new Opacity(
                  opacity: 0.45,
                  child: new Container(
                      height: heightCard,
                      child: emptyBackgroundImage == ""
                          ? null
                          : new NetworkImage(src: emptyBackgroundImage)))));
    }

    // Let's do a stack of positioned cards!
    List<Widget> kids = new List<Widget>();

    double w = this.width ?? widthCard * 5;
    double spacing = math.min(widthCard + CARD_MARGIN * 2,
        (w - widthCard - 2 * CARD_MARGIN) / (cardWidgets.length - 1));

    for (int i = 0; i < cardWidgets.length; i++) {
      kids.add(new Positioned(
          top: CARD_MARGIN,
          left: CARD_MARGIN + spacing * i,
          child: cardWidgets[i]));
    }
    return new Container(
        decoration: new BoxDecoration(backgroundColor: this.backgroundColor),
        height: _produceRowHeight,
        width: this.width,
        child: new Stack(kids));
  }

  double get _whiteLineHeight => WHITE_LINE_HEIGHT;

  Widget wrapCards(List<Widget> cardWidgets) {
    switch (this.orientation) {
      case Orientation.vert:
        return new Flex(util.flexChildren(cardWidgets),
            direction: FlexDirection.vertical);
      case Orientation.horz:
        return _produceRow(cardWidgets);
      case Orientation.fan:
      // unimplemented, so we'll fall through to show1, for now.
      // Probably a Stack + Positioned
      case Orientation.show1:
        return new Stack(cardWidgets);
      case Orientation.suit:
        List<Widget> cs = new List<Widget>();
        List<Widget> ds = new List<Widget>();
        List<Widget> hs = new List<Widget>();
        List<Widget> ss = new List<Widget>();

        List<logic_card.Card> theCards =
            this.comparator != null ? this._sortedCards : this.cards;
        for (int i = 0; i < theCards.length; i++) {
          // Group by suit. Then sort.
          logic_card.Card c = theCards[i];
          switch (c.identifier[0]) {
            case 'c':
              cs.add(cardWidgets[i]);
              break;
            case 'd':
              ds.add(cardWidgets[i]);
              break;
            case 'h':
              hs.add(cardWidgets[i]);
              break;
            case 's':
              ss.add(cardWidgets[i]);
              break;
            default:
              assert(false);
          }
        }
        return new Container(
            decoration:
                new BoxDecoration(backgroundColor: material.Colors.white),
            child: new Stack(<Widget>[
              new Positioned(
                  top: 0.0,
                  child: _produceRow(ss,
                      emptyBackgroundImage: "images/suits/Spade.png")),
              new Positioned(
                  top: _produceRowHeight + _whiteLineHeight,
                  child: _produceRow(hs,
                      emptyBackgroundImage: "images/suits/Heart.png")),
              new Positioned(
                  top: 2 * _produceRowHeight + 2 * _whiteLineHeight,
                  child: _produceRow(cs,
                      emptyBackgroundImage: "images/suits/Club.png")),
              new Positioned(
                  top: 3 * _produceRowHeight + 3 * _whiteLineHeight,
                  child: _produceRow(ds,
                      emptyBackgroundImage: "images/suits/Diamond.png"))
            ]));
      default:
        assert(false);
        return null;
    }
  }

  Widget build() {
    return _buildCollection();
  }

  Widget _buildCollection() {
    List<Widget> cardComponents = new List<Widget>();
    List<logic_card.Card> cs =
        this.comparator != null ? this._sortedCards : this.cards;

    for (int i = 0; i < cs.length; i++) {
      component_card.Card c = new component_card.Card(cs[i], faceUp,
          width: widthCard, height: heightCard);

      if (dragChildren) {
        cardComponents.add(new Draggable<component_card.Card>(c));
      } else {
        cardComponents.add(c);
      }
    }

    // Let's draw a stack of cards with DragTargets.
    // TODO(alexfandrianto): In many cases, card collections shouldn't have draggable cards.
    // Additionally, it may be worthwhile to restrict it to 1 at a time.
    switch (this.acceptType) {
      case DropType.none:
        return new Container(
            decoration:
                new BoxDecoration(backgroundColor: this.backgroundColor),
            height: this.desiredHeight,
            width: this.desiredWidth,
            child: wrapCards(cardComponents));
      case DropType.card:
        return new DragTarget<component_card.Card>(
            onWillAccept: _handleWillAccept, onAccept: _handleAccept,
            builder: (List<component_card.Card> data, _) {
          return new Container(
              decoration: new BoxDecoration(
                  backgroundColor:
                      data.isEmpty ? this.backgroundColor : this.altColor),
              height: this.desiredHeight,
              width: this.desiredWidth,
              child: wrapCards(cardComponents));
        });
      case DropType.card_collection:
        return new DragTarget<CardCollectionComponent>(
            onWillAccept: _handleWillAccept, onAccept: _handleAcceptMultiple,
            builder: (List<CardCollectionComponent> data, _) {
          return new Container(
              decoration: new BoxDecoration(
                  backgroundColor:
                      data.isEmpty ? this.backgroundColor : this.altColor),
              height: this.desiredHeight,
              width: this.desiredWidth,
              child: wrapCards(cardComponents));
        });
    }
  }
}
