unit cAICulture;
{
  Node AICulture

  This is a container of AISpirits, as well as an interface that can interact
  with them as a whole.

  Patterns:
    Spirits
}
interface

uses Classes, cAISpirit, cAIBaseObject, cAIBrainStructures,
  cAIGrid;

type

// ============================================================================
// a culture contains spirits
AICulture = Class(AIBaseContainer)
private
  fName: string;
  fGroupActions: AIActionList;
public
  Constructor Create(aEnvironment: pointer);
  Destructor Destroy; override;

  function NewSpirit(aLocation: AIGrid; aGender: integer): AISpirit;

  function AnyoneAlive: boolean;

  procedure BigJostle;
  procedure CollectGroupActions;
  procedure ClearGroupActions;

  property Name: string read fName write fName;
  property GroupActions: AIActionList read fGroupActions;

  procedure Clean;
//  procedure SaveToFile(var aFile: TextFile);
//  procedure LoadFromFile(var aFile: TextFile);
end;

// ----------------------------------------------------------------------------

implementation

uses
  cAIReality, cAIEnvironment, cGlobals;

// ----------------------------------------------------------------------------
Constructor AICulture.Create(aEnvironment: pointer);
begin
  inherited Create(aEnvironment);

  fGroupActions := AIActionList.Create(self);

  fName := 'Culture';
  gCulture := self;
end;

// ----------------------------------------------------------------------------
Destructor AICulture.Destroy;
begin
  fGroupActions.Free;

  inherited Destroy;
end;

// ----------------------------------------------------------------------------
procedure AICulture.Clean;
begin
  GroupActions.Clear;
end;

// ----------------------------------------------------------------------------
procedure AICulture.BigJostle;
var
  mySpirit: AISpirit;
  i: integer;
begin
  for i := 0 to Count - 1 do
  begin
    mySpirit := AISpirit(Items[i]);
    if mySpirit.IsAlive then
      mySpirit.Fuel;
  end;
end;

// ----------------------------------------------------------------------------
procedure AICulture.CollectGroupActions;
var
  mySpirit: AISpirit;
  myAction: AIAction;
  i: integer;
begin
  // get all the next actions from each individual
  GroupActions.Clear;

  for i := 0 to Count - 1 do
  begin
    mySpirit := AISpirit(Items[i]);
    if mySpirit.IsAlive then
      if mySpirit.HasNextAction then
      begin
        myAction := mySpirit.NextAction;
        GroupActions.AddAction(myAction);
      end;
  end;
end;

// ----------------------------------------------------------------------------
procedure AICulture.ClearGroupActions;
var
  mySpirit: AISpirit;
  i: integer;
begin
  GroupActions.Clear;

  for i := 0 to Count - 1 do
  begin
    mySpirit := AISpirit(Items[i]);
    mySpirit.Brain.Actions.Clear;
  end;
end;

// ----------------------------------------------------------------------------
function AICulture.NewSpirit(aLocation: AIGrid; aGender: integer): AISpirit;
var
  mySpirit: AISpirit;
  myEnvironment: AIEnvironment;
begin
  mySpirit := AISpirit.Create(self, aGender, aLocation);

  Add(mySpirit);

  myEnvironment := AIEnvironment(ParentPointer);
  myEnvironment.Things.Cradle.Add(mySpirit);
  myEnvironment.Things.Existents.Add(mySpirit);

  result := mySpirit;
end;

// ----------------------------------------------------------------------------
function AICulture.AnyoneAlive: boolean;
var
  mySpirit: AISpirit;
  i: integer;
begin
  result := false;
  for i := 0 to Count - 1 do
  begin
    mySpirit := AISpirit(Items[i]);
    if mySpirit.IsAlive then
      result := true;
  end;
end;

end.
