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

part of game;

// Note: Proto and Board are "fake" games intended to demonstrate what we can do.
// Proto is just a drag cards around "game".
// Board is meant to show how one _could_ layout a game of Hearts. This one is not hooked up very well yet.
enum GameType { Proto, Hearts, Poker, Solitaire, Board }

Map<GameType, String> _gameTypeMap = <GameType, String>{
  GameType.Proto: "Proto",
  GameType.Hearts: "Hearts",
  GameType.Poker: "Poker",
  GameType.Solitaire: "Solitaire",
};
String gameTypeToString(GameType t) {
  return _gameTypeMap[t];
}

GameType stringToGameType(String t) {
  GameType gt;
  _gameTypeMap.forEach((GameType type, String name) {
    if (name == t) {
      gt = type;
    }
  });
  return gt;
}

// You should share information like this if you want to setup a game for someone else.
class GameStartData {
  String type;
  int playerNumber;
  int gameID;
  int ownerID;

  GameStartData(this.type, this.playerNumber, this.gameID, this.ownerID);

  GameStartData.fromJSONString(String json) {
    var data = JSON.decode(json);
    type = data["type"];
    playerNumber = data["playerNumber"];
    gameID = data["gameID"];
    ownerID = data["ownerID"];
  }

  String toJSONString() {
    return JSON.encode({
      "type": type,
      "playerNumber": playerNumber,
      "gameID": gameID,
      "ownerID": ownerID
    });
  }

  GameType get gameType => stringToGameType(type);

  bool operator ==(Object other) {
    if (other is! GameStartData) {
      return false;
    }
    GameStartData gsd = other;
    return gsd.type == type &&
        gsd.playerNumber == playerNumber &&
        gsd.gameID == gameID &&
        gsd.ownerID == ownerID;
  }
}

typedef void NoArgCb();

/// 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.
abstract class Game {
  final GameType gameType;
  String get gameTypeName; // abstract

  final List<List<Card>> cardCollections = new List<List<Card>>();
  final List<Card> deck = new List<Card>.from(Card.All);
  final int gameID;

  final GameLog gamelog;

  int _playerNumber;
  int get playerNumber => _playerNumber;
  // Some subclasses may wish to override this setter to do extra work.
  void set playerNumber(int other) {
    _playerNumber = other;
  }

  String debugString = 'hello?';

  NoArgCb updateCallback; // Used to inform components of when a change has occurred. This is especially important when something non-UI related changes what should be drawn.

  // A super constructor, don't call this unless you're a subclass.
  Game.create(
      this.gameType, this.gamelog, this._playerNumber, int numCollections,
      {int gameID})
      : gameID = gameID ?? new math.Random().nextInt(0x00FFFFFF) {
    print("The gameID is ${gameID}");
    gamelog.setGame(this);
    for (int i = 0; i < numCollections; i++) {
      cardCollections.add(new List<Card>());
    }
  }

  List<Card> deckPeek(int numCards, [int start = 0]) {
    assert(deck.length >= numCards);

    List<Card> cards =
        new List<Card>.from(deck.getRange(start, start + numCards));
    return cards;
  }

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

  void resetCards() {
    for (int i = 0; i < cardCollections.length; i++) {
      cardCollections[i].clear();
    }
    deck.clear();
    deck.addAll(Card.All);
  }

  void quit() {
    this.gamelog.close();
  }

  // UNIMPLEMENTED
  void move(Card card, List<Card> dest);
  void triggerEvents();
}
