// 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.

library game_component;

import 'dart:math' as math;
import 'dart:async';

import 'package:flutter/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import '../logic/card.dart' as logic_card;
import '../logic/croupier.dart' show Croupier;
import '../logic/game/game.dart' show Game, GameType;
import '../logic/hearts/hearts.dart' show HeartsGame, HeartsPhase, HeartsType;
import '../logic/solitaire/solitaire.dart' show SolitaireGame, SolitairePhase;
import '../styles/common.dart' as style;
import 'board.dart' show HeartsBoard;
import 'card.dart' as component_card;
import 'card_collection.dart'
    show CardCollectionComponent, DropType, CardCollectionOrientation, AcceptCb;
import 'croupier_profile.dart' show CroupierProfileComponent;

part 'hearts/hearts.part.dart';
part 'proto/proto.part.dart';
part 'solitaire/solitaire.part.dart';

typedef void NoArgCb();

abstract class GameComponent extends StatefulComponent {
  final Croupier croupier;
  Game get game => croupier.game;
  final NoArgCb gameEndCallback;
  final double width;
  final double height;

  GameComponent(this.croupier, this.gameEndCallback,
      {Key key, this.width, this.height})
      : super(key: key);
}

abstract class GameComponentState<T extends GameComponent> extends State<T> {
  Map<logic_card.Card, CardAnimationData> cardLevelMap;

  void initState() {
    super.initState();

    cardLevelMap = new Map<logic_card.Card, CardAnimationData>();
    config.game.updateCallback = update;
  }

  void _reset() {
    cardLevelMap.clear();
  }

  // This callback is used to force the UI to draw when state changes occur
  // outside of the UIs control (e.g., synced data).
  void update() {
    if (this.mounted) {
      setState(() {});
    }
  }

  // A helper that most subclasses use in order to quit their respective games.
  void _quitGameCallback() {
    setState(() {
      config.gameEndCallback();
    });
  }

  // A helper that subclasses might override to create buttons.
  Widget _makeButton(String text, NoArgCb callback) {
    return new FlatButton(
        child: new Text(text, style: style.Text.liveNow), onPressed: callback);
  }

  @override
  Widget build(BuildContext context); // still UNIMPLEMENTED

  void _cardLevelMapProcessAllVisible(List<int> visibleCardCollectionIndexes) {
    Game game = config.game;

    for (int i = 0; i < visibleCardCollectionIndexes.length; i++) {
      int index = visibleCardCollectionIndexes[i];
      for (int j = 0; j < game.cardCollections[index].length; j++) {
        _cardLevelMapProcess(game.cardCollections[index][j]);
      }
    }
  }

  void _cardLevelMapProcess(logic_card.Card logicCard) {
    component_card.GlobalCardKey key = new component_card.GlobalCardKey(
        logicCard, component_card.CardUIType.CARD);
    component_card.CardState cardState = key.currentState;
    if (cardState == null) {
      return; // There's nothing we can really do about this card since it hasn't drawn yet.
    }
    Point p = cardState.getGlobalPosition();
    double z = cardState.config.z;
    component_card.Card c = key.currentWidget;

    assert(c == cardState.config);

    CardAnimationData cad = cardLevelMap[logicCard];
    if (cad == null || cad.newPoint != p || cad.z != z) {
      setState(() {
        cardLevelMap[logicCard] = new CardAnimationData(c, cad?.newPoint, p, z);
      });
    } else if (!cad.comp_card.isMatchWith(c)) {
      // Even if the position or z index didn't change, we can still update the
      // card itself. This can help during screen rotations, since the top-left
      // card likely not change positions or z-index.
      setState(() {
        cad.comp_card = c;
      });
    }
  }

  bool _isMoving(logic_card.Card c) {
    CardAnimationData data = cardLevelMap[c];
    RenderBox box = context.findRenderObject();
    Point localOld =
        data.oldPoint != null ? box.globalToLocal(data.oldPoint) : null;
    Point localNew = box.globalToLocal(data.newPoint);

    // We also need confirmation from the ZCard that we are moving.
    component_card.GlobalCardKey zCardKey =
        new component_card.GlobalCardKey(c, component_card.CardUIType.ZCARD);
    component_card.ZCardState zCardKeyState = zCardKey.currentState;

    // It is moving if there is an old position, the new one isn't equal to the
    // old one, and the ZCard hasn't arrived at the new position yet.
    return localOld != null &&
        localOld != localNew &&
        localNew != zCardKeyState?.localPosition;
  }

  // Helper to build the card animation layer.
  // Note: This isn't a component because of its dependence on Widgets.
  Widget buildCardAnimationLayer(List<int> visibleCardCollectionIndexes) {
    // It's possible that some cards need to be moved after this build.
    // If so, we can catch it in the next frame.
    scheduler.requestPostFrameCallback((Duration d) {
      _cardLevelMapProcessAllVisible(visibleCardCollectionIndexes);
    });

    List<Widget> positionedCards = new List<Widget>();

    // Sort the cards by z-index. If a card is animating, it gets a z bonus.
    List<logic_card.Card> orderedKeys = cardLevelMap.keys.toList()
      ..sort((logic_card.Card a, logic_card.Card b) {
        bool isMovingA = _isMoving(a);
        bool isMovingB = _isMoving(b);

        // Moving cards take much higher priority.
        if (isMovingA && !isMovingB) {
          return 1;
        } else if (!isMovingA && isMovingB) {
          return -1;
        }

        // If both are moving/non-moving, we break ties with the z-index.
        double diff = cardLevelMap[a].z - cardLevelMap[b].z;
        return diff.sign.toInt();
      });

    orderedKeys.forEach((logic_card.Card c) {
      // Don't show a card if it isn't part of a visible collection.
      if (!visibleCardCollectionIndexes.contains(config.game.findCard(c))) {
        cardLevelMap.remove(c); // It is an old card, which we can clean up.
        assert(!cardLevelMap.containsKey(c));
        return;
      }

      CardAnimationData data = cardLevelMap[c];
      RenderBox box = context.findRenderObject();
      Point localOld =
          data.oldPoint != null ? box.globalToLocal(data.oldPoint) : null;
      Point localNew = box.globalToLocal(data.newPoint);

      positionedCards.add(new Positioned(
          key: new GlobalObjectKey(c
              .toString()), //needed, or else the Positioned wrapper may be traded out and animations fail.
          top:
              0.0, // must pass x and y or else it expands to the maximum Stack size.
          left:
              0.0, // must pass x and y or else it expands to the maximum Stack size.
          child: new component_card.ZCard(data.comp_card, localOld, localNew)));
    });

    return new IgnorePointer(
        ignoring: true,
        child: new Container(
            width: config.width,
            height: config.height,
            child: new Stack(positionedCards)));
  }
}

GameComponent createGameComponent(Croupier croupier, NoArgCb gameEndCallback,
    {Key key, double width, double height}) {
  switch (croupier.game.gameType) {
    case GameType.Proto:
      return new ProtoGameComponent(croupier, gameEndCallback,
          key: key, width: width, height: height);
    case GameType.Hearts:
      return new HeartsGameComponent(croupier, gameEndCallback,
          key: key, width: width, height: height);
    case GameType.Solitaire:
      return new SolitaireGameComponent(croupier, gameEndCallback,
          key: key, width: width, height: height);
    default:
      // We're probably not ready to serve the other games yet.
      assert(false);
      return null;
  }
}

abstract class GameArrangeComponent extends StatelessComponent {
  final Croupier croupier;
  final double width;
  final double height;
  GameArrangeComponent(this.croupier, {this.width, this.height});
}

GameArrangeComponent createGameArrangeComponent(Croupier croupier,
    {double width, double height}) {
  switch (croupier.game.gameType) {
    case GameType.Hearts:
      return new HeartsArrangeComponent(croupier, width: width, height: height);
    default:
      // We can't arrange this game.
      throw new UnimplementedError(
          "We cannot arrange the game type: ${croupier.game.gameType}");
  }
}

/// CardAnimationData contains the relevant information for a ZCard to be built.
/// It uses the comp_card's properties, the oldPoint, newPoint, and z-index to
/// determine how it needs to animate.
class CardAnimationData {
  component_card.Card comp_card;
  Point oldPoint;
  Point newPoint;
  double z;

  CardAnimationData(this.comp_card, this.oldPoint, this.newPoint, this.z);
}
