#ifndef ACTIONSUNIT_H
#define ACTIONSUNIT_H
/*******************************************************************
/*  ActionsUnit.h
/*  Author: Vadim Berman
/*
/*  Description: ActionsUnit.h contains the declarations for
/*  two basic Brainiac classes,
/*  Action and Strategy, as well as some non-member functions related
/*  to these classes
/*
/*  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 "CommonUnit.h"
#include "DiskRecUnit.h"
#include "RegUnit.h"

//-----------------------------------------------------------------------
class EXPO 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();
    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

    //Alignment 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 EXPO 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
};

//-------------------------------------------------------------------------
//---------------------- Miscellaneous functions --------------------------
//-------------------------------------------------------------------------
EXPO Action* BBECALL CreateAction(ID);
BOOL BBECALL ChangeAction(Action*, ID);
EXPO Strategy* BBECALL CreateStrategy(StrategyDefNodeP = NULL, ID = 0);

//------------------------------------------------------------------------
//--- exported functions not related to any class or list node structure -
//------------------------------------------------------------------------
EXPO BOOL BBECALL InitActionLib(int(BBECALL*)(void*));

EXPO void BBECALL FreeLibLists();

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

EXPO void BBECALL CalcOpinion(Core *, Core *, ItemScores * = NULL,
     unsigned char = TRUE);
EXPO percentage BBECALL PersonalEvaluate(Action&, Core& );
EXPO long BBECALL PersonalAttitude2Action(Action& , Core &,
    BOOL = TRUE);
#endif

