//---------------------------------------------------------------------------
#ifndef BeFuncH
#define BeFuncH
/*
#include "AlignmentUnit.h"
#include "VerbalUnit.h"
#include "ActionsUnit.h"
*/
#define DUMMY 1
#ifdef DUMMY

#include <windows.h>
//---------------------------------------------------------------------------
//-- Open BE (c) exported functions for loadtime link... --------------------
//------... and datatypes ---------------------------------------------------
//---------------------------------------------------------------------------

#define MANUAL_GOAL 0xFF

#define SEEMED  0
#define BOTH    2

typedef unsigned char ActionError;
//ActionError codes
#define ACTION_SUCCESS  	0
#define ACTION_FAILURE      1
#define	ACTION_NOT_PRIMED	2
#define NO_CANDIDATES       3
#define LO_WICK				4
#define HI_WICK				5
#define LO_ANA				6
#define HI_ANA				7
#define	LO_INT				8
#define	HI_INT				9
#define	LO_COU				10
#define TOO_FOREIGN			11
#define	NOT_INTERESTED_IN_DEAL			12
#define BAD_COMBAT_ODDS		13
#define WOULD_NOT_BELIEVE	14
#define HI_ATT              15
#define LO_ATT              16
#define NO_TRUST            17
#define PAST_FAILURE        18
#define STRATEGY_ABORTED    19

#define  GOAL_NONE          0
#define  ERROR_PERCENTAGE   -127

// -- Agent defines used to be part of enum ---
#define alPureGood      0
#define alLawfulGood    1
#define alLawfulNeutral 2
#define alLawfulEvil    3
#define alNeutralGood   4
#define alTrueNeutral   5
#define alNeutralEvil   6
#define alChaoticGood   7
#define alChaoticNeutral  8
#define alChaoticEvil   9
#define alUltimateEvil  10
#define UNSURPASSED_IMPORTANCE 11

//-----------------------------------------------------------------------
#define ITEM_ITEMID(it_p) ((it_p) == NULL ? (ID)0 : (it_p)->ItemID)

#define ACTION_ITEMID(act_p) ((act_p) == NULL ? (ID)0 :\
            ((act_p)->GetObjItem() == NULL ? (ID)0 : \
            (act_p)->GetObjItem()->ItemID ) )

#define STRATEGY_ITEMID(strat) ((strat).GetObjItem() == NULL ? (ID)0 :\
            (strat).GetObjItem()->ItemID == NULL)
//-----------------------------------------------------------------------

char *LastBEError();
void APIError();


typedef signed char percentage;
typedef unsigned short ID;

/*
typedef enum { alPureGood, alLawfulGood, alLawfulNeutral, alLawfulEvil,
	alNeutralGood, alTrueNeutral, alNeutralEvil, alChaoticGood,
	alChaoticNeutral, alChaoticEvil, alUltimateEvil } AlignmentType ;
*/
typedef ID AlignmentType;

struct _Attitude {
  ID person_id;
  percentage Real;
  percentage Seemed;
  struct _Attitude *RSon, *LSon;
} ;

typedef struct _Attitude   Attitude;

typedef struct _Core {
  AlignmentType alType;
  percentage Wickedness;
  percentage Anarchy;

  //secondary Agent variables
  percentage InitialAttitude; //neutral, uninfluenced starting personal attitude
  percentage AttitudeChangeUnit;
  percentage SuddenChange;

//  percentage Aggression;
  percentage   LieProbability;
  //Impression values - [1] means "true social"; [0] -
  // "seemed social"
  percentage Meanness[2], Wealth[2], Beauty;
  percentage Foreignness;
  percentage Intelligence[2], Courage;
  short UserDefined[3];
  ID attId;
  Attitude *attPersonal; //binary tree of personal attitudes
  _Core *LastAccessedBy;
  unsigned char CurrentEnvironment;
    // nature of actions aimed at this person
  ID LastTargettedInAction, LastCommittedAction;
  BOOL Dead;
} Core;

typedef struct {
    ID ItemID;
    ID Owner;
	percentage Wickedness;
	percentage Anarchy;
	percentage Meanness, Foreignness, Wealth, Beauty, Personality;
	percentage Influence;	//0 to 100 - percentage of influence on the
    		//overall Impression
    BOOL CanBeDivided;
    unsigned short UserDefined[3];
} ItemScores;

typedef ItemScores* ItemPtr;
typedef ItemPtr*    ItemPtrArr;

typedef enum { UNDEFINED = 0, VERBAL = 1, COMMERCIAL = 2, MECHANIC = 3,
        VITAL = 4, STRATEGY_CALL = 5 }
	ActionType;

typedef struct {
	ID Itself;
    percentage Importance; //actual importance is Strategy property only
} Goal;

struct _GoalDefNode {
	Goal goal;
    char Descr[26];
	Core LoReqs, HiReqs; //that's for the "autorun" feature
        //and criteria
    unsigned char CompType,AttDir,IdFlag1;
    ID IdFlag2;
    ID UserDefAttID;
    ID AttRefAct;
    ID IncGoalID;
	struct _GoalDefNode *next;
};
typedef struct _GoalDefNode* GoalDefNodeP;

struct _ActionDefNode {
	ID ActionID;
    char Verb[21];
    int (*ActionFn)(void*);
    ID ModNum;
    ActionType _Type;
    percentage Difficulty;
	percentage Wickedness, Anarchy;
	percentage AttitudeChange;
    	//not effective change, but a multiplier
    	//of AttitudeChangeUnit
    	// ******** "solid" scores ********
    percentage MinIntel, ReqCourage, MinAttitude, MaxAttitude;
	struct _ActionDefNode *next;
};
typedef struct _ActionDefNode* ActionDefNodeP;

struct _StrategyDefNode {
	ID StrategyID;
    char Name[16],Descr[51];
    Goal TheGoal;
    percentage MaxIntel;
    unsigned char _Type;
    ID ActionsNo;
    //dynamic array
    ID *ActionIDs;
    unsigned char *TACs;
    unsigned char *ReferencedTACs;
    unsigned char *ConditionalGoto;
    unsigned char *Verbal1Ind, *Verbal2Ind;
    //the 2 last are indices that hold verbal actions' contents

    ID *Verbal1;
    unsigned char *Verbal1TACs;
    unsigned char *v1ReferencedTACs;
    unsigned char *v1ConditionalGoto;
    ID *Verbal2;
    unsigned char *Verbal2TACs;
    unsigned char *v2ReferencedTACs;
    unsigned char *v2ConditionalGoto;
	struct _StrategyDefNode *next;
};
typedef struct _StrategyDefNode* StrategyDefNodeP;

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void Stop(char *);
GoalDefNodeP GetGoalNode(ID);
ActionDefNodeP GetActionNode(ID);
StrategyDefNodeP GetStrategyNode(ID);
percentage GetAttitude(ID , Attitude *, BOOL = TRUE);
BOOL AddAttitude(ID , percentage , Attitude **);
BOOL ModifyAttitude(ID , short , Attitude *, unsigned char = 2);
BOOL UpdateAttitude(ID , percentage ,//set or add
	Attitude **, unsigned char = 2);
void DelAttitudeTree(Attitude **);
Attitude *CopyAttitudeTree(Attitude*);
void Attitudes2String(Attitude *, char *);

//-----------------------------------------------------------------------
//-------------- Action and Strategy  class -----------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
class Action{
public:
	Action();
    Action(Action*);
    Action(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
		percentage BasicAnarArg, percentage MinIntArg, percentage ReqCouArg,
        percentage BasicAttitudeChangeArg, ID ActionIDArg, percentage MinAttArg,
        percentage MaxAttArg, int (*ActionFnArg)(void*));
    ~Action();
    void Init(ActionType , percentage , percentage ,
		percentage , percentage , percentage ,
        percentage , ID , percentage ,
        percentage , int (*)(void*));
	void Init(Action *);
    void SetActionFn(int (*)(void*));
    void InitTargets(Core * = NULL, Core * = NULL,
    	ItemScores * = NULL);//, Core* = NULL);
    void ResetTargets();
    Core *GetInitiator();
    Core *GetObjective();
    ItemScores *GetObjItem();
    Action *GetReported1Ptr();
    Action *GetReported2Ptr();
    void SetReported1(Action *);
    void SetReported2(Action *);
    void InitScores(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
    	percentage BasicAnarArg, percentage MinIntArg,
        percentage ReqCouArg, percentage BasicAttitudeChangeArg,
        percentage MinAttArg, percentage MaxAttArg);
	void ResetScores();
    void GetActualScores(percentage& ActualDiffArg, percentage& ActualWickArg,
    	percentage& ActualAnarArg, percentage& ActualAttChg);
    void GetSolidScores(percentage& , percentage&);
    void GetAttitudeLimits(percentage& , percentage&);
    ActionType GetType();
    ActionError Execute(void*, BOOL = FALSE, unsigned char = 0, percentage = 0);
    BOOL IsReady();
    ID GetID();
//  BOOL byLieCheckActive;
    void SetTargetAssignmentCriteria(unsigned char);
    void SetRefTAC(unsigned char);
    void SetFailureGoto(unsigned char);
    unsigned char GetTargetAssignmentCriteria();
    unsigned char GetRefTAC();
    unsigned char GetFailureGoto();
    percentage GetDealValue();
//    void SetID(ID IDarg) { ActionID = IDarg; }
    unsigned short FillSaveBuffer(BYTE*);
    void RestoreFromBuffer(BYTE *, Core **, unsigned short,
        ItemPtrArr*, unsigned short *);
    Action *Reported1,*Reported2;
    BOOL SkipChecks;
protected:
    ID ActionID;
    void CalcActualScores(BOOL = TRUE, percentage = 0, percentage = 0);
    void UpdateObjective();
    BOOL MeannessCheck(BOOL = TRUE, BOOL = FALSE, percentage = 0);
    ActionType ForeignnessCheck();
    BOOL WealthCheck(BOOL = TRUE);
	int (*ActionFn)(void*);	//pointer to function
 //Action Targets are pointers, not reference, because we might replace these
 //arguments later
    Core *Initiator, *Objective;
    ItemScores *ObjectiveItem;//we need scores of target inventory item
//	Core *ActualLocation;

    //Agent scores
    percentage BasicDifficulty, ActualDifficulty;
	percentage BasicWickedness, ActualWickedness, BasicAnarchy,
    	ActualAnarchy;
	percentage BasicAttitudeChange, ActualAttitudeChange;
    //"solid" scores
    percentage MinIntel, ReqCourage, MinAttitude, MaxAttitude;
    unsigned char TargetAssignmentCriteria, RefTAC, FailureGoto;
    ActionType _Type;
    BOOL IsPrimed;
};

struct _ActionNode	//not action definition!!! It is in the beginning
{			//used only in Strategy
	Action action;
    struct _ActionNode *next;
};

typedef struct _ActionNode * ActionNodeP;

class Strategy{
public:
	Strategy();
	Strategy(Goal argGoal, ID argID);
    ~Strategy();
    void Init(Goal);
    void Init(Goal ,ID );
    //do what you have to do and increment pointer
    ActionError ExecuteNextAction(void *, unsigned char = 0,
        percentage = 0);
    Action *GetNextAction();
    percentage GetNextActionOrder();
    Action *GetLastAction();
    percentage GetLastActionOrder();

    void UpdateNextActionTargets(Core *,
    	Core *, ItemScores *);//,Core*);
    BOOL AppendAction(Action*);
    Action DelAction();
    ActionNodeP FindAction(unsigned char);
    ActionNodeP GetActionList();
    void SetGoal(Goal);
	Goal GetGoal();
    void SetObjective(Core *argObj);
    Core *GetObjective();
    void SetObjItem(ItemScores *argItem);
    ItemScores *GetObjItem();
    percentage GetImportance();
    void CalcScores(percentage = 0);
    void FreeActionList();
    BOOL PossibilityCheck();
    void End();
    ID GetID();
    void SetNextActionAddress(ActionNodeP);
    void SetLastActionAddress(ActionNodeP);
    void SkipNextAction(BOOL = FALSE);
    BOOL IsListed(ID);
    unsigned short FillSaveBuffer(BYTE*);
    void RestoreFromBuffer(BYTE *, Core **, unsigned short,
        ItemPtrArr*, unsigned short *);
    void OverrideActionList(ActionNodeP);
    void ResetAllActionTargets();
    void ReturnToLastAction();
//    void SetID(ID IDarg) { StrategyID = IDarg; }
protected:
    Core *Objective;
    ItemScores	*Item;
    ID StrategyID;
	Goal StrategyGoal;
    ActionNodeP ActionList, NextAction, LastAction;
    //last one is for compatibility with certain criteria records
    unsigned short TotalDifficulty; // 'percentage' is not enough here
	percentage Wickedness, Anarchy, MaxIntel;
    percentage Importance; //calc'ed mostly by the Goal Importance
};



BOOL InitActionLib(int(*)(void*));

void FreeLibLists();

BOOL LieCheck(Action *, Core *, Core *,
	ItemScores * = NULL);

void CalcOpinion(Core *, Core *, ItemScores * = NULL);

class Agent{
public:
  Agent();

  Agent(percentage, percentage);
  ~Agent();
  void Init(percentage WickednessArg = 0, percentage AnarchyArg = 0);

  void SetImpression(percentage  , percentage ,
  	percentage , percentage , percentage ,BOOL = FALSE);
  void SetSolidScores(percentage argIntel, percentage argCourage);
  void GetImpression(percentage&  , percentage& ,
  	percentage& , percentage& , percentage& , BOOL = FALSE);
  void GetSolidScores(percentage& argIntel, percentage& argCourage);
  percentage InitialAttitudeModification(Core&,unsigned char = 0);
  const AlignmentType GetAlType();
  char* GetAlName();
  ID GetID();
  percentage ItemAcquisitionImportance(ItemScores &);
  BOOL Scan(Agent*, ItemPtrArr, unsigned short, ID = GOAL_NONE);
  BOOL ScanForCriterion(Agent *,ItemPtrArr , unsigned short ,
        GoalDefNodeP  );
  long FindCriterionMatch(Agent**,unsigned short,ItemPtrArr*,
		unsigned short *, ID = GOAL_NONE, percentage = -1);
  BOOL AssignTargetForNextAction(Agent** = NULL,unsigned short = 0,
        ItemPtrArr* = NULL,unsigned short * = 0);
  BOOL AssignTargetsForAction(Action *,
        Agent ** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL,
		unsigned short * = 0,
        Strategy * = NULL);
  ActionError ExecuteNextAction(void *, Agent** = NULL,unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0); //Core * = NULL,
//        unsigned char = 0);
  BOOL CalcResponse(Action&);
/*
  void SetLocation(Core *argLoc);
  Core GetLocation();
*/
  percentage AttitudeToItem(ItemScores& );
  BOOL PrimeAllActionTargets(Strategy *);

  Strategy CurrentStrategy;

  Core GetCore() const;
  Core *GetCoreAddress();
  void SetCore(Core &);
  Core GetOriginalCore() const;
  void SetOriginalCore(Core &);
  void ResetFromOriginal();
  void UpdateOriginalCore();
  BOOL CreateNewAttitude(Core &);
  percentage AttitudeTo(Core &);
  percentage AttitudeTo(ID);
  BOOL SetAttitudeTo(ID , percentage ,
        unsigned char = BOTH);
  BOOL IsNewStrategyMoreImportant(Strategy&);
  BOOL IsNewStrategyMoreImportant(percentage );
/*
  This check determines whether the current strategy should be Ended
  in order to adopt a new one. Normally, if the Importance score of the
  new proposed strategy is higher than Importance of the old one, the
  old strategy is Ended and replaced by the new one. But if more than
  ½ of the actions are already completed, the Importance score of the new
  strategy must be at least 30% higher for the Importance of the one to
  be ended.
  */
  void SetSeemed_TrueToggles(BOOL, BOOL, BOOL, BOOL);
  unsigned char FailuresCount, LoopFailuresCount;
  BOOL IsDead();
  void Die();
  BOOL AdoptStrategyFromOneAction(Action *,unsigned char );
  unsigned short VerifyCriteria(GoalDefNodeP, Core*,ItemPtrArr = NULL,
    unsigned short = 0);
  BOOL IsStrategyStillRelevant(Agent **,unsigned short ,
        ItemPtrArr* ,
		unsigned short *);

  static unsigned short AutoNumber;	//auto incrementing attitude ID

  BOOL PickStrategy(Goal , Core *,ItemScores * = NULL);
  void SetAttitudesRoot(Attitude *,BOOL = FALSE);
  void FillCritAttitudesArray(percentage*,Core *,GoalDefNodeP);

  unsigned short FillSaveBuffer(BYTE*);
  //Why two steps? Because we cannot assume that the unique attId's will
  //be the same if you generate these characters in the same order and
  //quantity.That's why first we must restore all their scores, including
  //IDs, and then recover all the pointers through these IDs
  void RestoreFromBufferStep1(BYTE *,unsigned short);
  void RestoreFromBufferStep2(BYTE *,unsigned short,
        Agent **, unsigned short,
        ItemPtrArr*, unsigned short *);
  percentage CalcNeutralSideMeanness(Agent **,
        unsigned short , Action *);
  unsigned char GetTrueStatsByte();
  BOOL WasStrategyFailure(Strategy *);
protected:
  Core core, Original; //*CurrentLocation;
  unsigned char UseTrueStats, UseTrueAttitude;
  BOOL Initialized;//for now, checks if the Original scores are initialized
  void      InitType();
  void UpdateSecondaryVars();
  Action *actAssignTargetsTo;
  BOOL bBypassCheckExecute; //bypass checking action executions, for example,
                            //for incomplete verbal contents actions
};

char *GetLastThought();
ActionDefNodeP      LinkFnToAction(ID, int (*)(void*));

//---------------- Verbal Actions related declarations ----------------------
char *GetVerbalOutput();
char *AbuseGenerator(Core&,Core&, unsigned char );
void FormatVerbal(char *,char *, int );
percentage AcceptDealProposal(Action *);//, Action *);
percentage AcceptRequest(Action *,Core *);
BOOL AcceptDiffWealth(Core *,Core *,short);
percentage MaxDiffWealth(Core *,Core *);
ActionError AcceptStatement(Action *, Core *);
ActionError AcceptThreat(Action *, ID ,Agent *);
short SelectItemForDealProposal(ItemPtrArr,short ,
        Core& , percentage ,
        percentage );

//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
int Random(int LoLimit, int HiLimit);
percentage PersonalEvaluate(Action&, Core& );
long PersonalAttitude2Action(Action& , Core &,
    BOOL = TRUE);
//-----------------------------------------------------------------------
//---------------- Mindset customization --------------------------------
#define CUSTOM_MINDSET_START    10

struct _MindDefNode {
    ID MindID;
    char Descr[26];
    percentage LWick,HWick,LAnar,HAnar;
    percentage InitialAttitude;
    //neutral, uninfluenced starting personal attitude
    percentage AttitudeChangeUnit;
    percentage SuddenChange;
    percentage AbsMeanness, Meanness, AbsWealth, Wealth,
        AbsBeauty, Beauty, AbsIntelligence, Intelligence;
    percentage Foreignness;
    percentage ItemMeanness, ItemBeauty, ItemWealth, ItemIntelligence;
    struct _MindDefNode *next;
};
typedef struct _MindDefNode* MindDefNodeP;
MindDefNodeP GetMindNode(ID);
char *GetMindDesc(ID);
int FillBufferWithMindPtrs(MindDefNodeP *,int = 0xFFFF);
MindDefNodeP GetMatchMindNode(percentage,percentage);
//-----------------------------------------------------------------------
int FillBufferWithActionPtrs(ActionDefNodeP *, int = 0xFFFF);
//-----------------------------------------------------------------------
unsigned short BSFillSaveBuffer(Core , BYTE *);//saving basic scores

Core *FindBSAddress(ID, Core **,unsigned short);
ItemScores *FindItemAddress(ID ,ID ,
            unsigned short ,ItemPtrArr* ,
            unsigned short* );
void BSRestoreFromBufferStep1(BYTE *, unsigned short,Core* );
void BSRestoreFromBufferStep2(Core*,Core **,unsigned short);
//-----------------------------------------------------------------------
void SetDynamicTACAssumptionPopulation(Agent**,unsigned short,ItemPtrArr*,
		unsigned short *);
void FreeDynamicTACAssumptionPopulation();
void SetSoloAssumptionMode(BOOL );
void SetSoloActionMode(BOOL );
void SetSuddenChangeUse(BOOL );
void SetMaxFailures(unsigned short );
void SetHistoryUse(BOOL );
//-----------------------------------------------------------------------
Action* CreateAction(ID );

//---------------------------------------------------------------------------
//                  GROUP class definition
//---------------------------------------------------------------------------
//--------------- Leadership type defines -----------------------------------
//---------------------------------------------------------------------------
#define PRESENT_LEADER_ONLY  0
#define REELECTABLE_LEADER   1
#define NO_LEADER            2
#define DISMANTLE_ON_STR_END 3
//---------------------------------------------------------------------------
//--------------- Execution type defines ------------------------------------
//---------------------------------------------------------------------------
#define COORDINATE  0
#define IMMEDIATE   1
#define NO_RETURN   2
//---------------------------------------------------------------------------
//--------------- Activity type defines -------------------------------------
//---------------------------------------------------------------------------
//FALSE, which is regular "false" and shouldn't be redefined
#define MEMBERS_SELECT      1
#define STRATEGY_EXECUTION  2
//---------------------------------------------------------------------------
class Group:public Agent{
public:
    Group();
    ~Group();
    ActionError ExecuteNextAction(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    ActionError ExecuteCommonEffort(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    ActionError ExecuteMemberSelection(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    ActionError ExecuteDifferentActions(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    int AddMember(Agent*,int = -1);
    void RemoveMember(unsigned short);
    void SetLeader(unsigned short);
    unsigned short GetLeaderIndex();
    void Dismantle();
    void DisposeStrategies();
    int  FindCriterionMatch(ID);    
    BOOL PickStrategy(Goal , Core *,ItemScores * = NULL);
    BOOL AssignInitiatorsInGroupStrategy(Strategy *);
    void SetActionsOrder(int*,int = 0);
    BOOL AssignGroupStrategy();
    unsigned char ActivityMode();
    void SetActivityMode(unsigned char);
    //attention: Agent is scanned here instead of Core
    BOOL Scan(Agent *,ItemPtrArr ,
		unsigned short , ID , void * );
    void CalcCore();
    unsigned char LeadershipType,ExecType;
    ID GetMemberCriterion();
    unsigned short GetMembersQty();
    Core *GetMemberCoreAddress(unsigned short);
    Agent *GetLeader();
    Agent *GetMember(unsigned short);
    void SetMemberCriterion(ID );
    void SetNewMemberChkFn(int (*)(void*));
    unsigned short MaxMembersQty;
    Core *GetLeaderCoreAddress();
    percentage CalcNeutralSideMeanness(Agent **,
        unsigned short , Action *);
    BOOL IsGroupMember(ID );
    BOOL AssignStrategy(ID ,unsigned short, BOOL = FALSE );
    /*serves as NEEDED members quantity in
    groups created for strategy completion*/
protected:
    unsigned short LeaderIndex,MembersQty;
    unsigned char Activity;
    /*Note: each strategy pointer must be coordinated with
        Members array members (that is, the same index)*/
    Agent **Members;
    Strategy **StrParts; /*These strategies are parts of the common
                        "squad strategy"*/
    ID MemberCriterion; //only for Groups not targetted at one goal
    int (*NewMemberChkFn)(void*);
        /*User-defined function
        used to handle a new member addition (queries, etc.)*/
};

//---------------------------------------------------------------------------
Group *CreateGroup(Agent *,ID,Core * = NULL,ItemScores * = NULL);
void SetDefaultMemberCheckFn(int (*)(void*));
//---------------------------------------------------------------------------
//-----------------------------------------------------------------------
//---------------------------------------------------------------------------
typedef unsigned char EventType;
#define ACTION_PROMISE      0
#define ACTION_FAILURE      1
#define STRATEGY_FAILURE    2

typedef struct{
    ID EventID;//which could be action or strategy ID
    ID ObjectiveID;
    ID ObjItemID;
    ID *Witnesses;
    unsigned short WitnessesQty;
    EventType _Type;
} EventEntry;
//---------------------------------------------------------------------------
void AddWitnessToEvent(EventEntry *,ID );
void RemoveWitnessFromEvent(EventEntry *,ID );
BOOL IsEventWitness(EventEntry *,ID );

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class PersonalLog{
public:
    PersonalLog();
    ~PersonalLog();
    void SetInitiatorID(ID);
    ID GetInitiatorID();
    unsigned short MaxLogLen;
    //the parameters are: action/strategy ID, Objective, Objective Item
    int GetEventIndex(ID,ID,ID,EventType);
    //these 3 are shortcuts for the previous one
    int GetPromiseIndex(ID,ID,ID);
    int GetFailedActionIndex(ID,ID,ID);
    int GetFailedStrategyIndex(ID,ID,ID);
    BOOL WasEventWitness(ID,ID,ID,EventType,ID);
    EventEntry *GetEvent(unsigned short);
    BOOL SetEvent(ID,ID,ID,EventType,unsigned short);
    //if exceeds maximum, overwrite first event
    EventEntry *AddEvent(ID,ID,ID,EventType);
    void RemoveEvent(unsigned short);
    void DisconnectPointer();
protected:
    BOOL ReallocLog(int = 0); //given 0 as parameter, used to free memory
    ID InitiatorID;
    unsigned short NextOverwritten,LogLen;
    EventEntry *Log;
};

//---------------------------------------------------------------------------
class EventsRegistry{
public:
    EventsRegistry();
    ~EventsRegistry();
    void Register(ID,ID,ID,ID,EventType);
    BOOL IsEventRegistered(ID,ID,ID,ID,EventType);
    EventEntry *GetEventEntry(ID,ID,ID,ID,EventType);
    void Unregister(ID,ID,ID,ID,EventType);
    PersonalLog *GetInitiatorLog(ID);
    PersonalLog *AddInitiatorLog(ID);
    BOOL RemoveInitiatorLog(ID);
    void Clear();
protected:
    BOOL ReallocRegistry(int = 0); //given 0 as parameter, used to free memory
    PersonalLog *Logs;
    unsigned short LogsQty;
};

//---------------------------------------------------------------------------
void ClearHistory();
EventsRegistry *GetHistoryAddress();
//---------------------------------------------------------------------------
#endif
#endif

