#include "GameRecordNow.h"

#include "Bases.h"
#include "GameCommander.h"
#include "OpponentModel.h"
#include "ScoutManager.h"

using namespace UAlbertaBot;

void GameRecordNow::writeSkills(std::ostream & output) const
{
    the.skillkit.write(output);
}

// Take a digest snapshot of the game situation.
void GameRecordNow::takeSnapshot()
{
    snapshots.push_back(new GameSnapshot(PlayerSnapshot (BWAPI::Broodwar->self()), PlayerSnapshot (BWAPI::Broodwar->enemy())));
}

// Figure out whether the enemy has seen our base yet.
bool GameRecordNow::enemyScoutedUs() const
{
    Base * base = Bases::Instance().myStart();

    for (const auto & kv : InformationManager::Instance().getUnitData(BWAPI::Broodwar->enemy()).getUnits())
    {
        const UnitInfo & ui(kv.second);

        // If a unit was last spotted close to us, assume we've been seen.
        if (ui.lastPosition.getDistance(base->getCenter()) < 800)
        {
            return true;
        }
    }

    return false;
}

// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

// Constructor for the record of the current game.
// When this object is initialized, the opening and some other items are not yet known.
GameRecordNow::GameRecordNow()
{
}

// Called when the game is over.
void GameRecordNow::setWin(bool isWinner)
{
    win = isWinner;
    frameGameEnds = BWAPI::Broodwar->getFrameCount();
}

void GameRecordNow::update()
{
    int now = BWAPI::Broodwar->getFrameCount();

    // Update the when-it-happens frame counters. We don't actually need to check often.
    if (now % 32 == 30)
    {
        if (enemyRace == BWAPI::Races::Unknown)
        {
            enemyRace = BWAPI::Broodwar->enemy()->getRace();
        }
        if (!enemyStartingBaseID && the.bases.enemyStart())
        {
            enemyStartingBaseID = the.bases.enemyStart()->getID();
        }
        enemyPlan = OpponentModel::Instance().getEnemyPlan();
        if (!frameWeMadeFirstCombatUnit && InformationManager::Instance().weHaveCombatUnits())
        {
            frameWeMadeFirstCombatUnit = now;
        }
        if (!frameWeGatheredGas && BWAPI::Broodwar->self()->gatheredGas() > 0)
        {
            frameWeGatheredGas = now;
        }
        if (!frameEnemyScoutsOurBase && enemyScoutedUs())
        {
            frameEnemyScoutsOurBase = now;
        }
        if (!frameEnemyGetsCombatUnits && InformationManager::Instance().enemyHasCombatUnits())
        {
            frameEnemyGetsCombatUnits = now;
        }
        if (!frameEnemyUsesGas && InformationManager::Instance().enemyGasTiming() > 0)
        {
            frameEnemyUsesGas = InformationManager::Instance().enemyGasTiming();
        }
        if (!frameEnemyGetsAirUnits && InformationManager::Instance().enemyHasAirTech())
        {
            frameEnemyGetsAirUnits = now;
        }
        if (!frameEnemyGetsStaticAntiAir && InformationManager::Instance().enemyHasStaticAntiAir())
        {
            frameEnemyGetsStaticAntiAir = now;
        }
        if (!frameEnemyGetsMobileAntiAir && InformationManager::Instance().enemyHasAntiAir())
        {
            frameEnemyGetsMobileAntiAir = now;
        }
        if (!frameEnemyGetsCloakedUnits && InformationManager::Instance().enemyHasCloakTech())
        {
            frameEnemyGetsCloakedUnits = now;
        }
        if (!frameEnemyGetsStaticDetection && InformationManager::Instance().enemyHasStaticDetection())
        {
            frameEnemyGetsStaticDetection = now;
        }
        if (!frameEnemyGetsMobileDetection && InformationManager::Instance().enemyHasMobileDetection())
        {
            frameEnemyGetsMobileDetection = now;
        }
    }

    /* disabled
    // If it's time, take a snapshot.
    int sinceFirst = now - firstSnapshotTime;
    if (sinceFirst >= 0 && sinceFirst % snapshotInterval == 0)
    {
        takeSnapshot();
    }
    */
}
