/*
   Project: Adun

   Copyright (C) 2005 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.
*/
/** \file **/

#ifndef _ADUNENVIRONMENT_
#define _ADUNENVIRONMENT_

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <locale.h>
#include "AdunKernel/AdKeyValueObserving.h"
#include "AdunKernel/AdunObject.h"
#include "AdunKernel/AdunMemoryManager.h"
#include "AdunKernel/AdunIOManager.h"


/**
\defgroup Frame Framework
\ingroup Kernel
**/

/**
\defgroup Inter Interfaces
\ingroup Frame
**/

/**
\defgroup Protocols Protocols
\ingroup Frame
*/

/**
\defgroup Structs Structures
\ingroup Base
**/

/**
\defgroup Base Base
\ingroup Kernel
**/

/**
\defgroup Cinter Components
\ingroup Kernel
**/

/*!
Provides environment information to all Framework objects
\todo Move to implementation based on domains. Domains
would be parts of the simulator that can change and would require
different options based on which part was active. Then these
parts can call valueForOption:inDomain: or something.
That way you wouldnt have to keep adding methods here for every
new option. Can also have standard domains e.g. General, Electrostatic etc. 
\todo Need to validate options
\bug If theres is no value in a selection array an exception is raised
\ingroup Inter
*/

@interface AdEnvironment: AdObject 
{
	@private
	NSMutableDictionary* optionsDict;
	NSMutableDictionary* keyObserverDict;
	id memoryManager;
	id ioManager;
	id defaults;
}
/**
Returns the global environment for the running process
*/
+ (id) globalEnvironment;
/**
Retrieves the envrionment options from the processes AdIOManager instance
and loads them.
*/
- (void) loadOptions;
/**
Uses the options in dict as the environment options. \dict must have the correct format.
*/
- (void) setOptions: (NSDictionary*) dict;
/**
Returns the environment options in the form of a dictionary
*/
- (NSDictionary*) options;
- (void)printBanner: (NSString*) banner;
- (void)printSeperator; 
/**
Adds the \e anObserver to the list of objects observing the environment variable \e key.
Whenever the value of key changes \e anObserver will revcieve an updateForKey:value:object message.
Raises an NSInvalidArgumentException if anObserver does not conform to the AdEnvironmentObservation
protocol. Raises an NSUndefinedKeyException if key is not an Environment key.
*/
- (void) addObserver: (id) anObserver forKey: (NSString*) key; 
/**
Removes object \e anObserver from the list of object observing \e key. \e anObserver
will recieve no further updates if the value of \e key changes. 
If anObserver was never registered to observe the particular key in question there is no effect.
Raises an NSUndefinedKeyException if key is not an Environment key.
*/
- (void) removeObserver: (id) anObserver forKey: (NSString*) key; 
/*Returns the value to be used as seed for random number generation*/
- (int) Seed;
/*Returns the output prefix for the output directory of the simulation*/
- (NSString*) OutputPrefix;
/*Returns the interval at which energies are collected.
The interval value is in simulation steps not time*/
- (int) EnergyWriteInterval;
/*Returns the interval at which configurations are collected*/
- (int) ConfigWriteInterval;
/*Returns the interval at which a log of the current state is output*/
- (int) LogInterval;
/*Returns the interval at which the currently collected energies should be output*/
- (int) EnergyDumpInterval;
/*Returns the time step (in femtoseconds) for the simulation*/ 
- (double) TimeStep;
/*Returns the number of configurations to be generated i.e. the number of steps*/
- (int) NumberConfigurations;
/*Returns the target temperaturein Kelvin*/
- (int) TargetTemperature;
/*Returns the type of simulation to be run. This can be Newtonian or Langevin*/
- (NSString*) SimulationType;
/*Returns YES if the simulation includes explicit solvent. NO otherwise.*/
- (BOOL) ExplicitSolvent;
/*Returns the coupling factor for the Berendsen Thermostat*/
- (double) CouplingFactor;
/*Returns the radius for the solvation sphere in angstroms*/
- (double) SolvationSphereRadius;
/* Return the required solvent density in ?*/
- (double) SolventDensity;
/*Returns the size of the boundary layer for SCAAS in angstroms*/
- (double) BoundarySize;
/*Returns the permittivity constant to be used in continuum calculations*/
- (double) Permittivity;
/*Returns the nonbonded cutoff radius in angstroms*/
- (float) CutOff;
/*Returns the interval at which the nonbonded lists should be recalculated*/
- (int) UpdateInterval;
/*Returns the method to use for calculating the electrostatic interactions inside
the cutoff (Pure, Shifted, GRF)*/
- (NSString*) ShortRangeInteractions;
/*Returns the mehods to be used for managing the nonbonded lists (Cell, Simple)*/
- (NSString*) ListManagementMethod;
/*Returns the name of the controller that will manage the simulation*/
- (NSString*) Controller;

@end 

#endif
