#include <iostream>
using std::cout;
using std::endl;

class Employee;     //forward class declaration

class Pay {
public:
	virtual void payTechEmpl(Employee*)=0;
	virtual void paySalesEmpl(Employee*)=0;
};

class Employee {
public:
	Employee(Pay* payImpl) { payImplementation = payImpl; }

	virtual void calcSalary()=0;

	void setMonthlySalary(double amount) { monthlySalary = amount; }
	double getMonthlySalary() { return monthlySalary; }
	void setHoursWorked(int hours) { hoursWorked = hours; }
	void setHourlySalary(double amount) { hourlySalary = amount; }
	int getHoursWorked() {return hoursWorked; }
	double getHourlySalary() { return hourlySalary; }
	Pay* getPayImplementation() { return payImplementation; }
	void setPayImplementation(Pay* impl) { payImplementation = impl; }

private:
	Pay* payImplementation;

	int hoursWorked;
	float monthlySalary;
	float hourlySalary;
};

class TechEmployee : public Employee {
public:
	TechEmployee(Pay* payImpl);
	virtual void calcSalary();
};

TechEmployee::TechEmployee(Pay* payImpl) : Employee(payImpl) {}

void TechEmployee::calcSalary()
{
	getPayImplementation()->payTechEmpl(this);
}

class PayPerMonth : public Pay {
public:
	virtual void payTechEmpl(Employee* emp);
	virtual void paySalesEmpl(Employee* emp);
};

void PayPerMonth::payTechEmpl(Employee* emp)
{
	double endSalary;
	endSalary = emp->getMonthlySalary();
	endSalary = endSalary * 0.9;	//deduce 10% tax
	cout << "Technical Employee, Pay Per Month" << endSalary << endl;
};

void PayPerMonth::paySalesEmpl(Employee* emp)
{
	double endSalary;
	endSalary = emp->getMonthlySalary();
	endSalary = endSalary * 0.8;	//deduce 20% tax
	cout << "Sales Employee, Pay Per Month" << endSalary << endl;
};


class PayPerHour : public Pay {
public: 
	virtual void payTechEmpl(Employee* emp);
	virtual void paySalesEmpl(Employee* emp);
};

void PayPerHour::paySalesEmpl(Employee* emp)
{
	double endSalary;
	endSalary = emp->getHourlySalary() * emp->getHoursWorked();
	endSalary = endSalary * 0.95;	//deduce 5% tax
	cout << "Sales Employee, Pay Per Hour" << endSalary << endl;;
};

void PayPerHour::payTechEmpl(Employee* emp)
{
	double endSalary;
	endSalary = emp->getHourlySalary() * emp->getHoursWorked();
	endSalary = endSalary * 0.985;	//deduce 15% tax
	cout << "Technical Employee, Pay Per Hour" << endSalary << endl;;
};

  
int main()
{

	PayPerMonth Pay1;				//δημιουργία αντικειμένου τρόπου πληρωμής
	TechEmployee Fred(&Pay1);		//δήλωση Τεχνικού Υπαλλήλου
	
	Fred.setMonthlySalary(1200.00);	
	Fred.calcSalary();				//υπολογισμός μισθού με βάση το μήνα

	PayPerHour Pay2;
	Fred.setPayImplementation(&Pay2);
	Fred.setHourlySalary(15.70);
	Fred.setHoursWorked(38);
	Fred.calcSalary();				//υπολογισμός μισθού με βάση τις ώρες

	return 0;
}



