// 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 'dart:async';

import 'package:flutter/material.dart';

import '../logic/card.dart' as logic_card;
import '../logic/croupier.dart' show Croupier;
import '../logic/croupier_settings.dart' show CroupierSettings;
import '../logic/game/game.dart' show Game, GameType, NoArgCb;
import '../logic/hearts/hearts.dart' show HeartsGame;
import 'card.dart' as component_card;
import 'card_collection.dart'
    show CardCollectionComponent, CardCollectionOrientation;
import 'croupier_profile.dart' show CroupierProfileComponent;

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 StatefulComponent {
  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 {
  final Croupier croupier;
  final NoArgCb trueSetState;

  HeartsBoard(Croupier croupier, this.trueSetState,
      {double height, double width, double cardHeight, double cardWidth})
      : super(croupier.game,
            height: height,
            width: width,
            cardHeight: cardHeight,
            cardWidth: cardWidth),
        croupier = croupier {
    assert(this.game is HeartsGame);
  }

  HeartsBoardState createState() => new HeartsBoardState();
}

class HeartsBoardState extends State<HeartsBoard> {
  bool trickTaking = false;
  List<List<logic_card.Card>> playedCards = new List<List<logic_card.Card>>(4);

  static const int SHOW_TRICK_DURATION = 2000; // ms

  @override
  void initState() {
    super.initState();

    _fillPlayedCards();
  }

  // Make copies of the played cards.
  void _fillPlayedCards() {
    for (int i = 0; i < 4; i++) {
      playedCards[i] = new List<logic_card.Card>.from(
          config.game.cardCollections[i + HeartsGame.OFFSET_PLAY]);
    }
  }

  // If there were 3 played cards before and now there are 0...
  bool _detectTrick() {
    HeartsGame game = config.game;
    int lastNumPlayed = playedCards.where((List<logic_card.Card> list) {
      return list.length > 0;
    }).length;
    return lastNumPlayed == 3 && game.numPlayed == 0;
  }

  // Make a copy of the missing played card.
  void _fillMissingPlayedCard() {
    HeartsGame game = config.game;
    List<logic_card.Card> trickPile =
        game.cardCollections[game.lastTrickTaker + HeartsGame.OFFSET_TRICK];

    // Find the index of the missing play card.
    int missing;
    for (int j = 0; j < 4; j++) {
      if (playedCards[j].length == 0) {
        missing = j;
        break;
      }
    }

    // Use the trickPile to get this card.
    playedCards[missing] = <logic_card.Card>[
      trickPile[trickPile.length - 4 + missing]
    ];
  }

  Widget build(BuildContext context) {
    if (!trickTaking) {
      if (_detectTrick()) {
        trickTaking = true;
        _fillMissingPlayedCard();
        // Unfortunately, ZCards are drawn on the game layer,
        // so instead of setState, we must use trueSetState.
        new Future.delayed(const Duration(milliseconds: SHOW_TRICK_DURATION),
            () {
          trickTaking = false;
          config.trueSetState();
        });
      } else {
        _fillPlayedCards();
      }
    }

    return new Container(
        height: config.height,
        width: config.width,
        child: new Stack([
          new Positioned(top: 0.0, left: 0.0, child: _buildBoardLayout()),
          new Positioned(
              top: config.height * 1.5,
              left: (config.width - config.cardWidth) / 2,
              child: _buildTrick(0)), // bottom
          new Positioned(
              top: (config.height - config.cardHeight) / 2,
              left: config.width * -0.5,
              child: _buildTrick(1)), // left
          new Positioned(
              top: config.height * -0.5,
              left: (config.width - config.cardWidth) / 2,
              child: _buildTrick(2)), // top
          new Positioned(
              top: (config.height - config.cardHeight) / 2,
              left: config.width * 1.5,
              child: _buildTrick(3)) // right
        ]));
  }

  Widget _buildBoardLayout() {
    return new Container(
        height: config.height,
        width: config.width,
        child: new Column([
          new Flexible(child: _buildPlayer(2), flex: 5),
          new Flexible(
              child: new Row([
                new Flexible(child: _buildPlayer(1), flex: 3),
                new Flexible(child: _buildCenterCards(), flex: 4),
                new Flexible(child: _buildPlayer(3), flex: 3)
              ],
                  alignItems: FlexAlignItems.center,
                  justifyContent: FlexJustifyContent.spaceAround),
              flex: 9),
          new Flexible(child: _buildPlayer(0), flex: 5)
        ],
            alignItems: FlexAlignItems.center,
            justifyContent: FlexJustifyContent.spaceAround));
  }

  Widget _buildPlayer(int playerNumber) {
    bool wide = (config.width >= config.height);

    List<Widget> widgets = [
      _getProfile(playerNumber, wide),
      _getHand(playerNumber),
      _getPass(playerNumber)
    ];

    if (playerNumber % 2 == 0) {
      return new Row(widgets,
          alignItems: FlexAlignItems.center,
          justifyContent: FlexJustifyContent.center);
    } else {
      return new Column(widgets,
          alignItems: FlexAlignItems.center,
          justifyContent: FlexJustifyContent.center);
    }
  }

  Widget _getProfile(int playerNumber, bool isWide) {
    bool isMini = isWide && config.cardHeight * 2 > config.height * 0.25;

    // If cs is null, a placeholder is used instead.
    CroupierSettings cs =
        config.croupier.settingsFromPlayerNumber(playerNumber);
    return new CroupierProfileComponent(
        settings: cs, height: config.height * 0.15, isMini: isMini);
  }

  Widget _getHand(int playerNumber) {
    double sizeRatio = 0.30;
    double cccSize = sizeRatio * config.width;

    return new CardCollectionComponent(
        config.game.cardCollections[playerNumber + HeartsGame.OFFSET_HAND],
        false,
        CardCollectionOrientation.horz,
        width: cccSize,
        widthCard: config.cardWidth,
        heightCard: config.cardHeight,
        useKeys: true);
  }

  Widget _getPass(int playerNumber) {
    double sizeRatio = 0.10;
    double cccSize = sizeRatio * config.width;

    HeartsGame game = config.game;
    return new CardCollectionComponent(
        game.cardCollections[
            game.getTakeTarget(playerNumber) + HeartsGame.OFFSET_PASS],
        false,
        CardCollectionOrientation.horz,
        backgroundColor: Colors.grey[300],
        width: cccSize,
        widthCard: config.cardWidth / 2,
        heightCard: config.cardHeight / 2,
        useKeys: true);
  }

  Widget _buildCenterCards() {
    bool wide = (config.width >= config.height);

    if (wide) {
      return new Row([
        _buildCenterCard(1),
        new Column([_buildCenterCard(2), _buildCenterCard(0)],
            alignItems: FlexAlignItems.center,
            justifyContent: FlexJustifyContent.spaceAround),
        _buildCenterCard(3)
      ],
          alignItems: FlexAlignItems.center,
          justifyContent: FlexJustifyContent.spaceAround);
    } else {
      return new Column([
        _buildCenterCard(2),
        new Row([_buildCenterCard(1), _buildCenterCard(3)],
            alignItems: FlexAlignItems.center,
            justifyContent: FlexJustifyContent.spaceAround),
        _buildCenterCard(0)
      ],
          alignItems: FlexAlignItems.center,
          justifyContent: FlexJustifyContent.spaceAround);
    }
  }

  Widget _buildCenterCard(int playerNumber) {
    HeartsGame game = config.game;
    List<logic_card.Card> cards =
        game.cardCollections[playerNumber + HeartsGame.OFFSET_PLAY];
    if (trickTaking) {
      cards = playedCards[playerNumber];
    }

    return new CardCollectionComponent(
        cards, true, CardCollectionOrientation.show1,
        widthCard: config.cardWidth * 1.25,
        heightCard: config.cardHeight * 1.25,
        backgroundColor:
            game.whoseTurn == playerNumber ? Colors.blue[500] : null,
        useKeys: true);
  }

  Widget _buildTrick(int playerNumber) {
    HeartsGame game = config.game;
    List<logic_card.Card> cards =
        game.cardCollections[playerNumber + HeartsGame.OFFSET_TRICK];
    // If took trick, exclude the last 4 cards for the trick taking animation.
    if (trickTaking && playerNumber == game.lastTrickTaker) {
      cards = new List.from(cards.sublist(0, cards.length - 4));
    }

    return new CardCollectionComponent(
        cards, true, CardCollectionOrientation.show1,
        widthCard: config.cardWidth,
        heightCard: config.cardHeight,
        useKeys: true,
        animationType: component_card.CardAnimationType.LONG);
  }
}
