/*
   Project: UL

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

   Author: Michael Johnston

   Created: 2005-05-23 18:32:14 +0200 by 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 _ULSYSTEMBUILDER_H_
#define _ULSYSTEMBUILDER_H_

#include <Foundation/Foundation.h>
#include <ULIOManager.h>
#include <ULConfigurationBuilder.h>
#include <ULTopologyFrameBuilder.h>
#include <ULInteractionsBuilder.h>
#include <ULMerger.h>
#include <ULSystem.h>
#include <ULSimpleMergerDelegate.h>

/**
Class that creates systems for simulation based on the Builder pattern.
It is composed of four seperate parts which are instances of 
ULConfigurationBuilder, ULTopologyFrameBuilder, ULMerger & ULInteractionsBuilder (or one of their subclasses) 
respectively. 
ULSystemBuilder is like an assembly line with each object performing a
different task in the production of a complete system.

\ingroup model

*/

@interface ULSystemBuilder : NSObject
{
	ULIOManager* ioManager;
	id configurationBuilder;	//!< ULConfigurationBuilder subclass
	id topologyFrameBuilder;	//!< ULTopologyFrameBuilder subclass
	id interactionsBuilder;		//!< ULInteractionsBuilder subclass
	id merger;			//!< ULMerger subclass
	id System;			//!< The last fully created system
	id configuration;		//!< The last built configuration
	id topologyFrame;		//!< The last built topology frame
	NSString* buildPosition;	//!< Where the builder is on the pathway
}

/**
Returns a new ULSystemBuilder initialises to process molecules of type /e fileType using the force field
/e forceFieldName
\param fileType The type of file ULSystemBuilder is to process
\param forceFieldName The force field to be used
\return A new ULSystemBuilder instance
*/
- (id) initWithFileType: (NSString*) configurationPluginName forceField: (NSString*) forceFieldName;

/**
Builds the \e partName section of the system. \e partName can be "Configuration", "Topology", "Merger" or
"Interactions" each of which is a step on the build pathway.
They must be called in this order e.g. calling this method with \e partName = "Topology" before
having called with partName = "Configuration" is an error. The pathway has single occupancy and is unidirectional.  
\param partName The section of the system to be built. ("Configuration", "Topology", "Merger", "Interactions")
\param optionsDict Options controlling each build. See the individual builder documentation for more info
\param error A pointer to an NSError object. Any errors in the build step will be put here
\param info A pointer to a string object. Information on the build step will be put here
\note The functionality may be expanded to enable multiple systems at different parts of the pathway.
*/
- (void) buildPart: (NSString*) partName 
		options: (NSDictionary*) optionsDict 
		error: (NSError**) buildError
		userInfo: (NSString**) buildInfo;

/** 
Sets the molecule that ULSystemBuilder will convert into a system
\param path The path to the molecule
Will raise an exception if the molecule is not of the same file type the object has been set to process
*/

- (void) setBuildMolecule: (NSString*) path;

/**
Returns the options dictionary for the molecule the object is currently working on
*/

- (NSMutableDictionary*) buildOptions;

/**
Cancels the current build, releasing the system currently on the build pathway.
*/
- (void) cancelBuild;

/**
Returns the last completed system if any. If there is none returns nil
*/
- (ULSystem*) system;

/**
Returns the current build position of the object. i.e. which section
it will build next
\return The current build position (Configuration, TopologyFrame, Merge, Interactions)
*/

- (NSString*) buildPosition;

/**
Removes the current molecule from the builder.
The current build must have been cancelled in order
to remove the molecule. If the build hasnt been cancelled
this method return NO. On success it returns YES
*/
- (BOOL) removeMolecule;

@end

#endif // _ULSYSTEMBUILDER_H_

