// 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 'card_collection.dart' show CardCollectionComponent, Orientation;
import '../logic/card.dart' as logic_card;
import '../logic/game/game.dart' show Game, GameType;
import '../logic/hearts/hearts.dart' show HeartsGame;

import 'dart:math' as math;

import 'package:sky/widgets.dart';

const double defaultBoardHeight = 400.0;
const double defaultBoardWidth = 400.0;
const double defaultCardHeight = 40.0;
const double defaultCardWidth = 40.0;

/// A Board represents a fixed-size canvas for drawing a Game's UI.
/// While other Widgets may be drawn to accomodate space, a Board is meant to
/// consume a specific amount of space on the screen, which allows for more
/// control when positioning elements within the Board's area.
abstract class Board extends StatelessComponent {
  final NavigatorState navigator;
  final Game game;
  final double _height;
  final double _width;
  final double _cardHeight;
  final double _cardWidth;

  double get height => _height ?? defaultBoardHeight;
  double get width => _width ?? defaultBoardWidth;
  double get cardHeight => _cardHeight ?? defaultCardHeight;
  double get cardWidth => _cardWidth ?? defaultCardWidth;

  Board(this.navigator, this.game,
      {double height, double width, double cardHeight, double cardWidth})
      : _height = height,
        _width = width,
        _cardHeight = cardHeight,
        _cardWidth = cardWidth;
}

/// The HeartsBoard represents the Hearts table view, which shows the number of
/// cards each player has, and the cards they are currently playing.
class HeartsBoard extends Board {
  HeartsBoard(NavigatorState navigator, HeartsGame game,
      {double height, double width, double cardHeight, double cardWidth})
      : super(navigator, game,
            height: height,
            width: width,
            cardHeight: cardHeight,
            cardWidth: cardWidth);

  Widget build(BuildContext context) {
    List<Widget> pile = new List<Widget>();

    _addHandsToPile(pile);
    _addProfilesToPile(pile);
    _addPlaysToPile(pile);

    return new Container(
        height: this.height, width: this.width, child: new Stack(pile));
  }

  // Show the hands of each player (facedown) around the perimeter of the board.
  void _addHandsToPile(List<Widget> pile) {
    HeartsGame game = this.game;

    for (int i = 0; i < 4; i++) {
      List<logic_card.Card> cards =
          game.cardCollections[i + HeartsGame.OFFSET_HAND];
      Orientation ori = i % 2 == 0 ? Orientation.horz : Orientation.vert;

      bool wide = (this.width >= this.height);
      double smallerSide = wide ? this.height : this.width;
      double sizeRatio = 0.60;
      double cccSize = sizeRatio * smallerSide;

      CardCollectionComponent ccc = new CardCollectionComponent(
          this.navigator, cards, false, ori,
          width: i % 2 == 0 ? cccSize : null,
          height: i % 2 != 0 ? cccSize : null,
          rotation: -math.PI / 2 * i);
      Widget w;
      switch (i) {
        case 2:
          w = new Positioned(
              top: 0.0, left: (this.width - cccSize) / 2.0, child: ccc);
          break;
        case 3:
          w = new Positioned(
              top: (this.height - cccSize) / 2.0, left: 0.0, child: ccc);
          break;
        case 0:
          w = new Positioned(
              // TODO(alexfandrianto): 1.7 is a magic number, but it just looks right somehow.
              // This could be due to the margins from each card collection.
              top: this.height - 1.7 * this.cardHeight,
              left: (this.width - cccSize) / 2.0,
              child: ccc);
          break;
        case 1:
          w = new Positioned(
              top: (this.height - cccSize) / 2.0,
              left: this.width - 1.7 * this.cardWidth,
              child: ccc);
          break;
        default:
          assert(false);
      }
      pile.add(w);
    }
  }

  // Create and add Player Profile widgets to the board.
  void _addProfilesToPile(List<Widget> pile) {
    // TODO(alexfandrianto): Show player profiles.
    // I need to access each player's CroupierSettings here.
  }

  // Add 4 play slots. If the board is wider than it is tall, we need to have
  // A flat diamond (where the center 2 cards are stacked on top of each other).
  // If the board is taller than it is wide, then we want a tall diamond. The
  // center 2 cards should be horizontally adjacent.
  // TODO(alexfandrianto): Once I get the player profile settings, I can set
  // the background color of each play slot.
  void _addPlaysToPile(List<Widget> pile) {
    HeartsGame game = this.game;

    for (int i = 0; i < 4; i++) {
      List<logic_card.Card> cards =
          game.cardCollections[i + HeartsGame.OFFSET_PLAY];

      double MARGIN = 10.0;
      CardCollectionComponent ccc = new CardCollectionComponent(
          this.navigator, cards, true, Orientation.show1,
          width: this.cardWidth,
          widthCard: this.cardWidth,
          height: this.cardHeight,
          heightCard: this.cardHeight,
          rotation: -math.PI / 2 * i);
      Widget w;

      double left02 = (this.width - this.cardWidth) / 2;
      double top13 = (this.height - this.cardHeight) / 2.0;

      double baseTop = (this.height - (this.cardHeight * 2 + MARGIN)) / 2;
      double baseLeft = (this.width - (this.cardWidth * 2 + MARGIN)) / 2;
      double dHeight = (this.cardHeight + MARGIN) / 2;
      double dWidth = (this.cardWidth + MARGIN) / 2;

      if (this.width >= this.height) {
        switch (i) {
          case 2:
            w = new Positioned(top: baseTop, left: left02, child: ccc);
            break;
          case 3:
            w = new Positioned(top: top13, left: baseLeft - dWidth, child: ccc);
            break;
          case 0:
            w = new Positioned(
                top: baseTop + dHeight * 2, left: left02, child: ccc);
            break;
          case 1:
            w = new Positioned(
                top: top13, left: baseLeft + dWidth * 3, child: ccc);
            break;
          default:
            assert(false);
        }
      } else {
        switch (i) {
          case 2:
            w = new Positioned(
                top: baseTop - dHeight, left: left02, child: ccc);
            break;
          case 3:
            w = new Positioned(top: top13, left: baseLeft, child: ccc);
            break;
          case 0:
            w = new Positioned(
                top: baseTop + dHeight * 3, left: left02, child: ccc);
            break;
          case 1:
            w = new Positioned(
                top: top13, left: baseLeft + dHeight * 2, child: ccc);
            break;
          default:
            assert(false);
        }
      }

      pile.add(w);
    }
  }
}
