// 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) {
    int userID = config.croupier.userIDFromPlayerNumber(playerNumber);

    bool isMini = isWide && config.cardHeight * 2 > config.height * 0.25;

    CroupierSettings cs; // If cs is null, a placeholder is used instead.
    if (userID != null) {
      cs = config.croupier.settings_everyone[userID];
    }
    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);
  }
}
