module gumballmachine;

import std.stdio : writeln;
import std.conv : to;
import soldoutstate, noquarterstate, hasquarterstate, soldstate, state, winnerstate;

class GumballMachine
{ 
    State soldOutState;     // нет жевательных шариков
    State noQuarterState;   // нет четвертака (есть жевательные шарики, готов к продаже)
    State hasQuarterState;  // вставлен четвертак (либо купить шарик, либо вернуть моентку)
    State soldState;        // продажа шарика (выдача шарика)
    State winnerState;      // выдача дополнительного шарика при 10% вероятности
 
    State state;
    int count = 0;
 
    this(int numberGumballs)
    {
        soldOutState = new SoldOutState(this);
        noQuarterState = new NoQuarterState(this);
        hasQuarterState = new HasQuarterState(this);
        soldState = new SoldState(this);
        winnerState = new WinnerState(this);

        this.count = numberGumballs;
        if (numberGumballs > 0)
        {
            state = noQuarterState;
        }
        else
        {
            state = soldOutState;
        }
    }
 
    void insertQuarter()
    {
        state.insertQuarter();
    }
 
    void ejectQuarter()
    {
        state.ejectQuarter();
    }
 
    void turnCrank()
    {
        state.turnCrank();
        state.dispense();
    }
 
    void releaseBall()
    {
        writeln("Из щели выкатывается шарик жевательной резинки...");
        if (count > 0)
        {
            count = count - 1;
        }
    }
 
    int getCount()
    {
        return count;
    }
 
    void refill(int count)
    {
        this.count += count;
        writeln("Автомат для жевательных резинок был только что заправлен; его новое количество составляет: ",
            this.count);
        state.refill();
    }

    void setState(State state)
    {
        this.state = state;
    }

    State getState()
    {
        return state;
    }

    State getSoldOutState()
    {
        return soldOutState;
    }

    State getNoQuarterState()
    {
        return noQuarterState;
    }

    State getHasQuarterState()
    {
        return hasQuarterState;
    }

    State getSoldState()
    {
        return soldState;
    }

    State getWinnerState()
    {
        return winnerState;
    }
 
    override string toString() const
    {
        string s;
        s ~= "\nMighty Gumball, Inc.";
        s ~= "\nD-enabled Standing Gumball Model #2004";
        s ~= "\nInventory: " ~ count.to!string ~ " gumball";
        if (count != 1)
        {
            s ~= "s";
        }
        s ~= "\n";
        s ~= "Machine is " ~ state.to!string ~ "\n";
        return s;
    }
}