// 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, CardCollectionOrientation;
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:flutter/material.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 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.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(HeartsGame game,
      {double height, double width, double cardHeight, double cardWidth})
      : super(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];
      CardCollectionOrientation ori = i % 2 == 0 ? CardCollectionOrientation.horz : CardCollectionOrientation.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(
          cards, false, ori,
          width: i % 2 == 0 ? cccSize : null,
          height: i % 2 != 0 ? cccSize : null,
          rotation: -math.PI / 2 * i,
          useKeys: true);
      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(
          cards, true, CardCollectionOrientation.show1,
          width: this.cardWidth,
          widthCard: this.cardWidth,
          height: this.cardHeight,
          heightCard: this.cardHeight,
          rotation: -math.PI / 2 * i,
          useKeys: true);
      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);
    }
  }
}
