#ifndef __OVERHEAD_H
#define __OVERHEAD_H

#include <string.h>
#include <stdio.h>
#include "Soldier Control.h"
#include "overhead types.h"
#include "soldier find.h"
#include "Campaign Types.h"		// added by Flugente for SECTORINFO and UNDERGROUND_SECTORINFO
#define             ADD_SOLDIER_NO_PROFILE_ID       200

#define MAX_REALTIME_SPEED_VAL                      10

// Enums for waiting for mercs to finish codes
enum
{   
    NO_WAIT_EVENT = 0,
    WAIT_FOR_MERCS_TO_WALKOFF_SCREEN,
    WAIT_FOR_MERCS_TO_WALKON_SCREEN,
    WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO
};

// TACTICAL ENGINE STATUS FLAGS
typedef struct
{
    UINT8           bFirstID;
    UINT8           bLastID;
    COLORVAL    RadarColor;
    INT8        bSide;
    INT8            bMenInSector;
    UINT8           ubLastMercToRadio;
    INT8        bTeamActive;
    INT8        bAwareOfOpposition;
    INT8        bHuman;
} TacticalTeamType;

//for use with TacticalStatusType.ubEnemyIntention 
enum
{
    INTENTION_SCOUTING,
    INTENTION_PATROLLING,
    INTENTION_ATTACKING,
    INTENTION_DEFENDING,
    INTENTION_RETREATING
};

//for use with TacticalStatusType.ubEnemyIntendedRetreatDirection 
enum
{
    RETREAT_NORTH,
    RETREAT_EAST,
    RETREAT_SOUTH,
    RETREAT_WEST
};

#define PANIC_BOMBS_HERE        0x01
#define PANIC_TRIGGERS_HERE     0x02
#define NUM_PANIC_TRIGGERS      3
#define ENEMY_OFFERED_SURRENDER 0x01

struct TacticalStatusType
{
    UINT32                          uiFlags;
    TacticalTeamType        Team[ MAXTEAMS ];
    UINT8                               ubCurrentTeam;
    INT32                               sSlideTarget;
    INT16                               sSlideReason;
    UINT32                          uiTimeSinceMercAIStart;
    INT8                                fPanicFlags;
    INT32                               sPanicTriggerGridNoUnused;
    INT16                               sHandGrid;
    UINT8                               ubSpottersCalledForBy;
    UINT8                               ubTheChosenOne;
    UINT32                          uiTimeOfLastInput;
    UINT32                          uiTimeSinceDemoOn;
    UINT32                          uiCountdownToRestart;
    BOOLEAN                         fGoingToEnterDemo;
    BOOLEAN                         fNOTDOLASTDEMO;
    BOOLEAN                         fMultiplayer;
    BOOLEAN                         fCivGroupHostile[ NUM_CIV_GROUPS ];
    UINT8                               ubLastBattleSectorX;                    
    UINT8                               ubLastBattleSectorY;
    BOOLEAN                         fLastBattleWon;
    INT8                                bOriginalSizeOfEnemyForce;
    INT8                                bPanicTriggerIsAlarmUnused;
    BOOLEAN                         fVirginSector;
    BOOLEAN                         fEnemyInSector;
    BOOLEAN                         fInterruptOccurred;
    INT8                                bRealtimeSpeed;
    UINT8                               ubEnemyIntention;
    UINT8                               ubEnemyIntendedRetreatDirection;
    UINT8                               ubEnemySightingOnTheirTurnEnemyID;
    UINT8                               ubEnemySightingOnTheirTurnPlayerID;
    BOOLEAN                         fEnemySightingOnTheirTurn;
    BOOLEAN                         fAutoBandageMode;
    UINT8                               ubAttackBusyCount;
    INT8                                bNumEnemiesFoughtInBattleUnused;
    UINT8                               ubEngagedInConvFromActionMercID;
    UINT16                          usTactialTurnLimitCounter;
    BOOLEAN                         fInTopMessage;
    UINT8                               ubTopMessageType;
    CHAR16                              zTopMessageString[20];
    UINT16                          usTactialTurnLimitMax;
    UINT32                          uiTactialTurnLimitClock;
    BOOLEAN                         fTactialTurnLimitStartedBeep;
    INT8                                bBoxingState;
    INT8                                bConsNumTurnsNotSeen;
    UINT8                               ubArmyGuysKilled;

    INT32                               sPanicTriggerGridNo[ NUM_PANIC_TRIGGERS ];
    INT8                                bPanicTriggerIsAlarm[ NUM_PANIC_TRIGGERS ];
    UINT8                               ubPanicTolerance[ NUM_PANIC_TRIGGERS ];
    BOOLEAN                         fAtLeastOneGuyOnMultiSelect;
    BOOLEAN                         fSaidCreatureFlavourQuote;
    BOOLEAN                         fHaveSeenCreature;
    BOOLEAN                         fKilledEnemyOnAttack;
    UINT8                               ubEnemyKilledOnAttack;
    INT8                                bEnemyKilledOnAttackLevel;
    UINT16                          ubEnemyKilledOnAttackLocation;
    BOOLEAN                         fItemsSeenOnAttack;
    BOOLEAN                         ubItemsSeenOnAttackSoldier;
    BOOLEAN                         fBeenInCombatOnce;
    BOOLEAN                         fSaidCreatureSmellQuote;
    UINT32                          usItemsSeenOnAttackGridNo;
    BOOLEAN                         fLockItemLocators;
    UINT8                               ubLastQuoteSaid;
    UINT8                               ubLastQuoteProfileNUm;
    BOOLEAN                         fCantGetThrough;
    INT32                               sCantGetThroughGridNo;
    INT32                               sCantGetThroughSoldierGridNo;
    UINT8                               ubCantGetThroughID;
    BOOLEAN                         fDidGameJustStart;
    BOOLEAN                         fStatChangeCheatOn;
    UINT8                               ubLastRequesterTargetID;
    BOOLEAN                         fGoodToAllowCrows;
    UINT8                               ubNumCrowsPossible;
    UINT32                          uiTimeCounterForGiveItemSrc;
    BOOLEAN                         fUnLockUIAfterHiddenInterrupt;
    INT8                                bNumFoughtInBattle[ MAXTEAMS ];
    UINT32                          uiDecayBloodLastUpdate;
    UINT32                          uiTimeSinceLastInTactical;
    BOOLEAN                         fHasAGameBeenStarted;
    INT8                                bConsNumTurnsWeHaventSeenButEnemyDoes;
    BOOLEAN                             fSomeoneHit;
    UINT8                               ubPaddingSmall;
    UINT32                          uiTimeSinceLastOpplistDecay;
    INT8                                bMercArrivingQuoteBeingUsed;
    UINT8                               ubEnemyKilledOnAttackKiller;
    BOOLEAN                         fCountingDownForGuideDescription;
    INT8                                bGuideDescriptionCountDown;
    UINT8                               ubGuideDescriptionToUse;
    INT8                                bGuideDescriptionSectorX;
    INT8                                bGuideDescriptionSectorY;
    INT8                                fEnemyFlags;
    BOOLEAN          fAutoBandagePending;
    BOOLEAN          fHasEnteredCombatModeSinceEntering;
    BOOLEAN          fDontAddNewCrows;
    UINT8               ubMorePadding;
    UINT16              sCreatureTenseQuoteDelay;
    UINT32              uiCreatureTenseQuoteLastUpdate;
    // SANDRO - added these
    UINT8                               ubLastRequesterSurgeryTargetID;
    UINT8                               ubInterruptPending;
	// sevenfm: Ctrl+D disable interrupts
	BOOLEAN								ubDisablePlayerInterrupts;
    // PADDING GONE!!!!!

};


extern UINT8    gbPlayerNum;
extern INT8     gbShowEnemies;

extern UINT16   gusSelectedSoldier;
extern UINT16   gusOldSelectedSoldier;

extern CHAR8    gzAlertStr[][ 30 ];
extern CHAR8    gzActionStr[][ 30 ];
extern CHAR8    gzDirectionStr[][ 30 ];

// TEMP FOR E3
extern UINT8    gubCurrentScene;
extern CHAR8    *GetSceneFilename(  );
extern INT8     ubLevelMoveLink[ 10 ];

// Soldier List used for all soldier overhead interaction
extern SOLDIERTYPE  Menptr[ TOTAL_SOLDIERS ];
extern SOLDIERTYPE  *MercPtrs[ TOTAL_SOLDIERS ];

// MERC SLOTS - A LIST OF ALL ACTIVE MERCS
extern SOLDIERTYPE  *MercSlots[ TOTAL_SOLDIERS ];
extern UINT32       guiNumMercSlots;

extern BOOLEAN      gfMovingAnimation;


extern TacticalStatusType   gTacticalStatus;

#define OUR_TEAM_SIZE_NO_VEHICLE (gTacticalStatus.Team[ OUR_TEAM ].bLastID - gTacticalStatus.Team[ OUR_TEAM ].bFirstID + 1 - gGameExternalOptions.ubGameMaximumNumberOfPlayerVehicles)


BOOLEAN InitTacticalEngine( );
void ShutdownTacticalEngine( );


BOOLEAN InitOverhead( );
BOOLEAN ShutdownOverhead( );
BOOLEAN GetSoldier( SOLDIERTYPE **ppSoldier, UINT16 usSoldierIndex );

UINT32 CountNonVehiclesOnPlayerTeam( );

BOOLEAN NewOKDestination( SOLDIERTYPE * pCurrSoldier, INT32 sGridNo, BOOLEAN fPeopleToo, INT8 bLevel );

//Simple check to see if a (one-tiled) soldier can occupy a given location on the ground or roof.
extern BOOLEAN IsLocationSittable( INT32 iMapIndex, BOOLEAN fOnRoof );
extern BOOLEAN IsLocationSittableExcludingPeople( INT32 iMapIndex, BOOLEAN fOnRoof );
extern BOOLEAN FlatRoofAboveGridNo( INT32 iMapIndex );


BOOLEAN ExecuteOverhead( );
BOOLEAN ResetAllAnimationCache( );

void EndTurn( );
void EndTurn( UINT8 ubNextTeam );

void StartPlayerTeamTurn( BOOLEAN fDoBattleSnd, BOOLEAN fEnteringCombatMode );
void EndTacticalDemo( );

void SelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fForceReselect    );

//Kaiden: Function declaration from UB to reveal all items after combat.
void RevealAllDroppedEnemyItems();

void LocateGridNo( INT32 sGridNo );
void LocateSoldier( UINT16 usID, BOOLEAN fSetLocator);

void BeginTeamTurn( UINT8 ubTeam );
void SlideTo(INT32 sGridNo, UINT16 usSoldierID , UINT16 usReasonID, BOOLEAN fSetLocator) ;
void SlideToLocation( UINT16 usReasonID, INT32 sDestGridNo );

void RebuildAllSoldierShadeTables( );
void HandlePlayerTeamMemberDeath( SOLDIERTYPE *pSoldier );
UINT8 LastActiveTeamMember( UINT8 ubTeam );
BOOLEAN SoldierOnVisibleWorldTile( SOLDIERTYPE *pSoldier );

UINT8 FindNextActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKLife, BOOLEAN fOnlyRegularMercs );
UINT8 FindPrevActiveAndAliveMerc( SOLDIERTYPE *pSoldier, BOOLEAN fGoodForLessOKLife, BOOLEAN fOnlyRegularMercs );

BOOLEAN CheckForPlayerTeamInMissionExit( );
void HandleNPCTeamMemberDeath( SOLDIERTYPE *pSoldier );

void StopMercAnimation( BOOLEAN fStop );

UINT32 EnterTacticalDemoMode();

BOOLEAN UIOKMoveDestination( SOLDIERTYPE *pSoldier, INT32 usMapPos );

INT32 FindAdjacentGridEx( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 *pubDirection, INT32 *psAdjustedGridNo, BOOLEAN fForceToPerson, BOOLEAN fDoor , bool allow_diagonal = false);
INT32 FindNextToAdjacentGridEx( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 *pubDirection, INT32 *psAdjustedGridNo, BOOLEAN fForceToPerson, BOOLEAN fDoor );


void SelectNextAvailSoldier( SOLDIERTYPE *pSoldier );
BOOLEAN TeamMemberNear(INT8 bTeam, INT32 sGridNo, INT32 iRange);
BOOLEAN IsValidTargetMerc( UINT8 ubSoldierID );

// FUNCTIONS FOR MANIPULATING MERC SLOTS - A LIST OF ALL ACTIVE MERCS
INT32 GetFreeMercSlot( );
INT32 AddMercSlot( SOLDIERTYPE *pSoldier );
BOOLEAN RemoveMercSlot( SOLDIERTYPE *pSoldier   );

INT32   AddAwaySlot( SOLDIERTYPE *pSoldier );
BOOLEAN RemoveAwaySlot( SOLDIERTYPE *pSoldier );
INT32   MoveSoldierFromMercToAwaySlot( SOLDIERTYPE * pSoldier );
INT32   MoveSoldierFromAwayToMercSlot( SOLDIERTYPE * pSoldier );

void EnterCombatMode( UINT8 ubStartingTeam );
void ExitCombatMode( );
void HandleTeamServices( UINT8 ubTeamNum );
void HandlePlayerServices( SOLDIERTYPE *pTeamSoldier );
void SetEnemyPresence( );
void CycleThroughKnownEnemies( BOOLEAN backward = FALSE );
BOOLEAN CheckForEndOfCombatMode( BOOLEAN fIncrementTurnsNotSeen );
SOLDIERTYPE * FreeUpAttacker( );
BOOLEAN PlayerTeamFull( );
void SetActionToDoOnceMercsGetToLocation( UINT8 ubActionCode, UINT8 uiNumMercsWaiting, UINT32 uiData1, UINT32 uiData2, UINT32 uiData3 );
void ResetAllMercSpeeds( );
BOOLEAN HandleGotoNewGridNo( SOLDIERTYPE *pSoldier, BOOLEAN *pfKeepMoving, BOOLEAN fInitialMove, UINT16 usAnimState );
SOLDIERTYPE * ReduceAttackBusyCount( );

// HEADROCK HAM B2.6: Made this public so it can be used elsewhere.
INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier );
// HEADROCK HAM 3.2: A new function for checking the condition of nearby friendlies and returning a modifier.
INT8 CheckStatusNearbyFriendlies( SOLDIERTYPE *pSoldier );
// sevenfm: simplified version
INT8 CheckStatusNearbyFriendliesSimple(SOLDIERTYPE *pSoldier);

void CommonEnterCombatModeCode( );
void CheckForPotentialAddToBattleIncrement( SOLDIERTYPE *pSoldier );
void CencelAllActionsForTimeCompression( );
BOOLEAN CheckForEndOfBattle( BOOLEAN fAnEnemyRetreated );
void AddManToTeam( INT8 bTeam );
void RemoveManFromTeam( INT8 bTeam );
void RemoveSoldierFromTacticalSector( SOLDIERTYPE *pSoldier, BOOLEAN fAdjustSelected );
void MakeCivHostile(SOLDIERTYPE *pSoldier);

#define REASON_NORMAL_ATTACK    1
#define REASON_EXPLOSION        2

BOOLEAN ProcessImplicationsOfPCAttack( SOLDIERTYPE * pSoldier, SOLDIERTYPE ** ppTarget, INT8 bReason );
INT32 FindAdjacentPunchTarget( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTargetSoldier, INT32 * psAdjustedTargetGridNo, UINT8 * pubDirection );
SOLDIERTYPE * CivilianGroupMemberChangesSides( SOLDIERTYPE * pAttacked );
void CivilianGroupChangesSides( UINT8 ubCivilianGroup );
void CycleVisibleEnemies( SOLDIERTYPE *pSrcSoldier );
void CycleVisibleEnemiesBackward( SOLDIERTYPE *pSrcSoldier );
UINT8 CivilianGroupMembersChangeSidesWithinProximity( SOLDIERTYPE * pAttacked );
void PauseAITemporarily( );
void PauseAIUntilManuallyUnpaused( );
void UnPauseAI( );
void DoPOWPathChecks( );
BOOLEAN HostileCiviliansWithGunsPresent( );
BOOLEAN HostileCiviliansPresent( );
BOOLEAN HostileBloodcatsPresent( );
BOOLEAN HostileZombiesPresent( );
BOOLEAN HostileCreaturesPresent();

UINT8 NumPCsInSector( );
void SetSoldierNonNeutral( SOLDIERTYPE * pSoldier );
void SetSoldierNeutral( SOLDIERTYPE * pSoldier );

#ifdef JA2UB
void HandleThePlayerBeNotifiedOfSomeoneElseInSector();
void SetMsgBoxForPlayerBeNotifiedOfSomeoneElseInSector();

void HandleDisplayingOfPlayerLostDialogue( );

// UTILITY FUNCTIONS
INT8    NumActiveAndConsciousTeamMembers( UINT8 ubTeam );
UINT8 NumEnemyInSector( );
UINT8 NumCapableEnemyInSector( );
INT8    NumMercsOnPlayerTeam( );
#endif

extern BOOLEAN sniperwarning;
extern BOOLEAN biggunwarning;
extern BOOLEAN gogglewarning;
//extern BOOLEAN airstrikeavailable;

//void CheckForAndSetupAirRaid ();
//void EnemyCallInAirStrike (INT16 sSectorX, INT16 sSectorY);

// will a sam site under the players control shoot down an airraid?
BOOLEAN WillAirRaidBeStopped( INT16 sSectorX, INT16 sSectorY );
// HEADROCK HAM 3.5: Externalized for First Arrival enemy check
extern UINT8 NumEnemyInSector();

// Flugente
extern UINT8 NumZombiesInSector();

// Flugente: offer the enemy the chance to surrender
void HandleSurrenderOffer( SOLDIERTYPE* pSoldier );

// Flugente: attempt to convince a soldier to become a turncoat
void HandleTurncoatAttempt( SOLDIERTYPE* pSoldier );

// Flugente: disguised mercs can distract enemies by talking to them. In order to display that, we sometimes display excerpts of their 'chats'
void CheckChatPartners();

// Flugente: order a team to drop gear, or pick it up
// setting fForce to TRUE allows dropping of gear in combat (used in auto-resolve instances)
void TeamDropAll(UINT8 bTeam, BOOLEAN fForce = FALSE);
void TeamRestock(UINT8 bTeam);

// are we allowed to steal access this guy's inventory?
BOOLEAN AllowedToStealFromTeamMate( UINT8 aAccessorID, UINT8 aTargetID );

// Flugente: is an soldier profile already used?
BOOLEAN IsProfileInUse(UINT8 usTeam, INT8 aType, UINT16 aNr);

// Flugente: functions altering a sector's prisoners
UINT16 GetNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aPrisoners[] );
UINT16 GetNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aPrisoners[] );

void ChangeNumberOfPrisoners( SECTORINFO *pSectorInfo, INT16 aPrisoners[] );
void ChangeNumberOfPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo, INT16 aPrisoners[] );

void DeleteAllPrisoners( SECTORINFO *pSectorInfo );
void DeleteAllPrisoners( UNDERGROUND_SECTORINFO *pSectorInfo );

// used when the player kills a prisoner. We kill of high-value prisoners first, to punish this kind of behaviour
void KillOnePrisoner( SECTORINFO *pSectorInfo );

// sevenfm: calc shock level with modifiers (traits, backgrounds, ...)
INT8 CalcEffectiveShockLevel( SOLDIERTYPE * pSoldier );
BOOLEAN CoweringShockLevel( SOLDIERTYPE * pSoldier );
// Flugente: enemy officers
enum {
	OFFICER_NONE = 0,
	OFFICER_LIEUTNANT,
	OFFICER_CAPTAIN,

	OFFICER_MAX,
};

// Flugente: return number of enemy officers and highest rank found
UINT8 HighestEnemyOfficersInSector(UINT8& aType);

// count all soldiers in the current sector that have a specific flag set
UINT16 NumSoldiersWithFlagInSector(UINT8 aTeam, UINT32 aFlag);
UINT16 NumSoldiersofClassWithFlag2InSector( UINT8 aTeam, UINT8 aSoldierClass, UINT32 aFlag );
INT32 GetClosestSoldierWithFlag( UINT8 aTeam, UINT32 aFlag );

// Flugente: VIP targets
// can a new VIP be created?
BOOLEAN VIPSlotFree();

BOOLEAN SectorHasVIP( INT16 sMapX, INT16 sMapY );
BOOLEAN PlayerKnowsAboutVIP( INT16 sMapX, INT16 sMapY );

BOOLEAN TownHasVIP( INT8 bTownId );

BOOLEAN GetRandomEnemyTownSector( INT8 bTownId, UINT16& aSector );

// Get a possible sector for a VIP to spawn in. Note: we do not spawn new VIPs in Meduna - VIPs that escape move there instead
BOOLEAN GetPossibleVIPSector( UINT16& aSector );

// Get the location of a VIP we do not yet know about
BOOLEAN GetRandomUnknownVIPSector( UINT16& aSector );

void DeleteVIP( INT16 sMapX, INT16 sMapY );
void VIPFleesToMeduna();

// Flugente: is any member of a specific civilian faction still alive in the current sector?
BOOLEAN IsCivFactionMemberAliveInSector( UINT8 usCivilianGroup );

BOOLEAN IsFreeSlotAvailable( int aTeam );

#endif

