import 'card.dart' show Card;
import 'dart:math' show Random;

enum GameType {
  Hearts
}

/// A game consists of multiple decks and tracks a single deck of cards.
/// It also handles events; when cards are dragged to and from decks.
class Game {
  final GameType gameType;
  final List<List<Card>> cardCollections = new List<List<Card>>();
  final List<Card> deck = <Card>[
    new Card("classic", "c1"),
    new Card("classic", "c2"),
    new Card("classic", "c3"),
    new Card("classic", "c4"),
    new Card("classic", "c5"),
    new Card("classic", "c6"),
    new Card("classic", "c7"),
    new Card("classic", "c8"),
    new Card("classic", "c9"),
    new Card("classic", "c10"),
    new Card("classic", "cj"),
    new Card("classic", "cq"),
    new Card("classic", "ck"),
    new Card("classic", "d1"),
    new Card("classic", "d2"),
    new Card("classic", "d3"),
    new Card("classic", "d4"),
    new Card("classic", "d5"),
    new Card("classic", "d6"),
    new Card("classic", "d7"),
    new Card("classic", "d8"),
    new Card("classic", "d9"),
    new Card("classic", "d10"),
    new Card("classic", "dj"),
    new Card("classic", "dq"),
    new Card("classic", "dk"),
    new Card("classic", "h1"),
    new Card("classic", "h2"),
    new Card("classic", "h3"),
    new Card("classic", "h4"),
    new Card("classic", "h5"),
    new Card("classic", "h6"),
    new Card("classic", "h7"),
    new Card("classic", "h8"),
    new Card("classic", "h9"),
    new Card("classic", "h10"),
    new Card("classic", "hj"),
    new Card("classic", "hq"),
    new Card("classic", "hk"),
    new Card("classic", "s1"),
    new Card("classic", "s2"),
    new Card("classic", "s3"),
    new Card("classic", "s4"),
    new Card("classic", "s5"),
    new Card("classic", "s6"),
    new Card("classic", "s7"),
    new Card("classic", "s8"),
    new Card("classic", "s9"),
    new Card("classic", "s10"),
    new Card("classic", "sj"),
    new Card("classic", "sq"),
    new Card("classic", "sk"),
  ];

  final Random random = new Random();
  final GameLog gamelog = new GameLog();
  int playerNumber;
  Function updateCallback;
  String debugString = 'hello?';

  Game.hearts(this.playerNumber) : gameType = GameType.Hearts {
    gamelog.setGame(this);

    // playerNumber would be used in a real game, but I have to ignore it for debugging.
    // It would determine faceUp/faceDown status.

    deck.shuffle();
    cardCollections.add(new List<Card>()); // Player A
    cardCollections.add(new List<Card>()); // Player B
    cardCollections.add(new List<Card>()); // Player C
    cardCollections.add(new List<Card>()); // Player D
    cardCollections.add(new List<Card>()); // an empty pile
    cardCollections.add(new List<Card>()); // a hidden pile!

    /*deal(0, 8);
    deal(1, 5);
    deal(2, 4);
    deal(3, 1);*/
  }

  List<Card> deckPeek(int numCards) {
    assert(deck.length >= numCards);
    List<Card> cards = new List<Card>.from(deck.take(numCards));
    return cards;
  }

  void deal(int playerId, int numCards) {
    gamelog.add(new HeartsCommand.deal(playerId, this.deckPeek(numCards)));
  }

  void move(Card card, List<Card> dest) {
    // The first step is to find the card. Where is it?
    // then we can remove it and add to the dest.
    debugString = 'Moving... ${card.toString()}';
    int i = findCard(card);
    if (i == -1) {
      debugString = 'NO... ${card.toString()}';
      return;
    }
    int destId = cardCollections.indexOf(dest);

    gamelog.add(new HeartsCommand.pass(i, destId, <Card>[card]));

    /*cardCollections[i].remove(card);
    dest.add(card);*/
    debugString = 'Move ${i} ${card.toString()}';
    print(debugString);
  }

  // Which card collection has the card?
  int findCard(Card card) {
    for (int i = 0; i < cardCollections.length; i++) {
      if (cardCollections[i].contains(card)) {
        return i;
      }
    }
    return -1;
  }
}

class GameLog {
  Game game;
  List<GameCommand> log = new List<GameCommand>();
  int position = 0;

  void setGame(Game g) {
    this.game = g;
  }

  // This adds and executes the GameCommand.
  void add(GameCommand gc) {
    log.add(gc);

    while (position < log.length) {
      log[position].execute(game);
      if (game.updateCallback != null) {
        game.updateCallback();
      }
      position++;
    }
  }
}

abstract class GameCommand {
  void execute(Game game);
}


class HeartsCommand extends GameCommand {
  final String data; // This will be parsed.

  // Usually this constructor is used when reading from a log/syncbase.
  HeartsCommand(this.data);

  // The following constructors are used for the player generating the HeartsCommand.
  HeartsCommand.deal(int playerId, List<Card> cards) :
    this.data = computeDeal(playerId, cards);

  // TODO: receiverId is actually implied by the game round. So it may end up being removable.
  HeartsCommand.pass(int senderId, int receiverId, List<Card> cards) :
    this.data = computePass(senderId, receiverId, cards);

  HeartsCommand.play(int playerId, Card c) :
    this.data = computePlay(playerId, c);

  static computeDeal(int playerId, List<Card> cards) {
    StringBuffer buff = new StringBuffer();
    buff.write("Deal:${playerId}:");
    cards.forEach((card) => buff.write("${card.toString()}:"));
    buff.write("END");
    return buff.toString();
  }
  static computePass(int senderId, int receiverId, List<Card> cards) {
    StringBuffer buff = new StringBuffer();
    buff.write("Pass:${senderId}:${receiverId}:");
    cards.forEach((card) => buff.write("${card.toString()}:"));
    buff.write("END");
    return buff.toString();
  }
  static computePlay(int playerId, Card c) {
    return "Play:${playerId}:${c.toString()}:END";
  }

  void execute(Game game) {
    print("HeartsCommand is executing: ${data}");
    List<String> parts = data.split(":");
    switch (parts[0]) {
      case "Deal":
        // Deal appends cards to playerId's hand.
        int playerId = int.parse(parts[1]);
        List<Card> hand = game.cardCollections[playerId];

        // The last part is 'END', but the rest are cards.
        for (int i = 2; i < parts.length - 1; i++) {
          Card c = new Card.fromString(parts[i]);
          this.transfer(game.deck, hand, c);
        }
        return;
      case "Pass":
        // Pass moves a set of cards from senderId to receiverId.
        int senderId = int.parse(parts[1]);
        int receiverId = int.parse(parts[2]);
        List<Card> handS = game.cardCollections[senderId];
        List<Card> handR = game.cardCollections[receiverId];

        // The last part is 'END', but the rest are cards.
        for (int i = 3; i < parts.length - 1; i++) {
          Card c = new Card.fromString(parts[i]);
          this.transfer(handS, handR, c);
        }
        return;
      case "Play":
        // In this case, move it to the designated discard pile.
        // For now, the discard pile is pile #4. This may change.
        int playerId = int.parse(parts[1]);
        List<Card> hand = game.cardCollections[playerId];

        Card c = new Card.fromString(parts[2]);
        this.transfer(hand, game.cardCollections[4], c);
        return;
      default:
        print(data);
        assert(false); // How could this have happened?
    }
  }

  void transfer(List<Card> sender, List<Card> receiver, Card c) {
    assert(sender.contains(c));
    sender.remove(c);
    receiver.add(c);
  }
}