#include <iostream>
//#include "Decaf.h"
//#include "Espresso.h"
//#include "SoyDecorator.h"
//#include "CaramelDecorator.h"

class Beverage
{
public:

	virtual std::string GetDescription() const = 0;
	virtual int GetCost() const = 0;
};

class CondimentDecorator : public Beverage
{
public:

	Beverage* beverage;
	CondimentDecorator(Beverage* beverage) : beverage(beverage) {}
};

class Espresso : public Beverage
{
	virtual std::string GetDescription() const override
	{
		return "Espresso";
	}

	virtual int GetCost() const override
	{
		return 5;
	}
};

class Decaf : public Beverage
{
	virtual std::string GetDescription() const override
	{
		return "Decaf";
	}

	virtual int GetCost() const override
	{
		return 4;
	}
};

class CaramelDecorator : public CondimentDecorator
{
public:
	
	CaramelDecorator(Beverage* beverage) : CondimentDecorator(beverage) {}
	
	virtual std::string GetDescription() const override
	{
		return this->beverage->GetDescription() + " with Caramel";
	}

	virtual int GetCost() const override
	{
		return this->beverage->GetCost() + 2;
	}
};

class SoyDecorator : public CondimentDecorator
{
public:

	SoyDecorator(Beverage* beverage) : CondimentDecorator(beverage) {}

	virtual std::string GetDescription() const override
	{
		return this->beverage->GetDescription() + " with Soy";
	}

	virtual int GetCost() const override
	{
		return this->beverage->GetCost() + 1;
	}
};

int main()
{
	Decaf* d = new Decaf;
	SoyDecorator* s = new SoyDecorator(d);
	CaramelDecorator* c = new CaramelDecorator(s);
	CaramelDecorator* cc = new CaramelDecorator(c);

	std::cout << cc->GetDescription() << std::endl;
	std::cout << cc->GetCost() << std::endl;
}