/*
   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 _ADDYNAMICS_DATASOURCE_
#define _ADDYNAMICS_DATASOURCE_
#include <Foundation/Foundation.h>

/**
Protocol for AdDynamics data source delegates
\ingroup Protocols
*/

@protocol AdDynamicsDataSource

/**
Called by the sender (usually AdDynamics) to retrieve the coordinates it is to manage. The data source 
\e must implement the method.
\param sender The sender of the message
\return An NSValue wrapping a DoubleMatrix struct in the Adun Coordinates Matrix format.
*/
- (NSValue*) objectValueForCoordinates: (id) sender;
/**
Called by the sender (usually AdDynamics) to retrieve the velocities it is to manage.
If the data source does not contain velocity information this method must return nil.
In this case the velocities will be generated by the sender
\param sender The sender of the message
\return An NSValue wrapping a DoubleMatrix struct  containing the velocities or nil.
*/
- (NSValue*) objectValueForVelocities: (id) sender;
/**
Called by the sender (usually AdDynamics) to retrieve the accelerations it is to manage.
If the data source does not contain acceleration information this method must return nil.
In this case the accelerations will be generated by the sender
\param sender The sender of the message
\return An NSValue wrapping a DoubleMatrix containing the acceleration or nil.
*/
- (NSValue*) objectValueForAccelerations: (id) sender;
/**
Called by the sender (usually AdDynamics) to retrieve atom types of the atoms it is managing.
\param sender The sender of the message
\return A NSMutableArray of atom ids.
*/
- (NSMutableArray*) objectValueForAtomTypes: (id) sender;

@end

/**
An AdDynamicsDataSource
may implement these methods aswell as their specific ones. You must be aware
that if it does not the data source may become out of sync with the dynamics object
which will cause problems if reloadData is called. This will happen if the data
source provides data by copy and not by reference.
\todo Definine these in an informal protocol instead ?
\ingroup Protocols
*/

@protocol AdDynamicsDataSourceExtensions

/**
Sent to the delegate before the sender removes the information corresponding to the atoms 
specified by atomIndexes from itself. 
\param sender The message sender
\param atomIndexes The indexes of the atoms it is about to remove
*/
- (void) object: (id) sender willRemoveAtoms: (NSIndexSet*) atomIndexes;
/**
Sent to the delegate before the sender removes all information corresponding to the atoms 
specified by atomTypes from itself. 
Implementation of this method is optional.
\param sender The message sender
\param atomIndexes The types of the atoms it is about to remove
*/
- (void) object: (id) sender willRemoveAtomTypes: (NSMutableArray*) atomTypes;
/**
Sent to the delegate before the sender adds information about other atoms to itself.
Implementation of this method is optional.
\param sender The message sender
\param atomCoordinates An NSValue object wrapping a DoubleMatrix 
in the Adun Coordinates format containing information about the atoms being added.
\param atomTypes The types of the atoms being added.
*/
- (void) object: (id) sender didRemoveAtoms: (NSIndexSet*) atomIndexes;
/**
Sent to the delegate after the sender removes the information corresponding to the atoms 
specified by atomIndexes from itself. 
Implementation of this method is optional.
\param sender The message sender
\param atomIndexes The indexes of the atoms it is about to remove
*/
- (void) object: (id) sender willAddAtoms: (NSValue*) atomCoordinates withAtomTypes: (NSArray*) atomTypes;
/**
Sent to the delegate after the sender removes the information corresponding to the atoms 
specified by  atomTypes from itself.
Implementation of this method is optional.
\param sender The message sender
\param atomTypes The types of the atoms it is about to remove
*/
- (void) object: (id) sender didRemoveAtomTypes: (NSMutableArray*) atomTypes;
/**
Sent to the delegate after the sender adds the atoms specfied by atomCoordinates.
Implementation of this method is optional.
\param sender The message sender
\param atomIndexes The indexes of the atoms it is about to remove
*/
- (void) object: (id) sender didAddAtoms: (NSValue*) atomCoordinates withAtomTypes: (NSArray*) atomTypes;

@end

/**
Data sources for BondedTopology objects must implement these
methods
\todo Must define the topology types adun knows about as constants
\ingroup Protocols
*/

@protocol AdBondedTopologyDataSource

/**
Called by the sender to retrieve the topologies it is to manage. The data source 
\e must implement the method.
\param sender The sender of the message
\return An NSDictionary containing the interactions in interactionType:interactionMatrix pairs
*/
- (NSDictionary*) objectValueForBondedInteractions: (id) object;
@end

/**
Data sources for NonBondedTopology objects must implement these
methods
\todo Must define the topology types adun knows about as constants
\ingroup Protocols
*/

@protocol AdNonbondedTopologyDataSource

/**
Called by the sender to retrieve the set of nonbonded interactions it is to manage. The data source 
\e must implement the method.
\param sender The sender of the message
\return An NSArray of NSIndexSets containing the interactions for each atom.
*/
- (NSArray*) objectValueForNonbondedInteractions: (id) object;
/**
Called by the sender to retrieve the types of nonbonded interactions it is to manage. Each type may be associated
with a parameter matrix (or an array of parameter matricies. Which depends on the interactionType)
\param sender The sender of the message
\return An NSDictionary of interactionType:interactionParameters pairs. 
*/
- (NSDictionary*) objectValueForNonbondedInteractionTypes: (id) object;

@end

/**
A data source for a Topology object i.e. AdBondedTopology AdNonBondedTopology
may implement these methods aswell as their specific ones. You must be aware
that if it does not the data source may become out of sync with the Topology object
which will cause problems if reloadData is called. This will happen if the data
source provides data by copy and not by reference.
\todo Definine these in an informal protocol instead ?
\ingroup Protocols
*/

@protocol AdTopologyDataSourceExtensions

- (void) object: (id) sender 
		willRemoveInteractions: (NSIndexSet*) atomIndexes 
		fromInteractionType: (NSString*) topologyName;
- (void) object: (id) sender 
		willRemoveInteractionsInvolvingAtoms: (NSIndexSet*) atomIndexes 
		fromInteractionType: (NSString*) topologyName;
- (void) object: (id) sender 
		willAddInteraction: (NSValue*) interaction
		toInteractionType: (NSString*) topologyName;
- (void) object: (id) sender 
		didRemoveInteractions: (NSIndexSet*) atomIndexes 
		fromInteractionType: (NSString*) topologyName;
- (void) object: (id) sender 
		didRemoveInteractionsInvolvingAtoms: (NSIndexSet*) atomIndexes 
		fromInteractionType: (NSString*) topologyName;
- (void) object: (id) sender 
		didAddInteraction: (NSValue*) interaction
		toInteractionType: (NSString*) topologyName;
@end

/**
Data Source for an AdSystem object
\ingroup Protocols
*/

@protocol AdSystemDataSource <AdDynamicsDataSource, AdBondedTopologyDataSource, AdNonbondedTopologyDataSource>
@end

/**
Data source extension for an AdSystem object
\ingroup Protocols
*/

@protocol AdSystemDataSourceExtensions <AdDynamicsDataSourceExtensions, AdTopologyDataSourceExtensions>
@end

#endif
