/*
   Project: Adun

   Copyright (C) 2006 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/

#ifndef _ADUN_CONTROLLER_
#define _ADUN_CONTROLLER_

#include <AdunKernel/AdunKernel.h>
#include "AdunKernel/AdCoreAdditions.h"
#include "AdunKernel/AdController.h"

/**
\ingroup coreClasses
AdController is a simple implementation of a controller and hence
the AdController & AdThreadedController protocols. It is intended to be a base class for 
other controllers providing necessary threading functionality and proper integration
into the core exit procedures.
As a controller it simply calls AdConfigurationGenerator::production:()
to start the configuration generation process.

\section subclass Subclassing

AdController provides threading, exit handling & error handling code to its subclasses.
Subclasses should only override AdController::coreWillStartSimulation:(), 
AdController::cleanUp() & runSimulation(). 
In the first case they should call the superclass implementation to set up the \e core 
and \e configurationGenerator instance variables. 

Do \e not override runController(). This method contains error handling code that wraps
runSimulation() so subclasses do not have to implement it. Instead subclasses should 
override runSimulation() replacing AdControllers implementation with their main loop.

\note 
In some cases it may be necessary to provide a custom thread creation/termination
solution. In this case it is recommended that you implement a complete
new class based on the controller protocols.
*/
@interface AdController: NSObject <AdController>
{
	BOOL notifyCore;
	int maxAttempts;	//!< The number of times to try to restart a failed production run
	NSConnection* threadConnection; //!< For communicating between the threads
	NSError* controllerError;	//!< For reporting errors in the simulation
	AdConfigurationGenerator* configurationGenerator;	//!< The configuration generator
	id core;		//!< The programs AdCore instance.
}
/**
A wrapper around the configuration generators AdConfigurationGenerator::production: method
adding handling of expoloding simulations. If the configuration generator exits with an
error whose code is AdKernelSimulationSpaceError then a restart attempt is made. 
This involves rolling back the simulation to an earlier state, minimising and restarting.
If this attempt fails then the method exits as normal.
*/
- (BOOL) production: (NSError**) error;
/**
Subclasses should override this method, not runController(), replacing it with their main loop. 
*/
- (void) runSimulation;
@end


@interface AdController (AdControllerThreadingExtensions) <AdThreadedController>
@end
#endif
