#import "grid.h"
#import <activity.h>

#define __USE_FIXED_PROTOTYPES__   // for gcc headers
#include <stdio.h>

static void terminateFunction( void )
{
  [getTopLevelActivity() terminate];
}

static void stopFunction( void )
{
  printf( "stopping activity at time: %u\n", getCurrentTime() );
  [getTopLevelActivity() stop];
}

int main(void)
{
  id   aZone, aTurtle;
  id   simSched1, simSched2, displaySchedule, terminateSchedule;
  id   simSwarm, obsSwarm;

  // initialize

  initModule( grid );
  initModule( activity );
  aZone = [Zone create: globalZone];

  // create a turtle to turn and move during simulation

  aTurtle = [GridTurtle create: aZone];

  // create a pair of simulation schedules (repeat intervals of 2 and 4)

  simSched1 = [Schedule createBegin: aZone];
  [simSched1 setRepeatInterval: 2];
  simSched1 = [simSched1 createEnd];
  [simSched1 at: 0 createActionTo: aTurtle message: M(move:) : (id)10];

  simSched2 = [Schedule createBegin: aZone];
  [simSched2 setRepeatInterval: 4];
  simSched2 = [simSched2 createEnd];
  [simSched2 at: 0 createActionTo: aTurtle message: M(turn:) : (id)1];

  simSwarm = [GenericSwarm create: aZone];

  // create a display schedule to print turtle at every time step

  displaySchedule = [Schedule createBegin: aZone];
  [displaySchedule setRepeatInterval: 1];
  displaySchedule = [displaySchedule createEnd];
  [displaySchedule at: 0 createActionTo: aTurtle message: M(print)];

  // create a schedule to terminate all activity at timestep 32

  terminateSchedule = [Schedule create: aZone];
  [terminateSchedule   at: 10 createActionCall: stopFunction];
  [terminateSchedule at: 32 createActionCall: terminateFunction];

  // create a swarm object to hold both a default swarm plan and its activity

  obsSwarm = [GenericSwarm create: aZone];
  [obsSwarm activateIn: nil];
  [displaySchedule activateIn: obsSwarm];
  [terminateSchedule activateIn: obsSwarm];

  // load the swarm plan with its startup actions

  [simSwarm activateIn: [obsSwarm getSwarmActivity]];
  [simSched1 activateIn: simSwarm];
  [simSched2 activateIn: simSwarm];

  // run the swarm to completion

  while ( [[obsSwarm getSwarmActivity] run] != Completed );

  return 0;
}
