/*
   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.
*/
#ifndef _ADUNINTERACTIONSYSTEM_
#define _ADUNINTERACTIONSYSTEM_

#include "Base/InterTable.h"
#include "AdunKernel/AdDataSources.h"
#include "AdunKernel/AdDelegation.h"
#include "AdunKernel/AdunDefinitions.h"
#include "AdunKernel/AdunObject.h"
#include "AdunKernel/AdunNonBondedTopology.h"
#include "AdunKernel/AdunState.h"
#include "AdunKernel/AdunTimer.h"

/**
AdInteractionSystem represents the interactions (i.e. the topology) between two AdSystems. Unlike an AdSystem
it doesnt "contain" any system elements e.g. atoms, as these are already part of its constituent AdSystems.
Hence the return value for coordinates and accelerations is simply the combination of the 
coordinates & accelerations of its consituents. 

An AdInteractionSystem can have two states "Active" or "Inactive" - it cannot be passive. In addition if either
of its the two consituent AdSystems is "Inactive" then it should also be "Inactive". This change is automatically
handled by the AdSystemNode that manages all the subsystems. Also an AdInteractionSystem cannot 
be made "Active" if either of the AdSystems is "Inactive". You must change the AdSystems' states first.

You should not normally create AdInteractionSystem's yourself. AdSystemNode will create and provide access to
them where necessary.

\note The coordinates and accelerations matrices returned by an AdInteractionSystem are directly related to
the coordinates and acceleration matrices of its constituents i.e. modifying them will modify the originals.
Hence great care must be taken when using these matrices. In general the coordinates matrix should never be
modified. AdForceField objects directly add forces to the acceleration matrix which  means that the
the AdSystems acceleration matrices contain the cumulative force on each atom from all interactions after
AdForceFieldManager:calculateAccelerations is called.

\todo Move matrix combining code to Base
\todo Implement handling of bonded interactions between two systems
\todo Implement proper handling of nonbonded interaction types. 
\todo Implement initWithCoder:
(Currently assumes the types of nonbonded interactions to be CoulombElectrostatic and TypeOneVDWInteraction)
\ingroup Inter

*/

@interface AdInteractionSystem: AdObject <AdDataSourceDelegation, AdNonbondedTopologyDataSource>
{
	BOOL dataLoaded;
	int numberOfAtoms;
	AdMatrix* combinedCoordinates;
	AdMatrix* combinedVelocities;
	AdMatrix* combinedAccelerations;
	NSMutableArray* nonbondedInteractions;
	NSMutableArray* nonbondedInteractionTypes;
	NSMutableArray* systemKeywords;
	NSArray* allowedStates;
	NSString* status;
	id shortRangeNonbondedTopology;
	id longRangeNonbondedTopology;
	id bondedTopology;
	id dataSource;
	id subsystemOne;
	id subsystemTwo;
	id state;
}

- (NSValue*) coordinates;
- (NSValue*) velocities;
- (NSValue*) accelerations;
- (id) dynamics;
- (id) bondedTopology;
- (id) shortRangeNonbondedTopology;
- (id) longRangeNonbondedTopology;
- (id) state;
- (NSDictionary*) bondedInteractions;
- (NSDictionary*) nonbondedInteractionTypes;
- (NSValue*) shortRangeNonbondedInteractions;
- (NSValue*) longRangeNonbondedInteractions;
- (id) systemKeywords;
- (NSString*) systemName;
- (NSString*) status;
- (void) setStatus: (NSString*) status;

@end

#endif
