// 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);
    }
  }
}
