#include <cmath>
#include "expression.h"

namespace ExprCalc
{
	/*
		--------------------------------------
		|          Class Expression          |
		--------------------------------------
												*/

	// Destructor, needs to be defined even if //
	// declared as pure virtual, because base  //
	// classes' destructors are always called  //
	// before the derived classes' destructors //
	Expression::~Expression()
	{
	}


	/*
		--------------------------------------
		|        Class DecimalNumber         |
		--------------------------------------
												*/

	// Constructor, initializes the number         //
	// with the given double passed as an argument //
	DecimalNumber::DecimalNumber(double n) : number(n)
	{
	}

	// Returns the number //
	double DecimalNumber::Evaluate()
	{
		return number;
	}


	/*
		--------------------------------------
		|       Class  UnaryOperator         |
		--------------------------------------
												*/

	// Constructor, assigns the right-hand value    //
	// and gives the unary operation its precedence //
	UnaryOperator::UnaryOperator(Expression * r, OperatorPrecedence p) : right(r), precedence(p)
	{
	}

	// Destructor, deletes the right-hand expression //
	UnaryOperator::~UnaryOperator()
	{
		delete right;
	}


	/*
		--------------------------------------
		|      Class  ParanthesisOperator       |
		--------------------------------------
												*/

	// Constructor, assigns the right-hand value    //
	// and gives the unary operation its precedence //
	ParanthesisOperator::ParanthesisOperator(Expression * r) : UnaryOperator(r, Paranthesis)
	{
	}

	// Returns the right-hand value negated //
	double ParanthesisOperator::Evaluate()
	{
		return right->Evaluate();
	}


	/*
		--------------------------------------
		|      Class  NegativeOperator       |
		--------------------------------------
												*/

	// Constructor, assigns the right-hand value    //
	// and gives the unary operation its precedence //
	NegativeOperator::NegativeOperator(Expression * r) : UnaryOperator(r, Negative)
	{
	}

	// Returns the right-hand value negated //
	double NegativeOperator::Evaluate()
	{
		return -right->Evaluate();
	}


	/*
		--------------------------------------
		|       Class  BinaryOperator        |
		--------------------------------------
												*/

	// Constructor, assigns the left-hand //
	// and right-hand value and gives the //
	// binary operation its precedence     //
	BinaryOperator::BinaryOperator(Expression * l, Expression * r, OperatorPrecedence p) : UnaryOperator(r, p), left(l)
	{
	}

	// Destructor, deletes the left-hand expression  //
	// UnaryOperator's destructors handles right one //
	BinaryOperator::~BinaryOperator()
	{
		delete left;
	}


	/*
		--------------------------------------
		|      Class  AdditionOperator       |
		--------------------------------------
												*/

	// Constructor, assigns the left- and right-hand      //
	// value and gives the unary operation its precedence //
	AdditionOperator::AdditionOperator(Expression * l, Expression * r) : BinaryOperator(l, r, Addition)
	{
	}

	// Returns the left- and right-hand value added//
	double AdditionOperator::Evaluate()
	{
		return left->Evaluate() + right->Evaluate();
	}


	/*
		--------------------------------------
		|    Class  SubtractionOperator      |
		--------------------------------------
												*/

	// Constructor, assigns the left- and right-hand      //
	// value and gives the unary operation its precedence //
	SubtractionOperator::SubtractionOperator(Expression * l, Expression * r) : BinaryOperator(l, r, Subtraction)
	{
	}

	// Returns the value of right-hand value substracted from left-hand value //
	double SubtractionOperator::Evaluate()
	{
		return left->Evaluate() - right->Evaluate();
	}


	/*
		--------------------------------------
		|   Class  MultiplicationOperator    |
		--------------------------------------
												*/

	// Constructor, assigns the left- and right-hand      //
	// value and gives the unary operation its precedence //
	MultiplicationOperator::MultiplicationOperator(Expression * l, Expression * r) : BinaryOperator(l, r, Multiplication)
	{
	}

	// Returns the left- and right-hand values multiplied //
	double MultiplicationOperator::Evaluate()
	{
		return left->Evaluate() * right->Evaluate();
	}


	/*
		--------------------------------------
		|      Class  DivisionOperator       |
		--------------------------------------
												*/

	// Constructor, assigns the left- and right-hand      //
	// value and gives the unary operation its precedence //
	DivisionOperator::DivisionOperator(Expression * l, Expression * r) : BinaryOperator(l, r, Division)
	{
	}

	// Returns the value of left-hand value divided by right-hand value //
	double DivisionOperator::Evaluate()
	{
		return left->Evaluate() / right->Evaluate();
	}


	/*
		--------------------------------------
		|       Class  ModuleOperator        |
		--------------------------------------
												*/

	// Constructor, assigns the left- and right-hand      //
	// value and gives the unary operation its precedence //
	ModuleOperator::ModuleOperator(Expression * l, Expression * r) : BinaryOperator(l, r, Module)
	{
	}

	// Returns the remaining value of left-hand value divided by right-hand value //
	double ModuleOperator::Evaluate()
	{
		return fmod(left->Evaluate(), right->Evaluate());
	}


	/*
		--------------------------------------
		|       Class  PowerOperator         |
		--------------------------------------
												*/

	// Constructor, assigns the left- and right-hand      //
	// value and gives the unary operation its precedence //
	PowerOperator::PowerOperator(Expression * l, Expression * r) : BinaryOperator(l, r, Power)
	{
	}

	// Returns the left-hand value raised to the power of right-hand value //
	double PowerOperator::Evaluate()
	{
		return pow(left->Evaluate(), right->Evaluate());
	}
}
