/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2001 Topi Mäenpää
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.4 $
 *********************************************************************/

#ifndef _VALUEHOLDER_H
#define _VALUEHOLDER_H

#include <Object.h>
#include <Util.h>
#include <iostream>

namespace prapi
{
	template <class T> class ValueHolder : virtual public util::Object
	{
	public:
		ValueHolder() { _dValue = 0; }
		ValueHolder(const ValueHolder& other);
		ValueHolder(double v, const T& object);
		
		double& value(void) { return _dValue; }
		T& object(void) { return _dataObject; }

		double getValue(void) const { return _dValue; }
		T getObject(void) const { return _dataObject; }

		void setValue(double v) { _dValue = v; }
		void setObject(const T& object) { _dataObject = object; }

		//friend ostream& operator << (ostream& sout, ValueHolder& obj);
		
		ValueHolder& operator = (const ValueHolder& other);	

		template <class U> friend bool operator == (const ValueHolder<U>& o1, const ValueHolder<U>& o2);
		template <class U> friend bool operator != (const ValueHolder<U>& o1, const ValueHolder<U>& o2);
		template <class U> friend bool operator > (const ValueHolder<U>& o1, const ValueHolder<U>& o2);
		template <class U> friend bool operator < (const ValueHolder<U>& o1, const ValueHolder<U>& o2);
		template <class U> friend bool operator >= (const ValueHolder<U>& o1, const ValueHolder<U>& o2);
		template <class U> friend bool operator <= (const ValueHolder<U>& o1, const ValueHolder<U>& o2);

		template <class U> friend std::ostream& operator<< (std::ostream& sout, const ValueHolder<U>& obj);
		template <class U> friend std::istream& operator>> (std::istream& sin, ValueHolder<U>& obj);
		
	private:
		double _dValue;
		T _dataObject;
	};

	typedef ValueHolder<int> IntegerHolder;
	typedef ValueHolder<float> FloatHolder;
	typedef ValueHolder<double> DoubleHolder;

	template <class T> ValueHolder<T>::ValueHolder(const ValueHolder<T>& other) : _dataObject(other._dataObject)
	{
		_dValue = other._dValue;
	}

	template <class T> ValueHolder<T>::ValueHolder(double v, const T& object)
	{
		_dValue = v;
		_dataObject = object;
	}

	template <class T> ValueHolder<T>& ValueHolder<T>::operator = (const ValueHolder<T>& other)
	{
		_dValue = other._dValue;
		_dataObject = other._dataObject;
		return *this;
	}

	template <class T> bool operator == (const ValueHolder<T>& o1, const ValueHolder<T>& o2) { return (o1._dValue == o2._dValue)?true:false; }
	template <class T> bool operator != (const ValueHolder<T>& o1, const ValueHolder<T>& o2) { return (o1._dValue != o2._dValue)?true:false; }
	template <class T> bool operator > (const ValueHolder<T>& o1, const ValueHolder<T>& o2) { return (o1._dValue > o2._dValue)?true:false; }
	template <class T> bool operator < (const ValueHolder<T>& o1, const ValueHolder<T>& o2) { return (o1._dValue < o2._dValue)?true:false; }
	template <class T> bool operator >= (const ValueHolder<T>& o1, const ValueHolder<T>& o2) { return (o1._dValue >= o2._dValue)?true:false; }
	template <class T> bool operator <= (const ValueHolder<T>& o1, const ValueHolder<T>& o2) { return (o1._dValue <= o2._dValue)?true:false; }

	template <class U> std::ostream& operator<< (std::ostream& sout, const ValueHolder<U>& obj)
	{
		sout << "<valueholder value='" << obj._dValue << "'>";
		util::Util::writeXMLItem(sout,obj._dataObject);
		sout << "</valueholder>";
		return sout;
	}
	
	template <class U> std::istream& operator>> (std::istream& sin, ValueHolder<U>& obj)
	{
		return sin;
	}
}

#endif
