/*
   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 _ADGRID_
#define _ADGRID_

#include <math.h>
#include "Base/AdVector.h"
#include "Base/AdMatrix.h"
#include "AdunKernel/AdGridDelegate.h"
#include "AdunKernel/AdunDefinitions.h"
#include "AdunKernel/AdunObject.h"
#include "AdunKernel/AdunMemoryManager.h"

/**
Grid object
\ingroup Inter
*/

@interface AdGrid: AdObject 
{
	BOOL isTranslationEnabled;
	int gridPoints;
	AdMatrix* grid;
	int ticksPerAxis[3];
	Vector3D cavityCentre;
	NSArray* cavityExtremes;
	NSArray* gridSpacing;
	AdMemoryManager* memoryManager;
	id cavity;
}

/**
Creates a grid with the given density of points in the volume
defined by the delegate. Requires the delegate to implement cavityVolume.
*/
- (id) initWithDensity: (double) density cavity: (id) cavity environment: (id) object;
/**
Creates a grid with the given number of ticks on each axis. The
tick spacing is defined by the delegate extremes.
\param An NSArray on integers specfying the ticks for each axis in the order x,y,z
*/
- (id) initWithDivisions: (NSArray*) divisions cavity: (id) cavity environment: (id) object;
/**
Creates a grid with the given spacing between ticks on each axis
\param An NSArray of double specifying the spacing for each axis in the order x,y,z
*/
- (id) initWithSpacing: (NSArray*) spacing cavity: (id) cavity environment: (id) object;
+ (id) gridWithDensity: (double) density cavity: (id) aCavity environment: (id) object;
+ (id) gridWithDivisions: (NSArray*) divisions cavity: (id) aCavity environment: (id) object;
+ (id) gridWithSpacing: (NSArray*) spacing cavity: (id) aCavity environment: (id) object;
/**
Translates the grid by the vector \e translationVector. This method will only have an affect
if translationEnabled return YES.
\param An NSArray of doubles
*/
- (void) translateBy: (Vector3D*) translationVector;
/**
Sets if the object should allow translation. This method will only have an affect if the delegate
returns NO for handlesTranslation.
*/
- (void) setTranslationEnabled: (BOOL) value;
/**
Resturns YES if the grid can be translated
*/
- (BOOL) isTranslationEnabled;
/**
If the space defined by the cavity changes this message should be sent in order to update the grid.
Any objects that retain references to the grid matrix should acquire a new reference. 
*/
- (void) resetCavity;
/**
Should be sent on a change of cavity poisition. The grid object compares the old and new centers
and moves translates grid accordingly. If the volume defined by the cavity also changes you should use resetCavity instead.
This method does not affect the grid matrix references i.e. the pointer to grid matrix remains the same.
*/
- (void) cavityDidMove;
- (void) setCavity: (id) anObject;
- (id) cavity;
- (id) grid;
- (NSArray*) spacing;
- (NSArray*) divisions;
- (int) numberOfPoints;
@end

#endif

