import './card.dart' show Card;
import '../logic/card.dart' as logic_card;

import 'dart:math' as math;

import 'package:sky/widgets.dart' as widgets;
import 'package:vector_math/vector_math.dart' as vector_math;
import 'package:sky/theme/colors.dart' as colors;

const double cardHeight = 96.0;
const double cardWidth = 71.0;

class CardCluster extends widgets.Component {
  List<int> cards; // the indicies of the cards in the center, in clockwise order
  int startingPos;
  CardCluster(this.startingPos, this.cards);

  widgets.Widget build() {
    var widgetsList = [];
    for (int i = 0; i < cards.length; i++) {
      var posMod = (startingPos + i) % 4;
      switch (posMod) {
        case 0:
          widgetsList.add(new widgets.Transform(
              transform: new vector_math.Matrix4.identity()
                  .rotateZ(math.PI)
                  .translate(0.0, -cardHeight / 2),
              child: new Card(logic_card.Card.All[cards[i]], true)));
          break;
        case 1:
          widgetsList.add(new widgets.Transform(
              transform: new vector_math.Matrix4.identity()
                  .rotateZ(math.PI / 2.0)
                  .translate(0.0, cardWidth / 2),
              child: new Card(logic_card.Card.All[cards[i]], true)));
          break;
        case 2:
          widgetsList.add(new widgets.Transform(
              transform: new vector_math.Matrix4.identity().translate(
                  -cardWidth, cardWidth / 2),
              child: new Card(logic_card.Card.All[cards[i]], true)));
          break;
        case 3:
          widgetsList.add(new widgets.Transform(
              transform: new vector_math.Matrix4.identity()
                  .rotateZ(math.PI / 2.0)
                  .translate(0.0, -cardHeight / 2),
              child: new Card(logic_card.Card.All[cards[i]], true)));
          break;
      }
    }
    return new widgets.Container(child: new widgets.Stack(widgetsList));
  }
}

class PlayerHand extends widgets.Component {
  int count;
  PlayerHand(this.count);

  widgets.Widget build() {
    List<widgets.Positioned> cards = [];
    for (int i = 0; i < count; i++) {
      cards.add(new widgets.Positioned(
          child: new Card(logic_card.Card.All[0], false),
          top: 0.0,
          left: cardWidth * i / 2.0));
    }
    return new widgets.Stack(cards);
  }
}

class Board extends widgets.Component {
  CardCluster centerCluster;
  List<PlayerHand> hands; // counts of cards in players hands, in clockwise order

  Board(int firstCardPlayedPosition, List<int> cards, List<int> playerHandCount)
      : centerCluster = new CardCluster(firstCardPlayedPosition, cards) {
    assert(playerHandCount.length == 4);
    hands = new List<PlayerHand>();
    for (int count in playerHandCount) {
      hands.add(new PlayerHand(count));
    }
  }

  widgets.Widget build() {
    return new widgets.Container(
        decoration: new widgets.BoxDecoration(
            backgroundColor: colors.Pink[500]),
        child: new widgets.Stack([
      new widgets.Positioned(child: hands[0], top: 0.0, left: 250.0),
      new widgets.Positioned(
          child: new widgets.Transform(
              transform: new vector_math.Matrix4.identity()
                  .rotateZ(math.PI / 2.0),
              child: hands[1]),
          left: 100.0,
          top: 400.0),
      new widgets.Positioned(
          child: new widgets.Transform(
              transform: new vector_math.Matrix4.identity().rotateZ(math.PI),
              child: hands[2]),
          top: 820.0,
          left: 350.0),
      new widgets.Positioned(
          child: new widgets.Transform(
              transform: new vector_math.Matrix4.identity()
                  .rotateZ(math.PI / 2.0),
              child: hands[3]),
          left: 500.0,
          top: 400.0),
      new widgets.Positioned(child: centerCluster, top: 400.0, left: 300.0),
    ]));
  }
}
