/***************************************************************************
                          knightsmap.h  -  description
                             -------------------
    begin                : Sun Aug 25 2002
    copyright            : (C) 2003 by Troy Corbin Jr.
    email                : tcorbin@users.sf.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program 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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <tqvaluelist.h>

#ifndef KNIGHTSMAP_H
#define KNIGHTSMAP_H

/**
  *@author Troy Corbin Jr.
  */

template<class Key, class T>
class KnightsMap
{
public:
	typedef Key			KeyType;
	typedef T				DataType;
	struct	Pair
									{
										KeyType		key;
										DataType	data;
									};

private:
	TQValueList<Pair>	pairList;

	Key								searchKey;
	unsigned int			searchIndex;
	T									nullValue;
	T									tempValue;

public:
								/*
										Constructor
								*/
								KnightsMap()
								{
									nullValue = 0;
									clear();
								}

								/*
										Destructor
								*/
								~KnightsMap()
								{ clear(); }

								/*
										Returns the number of items in the map
								*/
unsigned int		count( void )
								{ return pairList.count(); }

								/*
										Clears the map
								*/
void						clear( void )
								{
									searchIndex = 0;
									pairList.clear();
								}

								/*
										Add a Key/Value pair to the map
								*/
void						add( KeyType key, DataType data )
								{
									Pair newPair;
									newPair.key = key;
									newPair.data = data;
									pairList.append( newPair );
								}

								/*
										Return the next Value associated with the Key given
										in the last call to 'find'. If there are none, then
										NULL is returned.
								*/
T&							findNext( void )
								{
									unsigned int maxIndex( pairList.count() );
									for( ; searchIndex < maxIndex ; searchIndex++ )
									{
										if( searchKey != pairList[searchIndex].key )
										{
											continue;
										}
										return pairList[searchIndex++].data;
									}
									return nullValue;
								}

								/*
										Lookup a Value by it's key. This will always return
										the first Value that's associated with the given Key.
										If no Value has the given Key, NULL is returned.
								*/
T&							find( KeyType key )
								{
									searchKey = key;
									searchIndex = 0;
									return findNext();
								}

								/* Removes all Values that are associated with Key */
T&							remove( KeyType key )
								{
									TQValueListIterator<Pair> IT( pairList.begin() );
									while( IT != pairList.end() )
									{
										if( (*IT).key == key )
										{
											tempValue = (*IT).data;
											IT = pairList.remove( IT );
											return tempValue;
										}
										IT++;
									}
									return nullValue;
								}

								/* Return the Value stored at Index i */
T&							operator[]( unsigned int i )
								{ return pairList[i].data; }

								/* Return the Key stored at Index i */
Key&						keyAt( unsigned int i )
								{ return pairList[i].key; }

								/*
										Return the Value stored one Index position previous
										to the last returned search Value. If already at the
										begining of the Map, then NULL is returned.
								*/
T&							operator--( void )
								{
									if( searchIndex > 1 )
									{
										searchIndex -= 2;
									}
									else
									{
										return nullValue;
									}
									return pairList[searchIndex++].data;
								}

								/*
										Return the Value stored one Index position after
										the last returned search Value. If already at the
										end of the Map, then NULL is returned.
								*/
T&							operator++( void )
								{
									if( searchIndex >= count() )
									{
										return nullValue;
									}
									return pairList[searchIndex++].data;
								}
};

#endif
