#include "application.h"
#include <fstream>

using namespace genv;
using namespace std;

int X = 0; int Y = 0;

/// ---------------------------------------- Konstansok ----------------------------------------------------------
const unsigned int t = 40;  // timer idõköze


/// ---------------------------------------- Függvények ----------------------------------------------------------
// Ablak törlése
void application::scrClear()
{
    colorize(BackgroundColor);
    gout << move_to(0,0) << box(X,Y);
}

// Általános billentyűvezérlés, gyorsbillentyűk
bool application::keyEvents(event &ev)
{
    if ( ev.keycode == key_tab )
        { next(); return true; }
    if ( ev.keycode == key_escape )
        { shutdownFlag = true; return true; }
    else if ( eventHotKeys(ev.keycode, keyControl, keyAlt) )
        return true;
    else if ( ev.keycode == key_lctrl || ev.keycode == key_rctrl )
        keyControl = true;
    else if ( ev.keycode == -key_lctrl || ev.keycode == -key_rctrl )
        keyControl = false;
    else if ( ev.keycode == key_lalt || ev.keycode == key_ralt )
        keyAlt = true;
    else if ( ev.keycode == -key_lalt || ev.keycode == -key_ralt )
        keyAlt = false;
    return false;
}

void application::shutdown()
    { shutdownFlag = true; }
/// ----------------------------------------------------------------------------------------------------------------



/// ---------------------------------------- Konstruktor / Destruktor ----------------------------------------------
void application::initApp(int X0, int Y0)
{
    X = X0; Y = Y0;
    gout.open(X,Y);
    tabIndex = 0;
    keyControl = false; keyAlt = false;
}

application::application(int X0, int Y0)
{
    initApp(X0, Y0);
    eventHotKeys = [] (char keyCode, bool Control, bool Alt) { return false; };
}

application::application(int X0, int Y0,std::function<bool(int, bool, bool)>f0)
{
    initApp(X0, Y0);
    eventHotKeys = f0;
}

application::~application()
{
    for( unsigned int i = 0; i < widgets.size(); i++ )
        delete widgets[i];
}
/// ----------------------------------------------------------------------------------------------------------------



/// ---------------------------------------- Bővítés ---------------------------------------------------------------
void application::add(widget *newWidget)
    { widgets.push_back(newWidget); }

group* application::newGroup()
{
    group* temp = new group(this);
    groups.push_back(temp);
    return temp;
}
/// ----------------------------------------------------------------------------------------------------------------



/// ---------------------------------------- Működés ---------------------------------------------------------------
 void application::run()
 {
    shutdownFlag = false;

    event ev;
    gin.timer(t);

    while ( gin >> ev && !shutdownFlag )
    {
        scrClear();

        // Általános billentyűparancsok kezelése (pl.: tab)
        if (ev.type == ev_key && keyEvents(ev)) continue;

        // Vezérlők kirajzolása
        for (unsigned int i = 0; i < widgets.size(); i++)
            widgets[i]->draw();

        // Ha több elemhez is eljutna az esemény, akkor csak a legfelső kapja meg, és az kerüljön fókuszba
        for (int i = widgets.size()-1; i >= 0; i--)
            if (widgets[i]->event(ev)) { setFocus(i); break; }

        gout << refresh;
    }
 }
/// ----------------------------------------------------------------------------------------------------------------



/// ---------------------------------------- Fókusz ---------------------------------------------------------------
void application::next()  // Fókusz továbbadása
{
    widgets[tabIndex]->focus = false;
    // Legközelebbi fókuszálható elem keresése
    while( !widgets[(++tabIndex %= widgets.size())]->tabStop )
        if (tabIndex > widgets.size() * 2) return;
    widgets[tabIndex]->focus = true;
}

bool application::setFocus(unsigned int newFocus)  // Fókusz állítása adott elemre
{
    if ( newFocus < 0 || widgets.size() <= newFocus || !widgets[newFocus]->tabStop ) return false; // Ha nem állítható az elemre fókusz
    widgets[tabIndex]->focus = false;
    widgets[newFocus]->focus = true;
    tabIndex = newFocus;
    return true;
}
/// ----------------------------------------------------------------------------------------------------------------

#include <sstream>

int convertI(std::string temp)
{
    int out;
    std::stringstream ss;
    ss << temp;
    ss >> out;
    return out;
}

float convertF(std::string temp)
{
    float out;
    std::stringstream ss;
    ss << temp;
    ss >> out;
    return out;
}







