public void Setup()
		{
			Core.Game = null;
			_game = new GameV2();
	        Core.Game = _game;
            _gameEventHandler = new GameEventHandler(_game);

            _heroPlayer = CreateNewEntity("HERO_01");
            _heroPlayer.SetTag(GameTag.CARDTYPE, (int)CardType.HERO);
            _heroPlayer.IsPlayer = true;
            _heroOpponent = CreateNewEntity("HERO_02");
            _heroOpponent.SetTag(GameTag.CARDTYPE, (int) CardType.HERO);
            _heroOpponent.SetTag(GameTag.CONTROLLER, _heroOpponent.Id);
            _heroOpponent.IsPlayer = false;

            _game.Entities.Add(0, _heroPlayer);
            _game.Player.Id = _heroPlayer.Id;
            _game.Entities.Add(1, _heroOpponent);
            _game.Opponent.Id = _heroOpponent.Id;

            _playerMinion1 = CreateNewEntity("EX1_010");
            _playerMinion1.SetTag(GameTag.CARDTYPE, (int)CardType.MINION);
            _playerMinion1.SetTag(GameTag.CONTROLLER, _heroPlayer.Id);
            _opponentMinion1 = CreateNewEntity("EX1_020");
            _opponentMinion1.SetTag(GameTag.CARDTYPE, (int)CardType.MINION);
            _opponentMinion1.SetTag(GameTag.CONTROLLER, _heroOpponent.Id);
            _opponentMinion2 = CreateNewEntity("EX1_021");
            _opponentMinion2.SetTag(GameTag.CARDTYPE, (int)CardType.MINION);
            _opponentMinion2.SetTag(GameTag.CONTROLLER, _heroOpponent.Id);
            _playerSpell1 = CreateNewEntity("CS2_029");
            _playerSpell1.SetTag(GameTag.CARDTYPE, (int)CardType.SPELL);
            _playerSpell1.SetTag(GameTag.CARD_TARGET, _opponentMinion1.Id);
            _playerSpell1.SetTag(GameTag.CONTROLLER, _heroPlayer.Id);
            _playerSpell2 = CreateNewEntity("CS2_025");
            _playerSpell2.SetTag(GameTag.CARDTYPE, (int)CardType.SPELL);
            _playerSpell2.SetTag(GameTag.CONTROLLER, _heroPlayer.Id);

            _game.Entities.Add(2, _playerMinion1);
            _game.Entities.Add(3, _opponentMinion1);
            _game.Entities.Add(4, _opponentMinion2);

            _secretHunter1 = CreateNewEntity("");
            _secretHunter1.SetTag(GameTag.CLASS, (int)CardClass.HUNTER);
            _secretHunter2 = CreateNewEntity("");
            _secretHunter2.SetTag(GameTag.CLASS, (int)CardClass.HUNTER);
            _secretMage1 = CreateNewEntity("");
            _secretMage1.SetTag(GameTag.CLASS, (int)CardClass.MAGE);
            _secretMage2 = CreateNewEntity("");
            _secretMage2.SetTag(GameTag.CLASS, (int)CardClass.MAGE);
            _secretPaladin1 = CreateNewEntity("");
            _secretPaladin1.SetTag(GameTag.CLASS, (int)CardClass.PALADIN);
            _secretPaladin2 = CreateNewEntity("");
            _secretPaladin2.SetTag(GameTag.CLASS, (int)CardClass.PALADIN);

            _gameEventHandler.HandleOpponentSecretPlayed(_secretHunter1, "", 0, 0, Zone.HAND, _secretHunter1.Id);
            _gameEventHandler.HandleOpponentSecretPlayed(_secretMage1, "", 0, 0, Zone.HAND, _secretMage1.Id);
            _gameEventHandler.HandleOpponentSecretPlayed(_secretPaladin1, "", 0, 0, Zone.HAND, _secretPaladin1.Id);
        }
        public void Setup()
        {
            _game = new GameV2();
            _gameEventHandler = new GameEventHandler(_game);

            _heroPlayer = CreateNewEntity("HERO_01");
            _heroPlayer.SetTag(GAME_TAG.CARDTYPE, (int) TAG_CARDTYPE.HERO);
            _heroPlayer.IsPlayer = true;
            _heroOpponent = CreateNewEntity("HERO_02");
            _heroOpponent.SetTag(GAME_TAG.CARDTYPE, (int) TAG_CARDTYPE.HERO);
            _heroOpponent.SetTag(GAME_TAG.CONTROLLER, _heroOpponent.Id);
            _heroOpponent.IsPlayer = false;

            _game.Entities.Add(0, _heroPlayer);
            _game.Player.Id = _heroPlayer.Id;
            _game.Entities.Add(1, _heroOpponent);
            _game.Opponent.Id = _heroOpponent.Id;

            _playerMinion1 = CreateNewEntity("EX1_010");
            _playerMinion1.SetTag(GAME_TAG.CARDTYPE, (int)TAG_CARDTYPE.MINION);
            _playerMinion1.SetTag(GAME_TAG.CONTROLLER, _heroPlayer.Id);
            _opponentMinion1 = CreateNewEntity("EX1_020");
            _opponentMinion1.SetTag(GAME_TAG.CARDTYPE, (int)TAG_CARDTYPE.MINION);
            _opponentMinion1.SetTag(GAME_TAG.CONTROLLER, _heroOpponent.Id);
            _opponentMinion2 = CreateNewEntity("EX1_021");
            _opponentMinion2.SetTag(GAME_TAG.CARDTYPE, (int)TAG_CARDTYPE.MINION);
            _opponentMinion2.SetTag(GAME_TAG.CONTROLLER, _heroOpponent.Id);

            _game.Entities.Add(2, _playerMinion1);
            _game.Entities.Add(3, _opponentMinion1);
            _game.Entities.Add(4, _opponentMinion2);

            _secretHunter1 = CreateNewEntity("");
            _secretHunter1.SetTag(GAME_TAG.CLASS, (int) TAG_CLASS.HUNTER);
            _secretHunter2 = CreateNewEntity("");
            _secretHunter2.SetTag(GAME_TAG.CLASS, (int) TAG_CLASS.HUNTER);
            _secretMage1 = CreateNewEntity("");
            _secretMage1.SetTag(GAME_TAG.CLASS, (int) TAG_CLASS.MAGE);
            _secretMage2 = CreateNewEntity("");
            _secretMage2.SetTag(GAME_TAG.CLASS, (int) TAG_CLASS.MAGE);
            _secretPaladin1 = CreateNewEntity("");
            _secretPaladin1.SetTag(GAME_TAG.CLASS, (int) TAG_CLASS.PALADIN);
            _secretPaladin2 = CreateNewEntity("");
            _secretPaladin2.SetTag(GAME_TAG.CLASS, (int) TAG_CLASS.PALADIN);

            _gameEventHandler.HandleOpponentSecretPlayed(_secretHunter1, "", 0, 0, false, _secretHunter1.Id);
            _gameEventHandler.HandleOpponentSecretPlayed(_secretMage1, "", 0, 0, false, _secretMage1.Id);
            _gameEventHandler.HandleOpponentSecretPlayed(_secretPaladin1, "", 0, 0, false, _secretPaladin1.Id);
        }
        private void Analyze(string log)
        {
            var logLines = log.Split('\n');

            foreach (var logLine in logLines)
            {
                _currentOffset += logLine.Length + 1;
                if (logLine.StartsWith("[Power]"))
                {
                    _powerCount++;

                    if ((_currentPlayer == Turn.Player && !_playerUsedHeroPower) || _currentPlayer == Turn.Opponent && !_opponentUsedHeroPower)
                    {
                        if (_heroPowerRegex.IsMatch(logLine))
                        {
                            var id = _heroPowerRegex.Match(logLine).Groups["Id"].Value.Trim();
                            if (!string.IsNullOrEmpty(id))
                            {
                                var heroPower = Game.GetCardFromId(id);
                                if (heroPower.Type == "Hero Power")
                                {
                                    if (_currentPlayer == Turn.Player)
                                    {
                                        GameEventHandler.HandlePlayerHeroPower(id, GetTurnNumber());
                                        _playerUsedHeroPower = true;
                                    }
                                    else
                                    {
                                        GameEventHandler.HandleOpponentHeroPower(id, GetTurnNumber());
                                        _opponentUsedHeroPower = true;
                                    }
                                }
                            }
                        }
                    }
                }
                else if (logLine.StartsWith("[Asset]"))
                {
                    if (logLine.ToLower().Contains("victory_screen_start"))
                    {
                        GameEventHandler.HandleWin();
                    }
                    else if (logLine.ToLower().Contains("defeat_screen_start"))
                    {
                        GameEventHandler.HandleLoss();
                    }
                    else if (logLine.Contains("rank_window"))
                    {
                        Game.CurrentGameMode = Game.GameMode.Ranked;
                        Logger.WriteLine(">>> GAME MODE: RANKED");
                    }
                }
                else if (logLine.StartsWith("[Bob] legend rank"))
                {
                    if (!Game.IsInMenu)
                    {
                        GameEventHandler.HandleGameEnd(false);
                    }
                }
                else if (logLine.StartsWith("[Bob] ---RegisterScreenPractice---"))
                {
                    Game.CurrentGameMode = Game.GameMode.Practice;
                    Logger.WriteLine(">>> GAME MODE: PRACTICE");
                }
                else if (logLine.StartsWith("[Bob] ---RegisterScreenTourneys---"))
                {
                    Game.CurrentGameMode = Game.GameMode.Casual;
                    Logger.WriteLine(">>> GAME MODE: CASUAL (RANKED)");
                }
                else if (logLine.StartsWith("[Bob] ---RegisterScreenForge---"))
                {
                    Game.CurrentGameMode = Game.GameMode.Arena;
                    Logger.WriteLine(">>> GAME MODE: ARENA");
                }
                else if (logLine.StartsWith("[Bob] ---RegisterScreenFriendly---"))
                {
                    Game.CurrentGameMode = Game.GameMode.Friendly;
                    Logger.WriteLine(">>> GAME MODE: FRIENDLY");
                }
                else if (logLine.StartsWith("[Bob] ---RegisterScreenBox---"))
                {
                    //game ended

                    Game.CurrentGameMode = Game.GameMode.None;
                    Logger.WriteLine(">>> GAME MODE: NONE");

                    GameEventHandler.HandleGameEnd(true);
                    _lastGameEnd = _currentOffset;
                    _turnCount   = 0;
                    _lastOpponentDrawIncrementedTurn = false;
                    _lastPlayerDrawIncrementedTurn   = false;
                    ClearLog();
                }
                else if (logLine.StartsWith("[Zone]"))
                {
                    if (_cardMovementRegex.IsMatch(logLine))
                    {
                        var match = _cardMovementRegex.Match(logLine);

                        var id   = match.Groups["Id"].Value.Trim();
                        var from = match.Groups["from"].Value.Trim();
                        var to   = match.Groups["to"].Value.Trim();

                        var zonePos = -1;
                        //var zone = string.Empty;

                        // Only for some log lines, should be valid in every action where we need it
                        if (_opponentPlayRegex.IsMatch(logLine))
                        {
                            var match2 = _opponentPlayRegex.Match(logLine);
                            zonePos = Int32.Parse(match2.Groups["zonePos"].Value.Trim());
                        }
                        if (_zoneRegex.IsMatch(logLine))
                        {
                            //var match3 = _zoneRegex.Match(logLine);
                            //zone = match3.Groups["zone"].Value.Trim();
                            GameEventHandler.PlayerSetAside(id);
                        }

                        //game start/end
                        if (id.Contains("HERO") || (id.Contains("NAX") && id.Contains("_01")))
                        {
                            if (!from.Contains("PLAY"))
                            {
                                if (to.Contains("FRIENDLY"))
                                {
                                    GameEventHandler.HandleGameStart(_heroIdDict[id]);
                                }
                                else if (to.Contains("OPPOSING"))
                                {
                                    string heroName;
                                    if (_heroIdDict.TryGetValue(id, out heroName))
                                    {
                                        GameEventHandler.SetOpponentHero(heroName);
                                    }
                                }
                            }
                            _powerCount = 0;
                            continue;
                        }

                        switch (from)
                        {
                        case "FRIENDLY DECK":
                            if (to == "FRIENDLY HAND")
                            {
                                //player draw
                                if (_powerCount >= PowerCountTreshold)
                                {
                                    _turnCount++;
                                    GameEventHandler.TurnStart(Turn.Player, GetTurnNumber());
                                    _currentPlayer                 = Turn.Player;
                                    _playerUsedHeroPower           = false;
                                    _lastPlayerDrawIncrementedTurn = true;
                                }
                                else
                                {
                                    _lastPlayerDrawIncrementedTurn = false;
                                }
                                GameEventHandler.HandlePlayerDraw(id, GetTurnNumber());
                            }
                            else if (to == "FRIENDLY SECRET")
                            {
                                GameEventHandler.HandlePlayerSecretPlayed(id, GetTurnNumber(), true);
                            }
                            else
                            {
                                //player discard from deck
                                GameEventHandler.HandlePlayerDeckDiscard(id, GetTurnNumber());
                            }
                            break;

                        case "FRIENDLY HAND":
                            if (to == "FRIENDLY DECK")
                            {
                                if (_lastPlayerDrawIncrementedTurn)
                                {
                                    _turnCount--;
                                }
                                GameEventHandler.HandlePlayerMulligan(id);
                            }
                            else if (to == "FRIENDLY PLAY")
                            {
                                GameEventHandler.HandlePlayerPlay(id, GetTurnNumber());
                            }
                            else if (to == "FRIENDLY SECRET")
                            {
                                GameEventHandler.HandlePlayerSecretPlayed(id, GetTurnNumber(), false);
                            }
                            else
                            {
                                //player discard from hand and spells
                                GameEventHandler.HandlePlayerHandDiscard(id, GetTurnNumber());
                            }

                            break;

                        case "FRIENDLY PLAY":
                            if (to == "FRIENDLY HAND")
                            {
                                GameEventHandler.HandlePlayerBackToHand(id, GetTurnNumber());
                            }
                            break;

                        case "OPPOSING HAND":
                            if (to == "OPPOSING DECK")
                            {
                                if (_lastOpponentDrawIncrementedTurn)
                                {
                                    _turnCount--;
                                }
                                //opponent mulligan
                                GameEventHandler.HandleOpponentMulligan(zonePos);
                            }
                            else if (to == "OPPOSING SECRET")
                            {
                                GameEventHandler.HandleOpponentSecretPlayed(id, zonePos, GetTurnNumber(), false);
                            }
                            else if (to == "OPPOSING PLAY")
                            {
                                GameEventHandler.HandleOpponentPlay(id, zonePos, GetTurnNumber());
                            }
                            else
                            {
                                GameEventHandler.HandleOpponentHandDiscard(id, zonePos, GetTurnNumber());
                            }

                            break;

                        case "OPPOSING DECK":
                            if (to == "OPPOSING HAND")
                            {
                                if (_powerCount >= PowerCountTreshold)
                                {
                                    _turnCount++;
                                    GameEventHandler.TurnStart(Turn.Opponent, GetTurnNumber());
                                    _currentPlayer                   = Turn.Opponent;
                                    _opponentUsedHeroPower           = false;
                                    _lastOpponentDrawIncrementedTurn = true;
                                }
                                else
                                {
                                    _lastOpponentDrawIncrementedTurn = false;
                                }

                                //opponent draw
                                GameEventHandler.HandlOpponentDraw(GetTurnNumber());
                            }
                            else if (to == "OPPOSING SECRET")
                            {
                                GameEventHandler.HandleOpponentSecretPlayed(id, zonePos, GetTurnNumber(), true);
                            }
                            else
                            {
                                //opponent discard from deck
                                GameEventHandler.HandleOpponentDeckDiscard(id, GetTurnNumber());
                            }


                            break;

                        case "OPPOSING SECRET":
                            //opponent secret triggered
                            GameEventHandler.HandleOpponentSecretTrigger(id, GetTurnNumber());
                            break;

                        case "OPPOSING PLAY":
                            if (to == "OPPOSING HAND")                                    //card from play back to hand (sap/brew)
                            {
                                GameEventHandler.HandleOpponentPlayToHand(id, GetTurnNumber());
                            }
                            break;

                        default:
                            if (to == "OPPOSING HAND")
                            {
                                //coin, thoughtsteal etc
                                GameEventHandler.HandleOpponentGet(GetTurnNumber());
                            }
                            else if (to == "FRIENDLY HAND")
                            {
                                //coin, thoughtsteal etc
                                GameEventHandler.HandlePlayerGet(id, GetTurnNumber());
                            }
                            else if (to == "OPPOSING GRAVEYARD" && from == "" && id != "")
                            {
                                //todo: not sure why those two are here
                                //CardMovement(this, new CardMovementArgs(CardMovementType.OpponentPlay, id));
                            }
                            else if (to == "FRIENDLY GRAVEYARD" && from == "")
                            {
                                // CardMovement(this, new CardMovementArgs(CardMovementType.PlayerPlay, id));
                            }
                            break;
                        }
                        _powerCount = 0;
                    }
                }
            }
        }