/*
   Project: Adun

   Copyright (C) 2006 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 ADLINKEDLIST_H
#define ADLINKEDLIST_H

#define _GNU_SOURCE

#include <stdlib.h>
#include <Foundation/Foundation.h>
#include <Base/AdLinkedList.h>
#include <AdunKernel/AdunObject.h>

/**
Class providing high performance linked list managment for
pairwise nonbonded interaction lists. 

\note This class is only useful for linked lists that
represent nonbonded interactions. The linked list structure
used is tailored for these interactions i.e. a pair of atoms
plus a distance them. At the moment vdw parameters are included
in each list element. However this affects generality i.e. why
vdw and not electrostatic or hbond and also assumes the system
knows the parameter combination rules of the force field. Any
combination should be obviously done by the force field itself.

\todo Extend with methods that provide "subviews" of the
list as arrays. E.g. All atoms above or below a certain distance etc.

\note Could have nonbondedListHandler return this class
instead of the list. Then the class could have a delegate
that could compute parameters etc.. 

*/

@interface AdLinkedList: AdObject
{
	int listCount;
	ListElement* linkedList;
	ListElement* linkedListEnd;
	//memory
	int BLOCKSIZE;
	int block_count;	//the current location in the current block
	int block_no;		//the current number of blocks
	int current_block_no; 	//the number of the current block
	int freeElementsCount;
	ListElement* blocks[50];	//array containing the current blocks
	ListElement* current_block;	//the current block
	NSMutableArray* freeElements;	//array of pointers to freed elements
	id (*getElement)(id, SEL);
	void (*removeElement)(id, SEL);
	void (*addElement)(id, SEL, id);
}
- (id) initWithBlocksize: (int) size;
- (ListElement*) createNewListBlock;
- (ListElement*) getNewListElement;
- (void) freeListElement: (ListElement*) list_p;
- (ListElement*) listStart;
- (ListElement*) listEnd;
- (int) listCount;
@end

#endif 
