/*********************************************************************
 * This file is part of the cpplibs suite.
 *
 * 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.5 $
 *********************************************************************/

#include "Computable.h"
#include "Boolean.h"
#include "Number.h"

namespace util
{
	SmartPtr<Computable> Computable::complement() const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean((bool)*this));
	}
	SmartPtr<Computable> Computable::less(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean(compare(c) < 0));
	}
	SmartPtr<Computable> Computable::greater(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean(compare(c) > 0));
	}
	SmartPtr<Computable> Computable::lessOrEqual(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean(compare(c) <= 0));
	}
	SmartPtr<Computable> Computable::greaterOrEqual(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean(compare(c) >= 0));
	}
	SmartPtr<Computable> Computable::equal(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean(compare(c) == 0));
	}
	SmartPtr<Computable> Computable::different(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean(compare(c) != 0));
	}
	SmartPtr<Computable> Computable::logAnd(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean((bool)*this && (bool)c));
	}
	SmartPtr<Computable> Computable::logOr(const Computable& c) const throw (ComputationException&)
	{
		return SmartPtr<Computable>(new Boolean((bool)*this || (bool)c));
	}

	SmartPtr<Computable> Computable::arrayIndex(const Computable& c) const throw (ComputationException&)
	{
		const Number* index = dynamic_cast<const Number*>(&c);
		if (index && index->doubleValue() == 0)
			{
				try
					{
						return SmartPtr<Computable>(dynamic_cast<Computable*>(clone()));
					}
				catch (NotCloneableException& nce)
					{
						throw ComputationException(nce.getMessage());
					}
			}
		else
			throw OperationNotDefinedException("Computable::arrayIndex(const Computable&): " +
																				 getClassName() + "[" + c.getClassName() + "] not defined.");
	}
}
