/*******************************************************************
/*  AlignmentUnit.h
/*  Author: Vadim Berman
/*
/*  Description:
/*  declaration of Agent class and some Agent-related non-member
/*  functions
/*
/*  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.
/********************************************************************/

#ifndef AgentUNIT_H
#define AgentUNIT_H

#include "CommonUnit.h"
#include "ActionsUnit.h"

typedef enum { wGood = -1, wNeutral = 0, wEvil = 1 }
	WickednessType;

typedef enum { aLawful = -1, aNeutral = 0, aChaotic = 1 }
	AnarchyType;

typedef enum { atHostile, atUpset, atCautious, atIndifferent,
	atFriendly, atVeryClose } AttitudeType;


class EXPO 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); //Core * = NULL,
  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 );
/*
  This check determines whether the current strategy should be aborted
  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 aborted 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 aborted.
  */
  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
};


EXPO char *BBECALL GetLastThought();
void EXPO BBECALL SetDynamicTACAssumptionPopulation(Agent**,unsigned short,ItemPtrArr*,
		unsigned short *);
void EXPO BBECALL FreeDynamicTACAssumptionPopulation();
void EXPO BBECALL SetSoloAssumptionMode(BOOL );
void EXPO BBECALL SetSoloActionMode(BOOL );
void EXPO BBECALL SetSuddenChangeUse(BOOL );
void EXPO BBECALL SetMaxFailures(unsigned short );
void EXPO BBECALL SetHistoryUse(BOOL );
void EXPO BBECALL ClearHistory();
EXPO EventsRegistry *BBECALL GetHistoryAddress();
EXPO void BBECALL SetGoalItemAcquisitionID(ID);
void BBECALL Agent2CorePtrArray(Agent **,Core ***,unsigned short);
#endif

