//---------------------------------------------------------------------------
#ifndef BrainiacH
#define BrainiacH

/*******************************************************************
/*  Brainiac.h
/*  Author: Vadim Berman
/*
/*  The contents of this file are subject to the Brainiac Public License.
/*  Version 1.0 (the "License"); you may not use this file except in
/*  compliance with the License. You may obtain a copy of the License at
/*  http://www.twilightminds.com
/*
/*  Software distributed under the License is distributed on an "AS IS"
/*  basis WITHOUT WARRANTY OF ANY KIND, either express or implied. See
/*  the License for the specific language governing rights and limitations
/*  under the License.
/*
/*  Copyright (C) 1999 Twilight Minds. All rights reserved.
/********************************************************************/

#include <windows.h>
#include <winuser.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define BBECALL __stdcall

#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 *BBECALL LastBEError();
void BBECALL APIError();


typedef signed char percentage;
typedef unsigned short ID;

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;

//--------------------- Record lengths / other record defines -----------
#define ITEM_CRITERIA_RECORDS_START 200
#define GOAL_REC_SIZE   160
#define ACT_REC_SIZE    120
#define MND_REC_SIZE    97

#define FUNCTION_LEN  61
#define VERB_LEN      21
#define GOAL_DESC_LEN 26
#define MIND_DESC_LEN 26
#define STR_NAME_LEN  16
#define STR_DESC_LEN  51
#define ACT_DESC_LEN  21

#define MAX_MODULE_NAME 101
#define PARAM_MODULE    1
#define MODULE_BE       0

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

struct _GoalDefNode {
	Goal goal;
    char Descr[GOAL_DESC_LEN];
	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[ACT_DESC_LEN];
    int (BBECALL *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[STR_NAME_LEN],Descr[STR_DESC_LEN];
    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 BBECALL Stop(char *);
GoalDefNodeP BBECALL GetGoalNode(ID);
ActionDefNodeP BBECALL GetActionNode(ID);
StrategyDefNodeP BBECALL GetStrategyNode(ID);
percentage BBECALL GetAttitude(ID , Attitude *, BOOL = TRUE);
BOOL BBECALL AddAttitude(ID , percentage , Attitude **);
BOOL BBECALL ModifyAttitude(ID , short , Attitude *, unsigned char = 2);
BOOL BBECALL UpdateAttitude(ID , percentage ,//set or add
	Attitude **, unsigned char = 2);
void BBECALL DelAttitudeTree(Attitude **);
Attitude *BBECALL CopyAttitudeTree(Attitude*);
void BBECALL Attitudes2String(Attitude *, char *);

//-----------------------------------------------------------------------
//-------------- Action and Strategy  class -----------------------------
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
class Action{
public:
	BBECALL Action();
    BBECALL Action(Action*);
    BBECALL Action(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
		percentage BasicAnarArg, percentage MinIntArg, percentage ReqCouArg,
        percentage BasicAttitudeChangeArg, ID ActionIDArg, percentage MinAttArg,
        percentage MaxAttArg, int (BBECALL *ActionFnArg)(void*));
    BBECALL ~Action();
    void BBECALL Init(ActionType , percentage , percentage ,
		percentage , percentage , percentage ,
        percentage , ID , percentage ,
        percentage , int (BBECALL *)(void*));
	void BBECALL Init(Action *);
    void BBECALL SetActionFn(int (BBECALL *)(void*));
    void BBECALL InitTargets(Core * = NULL, Core * = NULL,
    	ItemScores * = NULL);//, Core* = NULL);
    void BBECALL ResetTargets();
    Core *BBECALL GetInitiator();
    Core *BBECALL GetObjective();
    ItemScores *BBECALL GetObjItem();
    Action *BBECALL GetReported1Ptr();
    Action *BBECALL GetReported2Ptr();
    void BBECALL SetReported1(Action *);
    void BBECALL SetReported2(Action *);
    void BBECALL InitScores(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
    	percentage BasicAnarArg, percentage MinIntArg,
        percentage ReqCouArg, percentage BasicAttitudeChangeArg,
        percentage MinAttArg, percentage MaxAttArg);
	void BBECALL ResetScores();
    void BBECALL GetActualScores(percentage& ActualDiffArg, percentage& ActualWickArg,
    	percentage& ActualAnarArg, percentage& ActualAttChg);
    void BBECALL GetBasicScores(percentage& BasicDiffArg, percentage& BasicWickArg,
    	percentage& BasicAnarArg, percentage& BasicAttChg);
    void BBECALL GetSolidScores(percentage& , percentage&);
    void BBECALL GetAttitudeLimits(percentage& , percentage&);
    ActionType BBECALL GetType();
    ActionError BBECALL Execute(void*, BOOL = FALSE, unsigned char = 0, percentage = 0);
    BOOL BBECALL IsReady();
    ID BBECALL GetID();
//  BOOL byLieCheckActive;
    void BBECALL SetTargetAssignmentCriteria(unsigned char);
    void BBECALL SetRefTAC(unsigned char);
    void BBECALL SetFailureGoto(unsigned char);
    unsigned char BBECALL GetTargetAssignmentCriteria();
    unsigned char BBECALL GetRefTAC();
    unsigned char BBECALL GetFailureGoto();
    percentage BBECALL GetDealValue();
    unsigned short BBECALL FillSaveBuffer(BYTE*);
    void BBECALL RestoreFromBuffer(BYTE *, Core **, unsigned short,
        ItemPtrArr*, unsigned short *);
    Action *Reported1,*Reported2;
    BOOL SkipChecks;
protected:
    ID ActionID;
    void BBECALL CalcActualScores(BOOL = TRUE, percentage = 0, percentage = 0);
    void BBECALL UpdateObjective();
    BOOL BBECALL MeannessCheck(BOOL = TRUE, BOOL = FALSE, percentage = 0);
    ActionType BBECALL ForeignnessCheck();
    BOOL BBECALL WealthCheck(BOOL = TRUE);
	int (BBECALL *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

    //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:
	BBECALL Strategy();
	BBECALL Strategy(Goal argGoal, ID argID);
    BBECALL ~Strategy();
    void BBECALL Init(Goal);
    void BBECALL Init(Goal ,ID );
    //do what you have to do and increment pointer
    ActionError BBECALL ExecuteNextAction(void *, unsigned char = 0,
        percentage = 0);
    Action *BBECALL GetNextAction();
    percentage BBECALL GetNextActionOrder();
    Action *BBECALL GetLastAction();
    percentage BBECALL GetLastActionOrder();

    void BBECALL UpdateNextActionTargets(Core *,
    	Core *, ItemScores *);//,Core*);
    BOOL BBECALL AppendAction(Action*);
    Action BBECALL DelAction();
    ActionNodeP BBECALL FindAction(unsigned char);
    ActionNodeP BBECALL GetActionList();
    void BBECALL SetGoal(Goal);
	Goal BBECALL GetGoal();
    void BBECALL SetObjective(Core *argObj);
    Core *BBECALL GetObjective();
    void BBECALL SetObjItem(ItemScores *argItem);
    ItemScores *BBECALL GetObjItem();
    percentage BBECALL GetImportance();
    void BBECALL CalcScores(percentage = 0);
    void BBECALL FreeActionList();
    BOOL BBECALL PossibilityCheck();
    void BBECALL End();
    ID BBECALL GetID();
    void BBECALL SetNextActionAddress(ActionNodeP);
    void BBECALL SetLastActionAddress(ActionNodeP);
    void BBECALL SkipNextAction(BOOL = FALSE);
    BOOL BBECALL IsListed(ID);
    unsigned short BBECALL FillSaveBuffer(BYTE*);
    void BBECALL RestoreFromBuffer(BYTE *, Core **, unsigned short,
        ItemPtrArr*, unsigned short *);
    void BBECALL OverrideActionList(ActionNodeP);
    void BBECALL ResetAllActionTargets();
    void BBECALL ReturnToLastAction();
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 BBECALL InitActionLib(int(BBECALL *)(void*));

void BBECALL FreeLibLists();

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

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

class Agent{
public:
  BBECALL Agent();

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

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

  Strategy CurrentStrategy;

  Core BBECALL GetCore() const;
  Core *BBECALL GetCoreAddress();
  void BBECALL SetCore(Core &);
  Core BBECALL GetOriginalCore() const;
  void BBECALL SetOriginalCore(Core &);
  void BBECALL ResetFromOriginal();
  void BBECALL UpdateOriginalCore();
  BOOL BBECALL CreateNewAttitude(Core &);
  percentage BBECALL AttitudeTo(Core &);
  percentage BBECALL AttitudeTo(ID);
  BOOL BBECALL SetAttitudeTo(ID , percentage ,
        unsigned char = BOTH);
  BOOL BBECALL IsNewStrategyMoreImportant(Strategy&);
  BOOL BBECALL IsNewStrategyMoreImportant(percentage );
  void BBECALL SetSeemed_TrueToggles(BOOL, BOOL, BOOL, BOOL);
  unsigned char FailuresCount, LoopFailuresCount;
  BOOL BBECALL IsDead();
  void BBECALL Die();
  BOOL BBECALL AdoptStrategyFromOneAction(Action *,unsigned char );
  unsigned short BBECALL VerifyCriteria(GoalDefNodeP, Core*,ItemPtrArr = NULL,
    unsigned short = 0);
  BOOL BBECALL IsStrategyStillRelevant(Agent **,unsigned short ,
        ItemPtrArr* ,
		unsigned short *);

  static unsigned short AutoNumber;	//auto incrementing attitude ID

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

  unsigned short BBECALL 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 BBECALL RestoreFromBufferStep1(BYTE *,unsigned short);
  void BBECALL RestoreFromBufferStep2(BYTE *,unsigned short,
        Agent **, unsigned short,
        ItemPtrArr*, unsigned short *);
  percentage BBECALL CalcNeutralSideMeanness(Agent **,
        unsigned short , Action *);
  unsigned char BBECALL GetTrueStatsByte();
  BOOL BBECALL WasStrategyFailure(Strategy *);
protected:
  Core core, Original;
  unsigned char UseTrueStats, UseTrueAttitude;
  BOOL Initialized;//for now, checks if the Original scores are initialized
  void BBECALL InitType();
  void BBECALL UpdateSecondaryVars();
  Action *actAssignTargetsTo;
  BOOL bBypassCheckExecute; //bypass checking action executions, for example,
                            //for incomplete verbal contents actions
};

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

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

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

struct _MindDefNode {
    ID MindID;
    char Descr[MIND_DESC_LEN];
    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 BBECALL GetMindNode(ID);
char *BBECALL GetMindDesc(ID);
int BBECALL FillBufferWithMindPtrs(MindDefNodeP *,int = 0xFFFF);
MindDefNodeP BBECALL GetMatchMindNode(percentage,percentage);
//-----------------------------------------------------------------------
int BBECALL FillBufferWithActionPtrs(ActionDefNodeP *, int = 0xFFFF);
//-----------------------------------------------------------------------
unsigned short BBECALL BSFillSaveBuffer(Core , BYTE *);//saving basic scores

Core *BBECALL FindBSAddress(ID, Core **,unsigned short);
ItemScores *BBECALL FindItemAddress(ID ,ID ,
            unsigned short ,ItemPtrArr* ,
            unsigned short* );
void BBECALL BSRestoreFromBufferStep1(BYTE *, unsigned short,Core* );
void BBECALL BSRestoreFromBufferStep2(Core*,Core **,unsigned short);
//-----------------------------------------------------------------------
void BBECALL SetDynamicTACAssumptionPopulation(Agent**,unsigned short,ItemPtrArr*,
		unsigned short *);
void BBECALL FreeDynamicTACAssumptionPopulation();
void BBECALL SetSoloAssumptionMode(BOOL );
void BBECALL SetSoloActionMode(BOOL );
void BBECALL SetSuddenChangeUse(BOOL );
void BBECALL SetMaxFailures(unsigned short );
void BBECALL SetHistoryUse(BOOL );
//-----------------------------------------------------------------------
Action* BBECALL 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:
    BBECALL Group();
    BBECALL ~Group();
    ActionError BBECALL ExecuteNextAction(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    ActionError BBECALL ExecuteCommonEffort(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    ActionError BBECALL ExecuteMemberSelection(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    ActionError BBECALL ExecuteDifferentActions(void *, Agent** = NULL,
        unsigned short = 0,
        ItemPtrArr* = NULL, unsigned short * = 0);
    int BBECALL AddMember(Agent*,int = -1);
    void BBECALL RemoveMember(unsigned short);
    void BBECALL SetLeader(unsigned short);
    unsigned short BBECALL GetLeaderIndex();
    void BBECALL Dismantle();
    void BBECALL DisposeStrategies();
    int  BBECALL FindCriterionMatch(ID);
    BOOL BBECALL PickStrategy(Goal , Core *,ItemScores * = NULL);
    BOOL BBECALL AssignInitiatorsInGroupStrategy(Strategy *);
    void BBECALL SetActionsOrder(int*,int = 0);
    BOOL BBECALL AssignGroupStrategy();
    unsigned char BBECALL ActivityMode();
    void BBECALL SetActivityMode(unsigned char);
    //attention: Agent is scanned here instead of Core
    BOOL BBECALL Scan(Agent *,ItemPtrArr ,
		unsigned short , ID , void * );
    void BBECALL CalcCore();
    unsigned char LeadershipType,ExecType;
    ID BBECALL GetMemberCriterion();
    unsigned short BBECALL GetMembersQty();
    Core *BBECALL GetMemberCoreAddress(unsigned short);
    Agent *BBECALL GetLeader();
    Agent *BBECALL GetMember(unsigned short);
    void BBECALL SetMemberCriterion(ID );
    void BBECALL SetNewMemberChkFn(int (BBECALL *)(void*));
    unsigned short MaxMembersQty;
    Core *BBECALL GetLeaderCoreAddress();
    percentage BBECALL CalcNeutralSideMeanness(Agent **,
        unsigned short , Action *);
    BOOL BBECALL IsGroupMember(ID );
    BOOL BBECALL 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 (BBECALL *NewMemberChkFn)(void*);
        /*User-defined function
        used to handle a new member addition (queries, etc.)*/
};

//---------------------------------------------------------------------------
Group *BBECALL CreateGroup(Agent *,ID,Core * = NULL,ItemScores * = NULL);
void BBECALL SetDefaultMemberCheckFn(int (BBECALL *)(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 BBECALL AddWitnessToEvent(EventEntry *,ID );
void BBECALL RemoveWitnessFromEvent(EventEntry *,ID );
BOOL BBECALL IsEventWitness(EventEntry *,ID );

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

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

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

