/**------------------------------------------------------------------------
 * @file
 *
 * Copyright 2001 by the University of Toronto (UT).
 *
 *                       All Rights Reserved
 *
 * Permission to copy and modify this software and its documentation
 * only for internal use in your organization is hereby granted,
 * provided that this notice is retained thereon and on all copies.
 * UT makes no representations as to the suitability and operability
 * of this software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 *
 * UT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
 * SHALL UT BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
 * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * No other rights, including for example, the right to redistribute
 * this software and its documentation or the right to prepare
 * derivative works, are granted unless specifically provided in a
 * separate license agreement.
 *
 * Author: Maxim Trokhimtchouk (trokhim@cs.utoronto.ca)
 *
 * $Log: memorydatabase.hpp,v $
 * Revision 1.1.1.1  2002/03/10 07:38:07  dmac
 * Imported sources
 *
 * Revision 1.1  2001/10/03 20:19:57  dmac
 * Added file
 *
 *
 *-----------------------------------------------------------------------*/

#ifndef __DATABASE_HPP__
#define __DATABASE_HPP__

#include <vector>
#include <string>
#include <utility>
#include <iostream>

using namespace std;

///Type used as an identification type through out the system
typedef int ID;

///Defines a constant that identifies nonexistant element
const ID NULLID = -1;

///Template for a memory resident database.
/**
*Database class template used to maintain a memory resident 
*collection of records
*of type T addressed by the identification numbers
*@param T parameter identifies the type of the records in the database.
*/
template <class T> class MemoryDatabase
{
private:
	///Contains the name of the database.
	string name;
protected:
	///Record container.
	/**
	*Contains a vector of  pointers to data. NULL item
	*indicates that item does not exist
	*/
	vector<T*> records;
public:
	///Default construictor.
	MemoryDatabase();
	///Destructor.
	virtual ~MemoryDatabase();

	///indexing operator
	/**
	*Returns the pair of record data and boolean value indicating
	*whether such record exist in the database
	*@pre Create or Read functions must be called before a call to 
	*this function.
	*@post This function checks whether element with the identification 
	*id exist in the database.
	*@param 'id' contains element identifier.
	*@return Returns pair of record class value and boolean value
	*@return  indicating success of the operation.
	*/
	pair<T, bool> operator[](ID id);	
	
	///Adds the record to the database.
	/**
	*Adds the record to the database and returns its id.
	*@pre Create or Read functions must be called before a call to this
	*@pre function.
	*@post This function does not enforce for the uniquieness of the 
	*@postrecord values in the database.
	*@param 'record' is a value of the type T to store in the database
	*@return Returns the identification number of the new element 
	*@return added to a database.
	*/
	ID Add(const T& record);
	
	///Removes the record from the database.
	/**
	*Removes the element with the identification id from the database.
	*@pre Create or Read functions must be called before a call to 
	*@pre this function.
	*@post If element with identification id does not exit, 
	*@post function call is ignored.
	*@param 'id' contains the identification of the element 
	*@param 'id' to be removed from the database.
	*@return No return values.
	*/
	void Remove(ID id);

	///Removes all of the records from the database.	
	/**
	*Removes all of the records from the database.	
	*All of the memory allocated for the storage of the records 
	*is released.
	*@pre Create or Read functions must be called before 
	*@pre a call to this function.
	*@return No return values.
	*/
	void RemoveAll();

	///Determines whether element with 'id' is  contain in the database.
	/**
	*Determines whether element with 'id' is  contain in the database.
	*@pre Create or Read functions must be called before a call 
	*@pre to this function.
	*@param 'id' contains the identification number.
	*@return Returns true if a record with the specified id exist 
	*@return in the database. Return false otherwise.
	*/
	bool Contained(ID id);

	///Creates the database with the name n.
	/**
	*Creates the database with the name n. This function does
	*not influence the behaivior of the class, but is recomended to
	*use for consistency with other database classes.
	*@param 'n' contains the name of the database to be created.
	*@return Returns true if creation of the database was successful. 
	*@return Returns false otherwise.
	*/
	bool Create(const string& n);

	///Returns the name of the database that was specified 
        ///during creation of the database.
	/**
	*Returns the name of the database that was specified 
	*during creation of the database.
	*@return Returns the name of the database.
	*/
	string GetDatabaseName();
	
	///Reads database from a stream.
	/**
	*Reads database from a stream.
	*@param 'is' refers to an instance of a stream that will be 
	*@param 'is' used for loading the database
	*@return returns a reference to a stream used for loading the database.
	*/
	std::istream& Read(std::istream& is);

	///Writes database to a file
	/**
	*Writes database to a stream.	
	*@param 'os' refers to an instance of a stream that will 
	*@param 'os' be used to store the database
	*@return returns a reference to a stream used to store the database.
	*/
	std::ostream& Write(std::ostream& os);
};


//implementation
#include "memorydatabase.hxx"

#endif //__DATABASE_HPP__
