/*************************/
/*/  ---CPP11 ISO---    /*/
/*/                     /*/
/*/  dodaj ako ti nije  /*/
/*/  vec defaultno      /*/
/*/  pri kompilaciji    /*/
/*/  -std=c++11         /*/
/*************************/

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
typedef unsigned int uint;

#define NOT_IN_ORDER 0xff  // definiraj invariant (ono sto ne pase)
                           // vidi nize i bit ce jasnije


// struct Menu nosi osnovne podatke
struct Menu
{
    Menu(string menuItem , float menuPrice);

    string MenuItem;
    float MenuPrice;

};

Menu::Menu(string menuItem , float menuPrice)
    : MenuItem(menuItem) , MenuPrice(menuPrice)
{
}


// u klasi Restaurant rijesavamo cijeli zadatak
class Restaurant
{
public:
    Restaurant();

    // serve i display su dostupni
    // ostalo nema potrebe biti public
    // jer samo Restaurant interno
    // barata onime sto je pod private
    void serve();
    void display();


private:
    vector<Menu> m_menus
    {
        // c++11 dopusta iniciranje u samoj klasi
        // iskoristit cemo to upravo sad
        Menu("Plain_Egg",1.45),
        Menu("Bacon_and_Egg",2.45),
        Menu("Muffin",0.99),
        Menu("French_Toast",1.45),
        Menu("Fruit_Basket",2.49),
        Menu("Cereal",0.69),
        Menu("Coffee",0.50),
        Menu("Tea",0.75)
    };

    // ovime vrsimo provjeru unesenog MenuItem-a
    uint processWhat(string what);

    // u order punimo index odnosno offsete m_menus-a
    // vidi nize da bude jasnije
    vector<uint> order;

};

Restaurant::Restaurant()
{
    cout<< "u ponudi restauranta imamo :\n\n";

    // c++11 auto je dobra stvar koja ubrzava code
    // dakle iskoristimo ga
    for(auto x : m_menus)
        cout<< x.MenuItem << " " << x.MenuPrice << endl;
}


void Restaurant::serve()
{
    cout<< "\nchoose menu\n\n";

    string terminateString = "done";
    string what = "";

    while(what != terminateString)
    {
        cin>> what;

        uint offset = processWhat(what);
        if(offset != NOT_IN_ORDER)
        {
            // ukoliko je narudzba jednaka posojecem menu
            // u order stavljamo offset iz m_menus-a
            // vidi jos nize
            order.push_back(offset);
            cout<< "OK , another one or type done for exit\n";
            }
        else
            cout<< "not in order , try again or type done for exit\n";

    }

    display();
}


uint Restaurant::processWhat(string what)
{
    vector<Menu>::iterator it = find_if(m_menus.begin(),m_menus.end(), [&] (Menu a)
    {	//c++11 lambda
        return (a.MenuItem == what);
    }
                                       );
    // ukoliko menu koji je user upisao postoji
    // njegov offset u m_menus-u dobijes pointer aritmetikom
    // it - m_menus.begin() a ukoliko menu ne postoji vrati invariant
    return (it == m_menus.end() ? NOT_IN_ORDER : (it - m_menus.begin()));
}


void Restaurant::display()
{
    // na kraju ispis svega
    float price = 0;

    cout<< "\nNARUDZBA SADRZI :\n";
    for(auto x : order)
    {
        cout<< m_menus[x].MenuItem << endl;
        price += m_menus[x].MenuPrice;
    }

    cout<< "\n\n\nTOTAL : " << price << "$\nDODJITE NAM OPET\n\n";
}



int main()
{
    Restaurant BUG_RESTAURANT;
    BUG_RESTAURANT.serve();


    // pozdrav i sretno
    return 0;
}
