#include "application.h"
#include <iostream>

using namespace std;
using namespace genv;

label* background;
label* labelAns;
label* labelOperator;
label* labelActual;
group* numbers;
vector<button*> numberButtons;
group* operators;
vector<button*> operationButtons;
button* clearButton;
button* equalButton;

enum operations { addition = 0, substraction = 1, multiplication = 2, division = 3 };
int operation;

bool decimalPointFlag = false;

void numberButton_Click(int x, int y, char button, int index)
{
    if ( decimalPointFlag && index == 10 ) return;

    if ( labelOperator->getText() != " " )
    {
        labelActual->setText(labelActual->getText() + numberButtons[index]->getText());
    }
    else
    {
        if ( labelAns->getText() == "0") labelAns->setText(numberButtons[index]->getText());
        else labelAns->setText(labelAns->getText() + numberButtons[index]->getText());
    }

    if ( index == 10 ) decimalPointFlag = true;
}

void Clear ()
{
    labelOperator->setText(" ");
    labelActual->setText(" ");
    decimalPointFlag = false;
}

void clearButton_Click(int x, int y, char button, widget *W)
{
    Clear();
    labelAns->setText("0");
}

void equalButton_Click(int x, int y, char button, widget *W)
{
    if ( labelActual->getText() == " ") return;

    switch ( operation )
    {
    case addition :
        labelAns->setText(convertS(convertF(labelAns->getText()) + convertF(labelActual->getText())));
        Clear();
        break;
    case substraction :
        labelAns->setText(convertS(convertF(labelAns->getText()) - convertF(labelActual->getText())));
        Clear();
        break;
    case multiplication :
        labelAns->setText(convertS(convertF(labelAns->getText()) * convertF(labelActual->getText())));
        Clear();
        break;
    case division :
        labelAns->setText(convertS(convertF(labelAns->getText()) / convertF(labelActual->getText())));
        Clear();
        break;
    }
}

void operationButton_Click(int x, int y, char button, int index)
{
    if ( labelActual->getText() == " " )
    {
        labelOperator->setText(operationButtons[index]->getText());
    }
    else
    {
        equalButton_Click(x, y, button, NULL);
        labelOperator->setText(operationButtons[index]->getText());
    }
    operation = index;
}

/// ---- Main ------------------------
int main ()
{
    application App(270, 385);

    /// ---- Kijelző ----
    App.add( background = new label(10, 10, 250, 50, " ") );
    background->background = true;

    App.add( labelAns = new label(10, 10, 240, 15, "0") );
    labelAns->align = align_right;
    labelAns->display = trimEnd;

    App.add( labelOperator = new label(10, 30, 15, 15, " ") );

    App.add( labelActual = new label(35, 35, 225, 15, " ") );
    labelActual->align = align_right;
    labelActual->display = trimEnd;

    /// ---- Számgombok ----
    numbers = App.newGroup();
    numbers->eventGroupClick = numberButton_Click;
    for ( unsigned int i = 0; i < 9; i++ )
    {
        numberButtons.push_back( new button(15 + i%3*60, 80 + i/3*60, 50, 50, convertS(i)) );
        *numbers << numberButtons[i];
        numberButtons[i]->setMargin(20,20);
    }

    numberButtons.push_back( new button(75, 260, 50, 50, "9") );
    *numbers << numberButtons[9];
    numberButtons[9]->setMargin(20,20);

    numberButtons.push_back( new button(135, 260, 50, 50, ".") );
    *numbers << numberButtons[10];
    numberButtons[10]->setMargin(20,20);

    /// ---- Törlés-gomb ----
    App.add( clearButton = new button(15, 260, 50, 50, "C"));
    clearButton->eventClick = clearButton_Click;
    clearButton->setMargin(20,20);

    /// ---- Műveleti gombok ----
    operators = App.newGroup();
    operators->eventGroupClick = operationButton_Click;
    vector<string> temp = { "+", "-", "*", "/" };
    for ( unsigned int i = 0; i < 4; i++ )
    {
        operationButtons.push_back( new button(205, 80 + i*60, 50, 50, temp[i]) );
        *operators << operationButtons[i];
        operationButtons[i]->setMargin(20,20);
    }

    /// ---- Egyenlő-gomb ----
    App.add( equalButton = new button(15, 320, 240, 50, "=") );
    equalButton->eventClick = equalButton_Click;
    equalButton->setMargin(20,20);
    equalButton->align = align_center;

    /// ---------------------
    App.run();

    return 0;
}
