#ifdef USE_WX
#include <wx/wx.h>
#include <wx/image.h>
#include <wx/sizer.h>
#endif

#include "eval.h"
#include "parserVar.h"

#include <vector>

#include "watch2.h"

using namespace std;

volatile bool stop=false;

// Private

extern bool customSettings;
extern setting_file *sett;
void CleanAll();

#ifdef USE_WX
wxBitmap *seg_horz0;
wxBitmap *seg_horz1;
wxBitmap *seg_vert0;
wxBitmap *seg_vert1;
wxBitmap *bmp_2pt;

wxStaticBitmap *seg1[6][7], *seg0[6][7];
bool val_seg[6][7];

vector<wxFlexGridSizer *> sseg;

#ifdef SIM_C
int main(int argc, char **argv){
   return wxEntry(argc, argv);
}
#endif

class MyApp: public wxApp{
    virtual bool OnInit();
};

IMPLEMENT_APP_NO_MAIN(MyApp)

class MyFrame: public wxFrame{
public:

    MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size);

    void OnClose(wxCloseEvent& event);

    DECLARE_EVENT_TABLE()
};

enum{
    ID_Quit = 1,
    ID_About,
};

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_CLOSE(MyFrame::OnClose)
END_EVENT_TABLE()


bool MyApp::OnInit(){
    MyFrame *frame = new MyFrame( _("Simulateur - Watch2"), wxPoint(50, 50),
                                  wxSize(1600,512) );
    wxInitAllImageHandlers();
    frame->Show(true);
    SetTopWindow(frame);

    Eval();

#ifndef SIM_C
	if(customSettings){
		sett->close();
	}

	CleanAll();
#endif

    return false;
}

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
: wxFrame( NULL, -1, title, pos, size )
{
    SetBackgroundColour(*wxBLACK);

    wxBoxSizer *sizerV = new wxBoxSizer(wxVERTICAL);
    wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);

    seg_horz0 = new wxBitmap(_T("img/seg_horz0.bmp"),wxBITMAP_TYPE_BMP);
    seg_horz1 = new wxBitmap(_T("img/seg_horz1.bmp"),wxBITMAP_TYPE_BMP);
    seg_vert0 = new wxBitmap(_T("img/seg_vert0.bmp"),wxBITMAP_TYPE_BMP);
    seg_vert1 = new wxBitmap(_T("img/seg_vert1.bmp"),wxBITMAP_TYPE_BMP);
    bmp_2pt = new wxBitmap(_T("img/2pt.bmp"),wxBITMAP_TYPE_BMP);


    sizer->Add(1,1,1,wxEXPAND);

    for(short i=0;i<6;i++){
        sseg.push_back(new wxFlexGridSizer(1,3,0,0));

        seg1[i][0] = new wxStaticBitmap(this,-1,*seg_horz1);
        seg1[i][1] = new wxStaticBitmap(this,-1,*seg_vert1);
        seg1[i][2] = new wxStaticBitmap(this,-1,*seg_vert1);
        seg1[i][3] = new wxStaticBitmap(this,-1,*seg_horz1);
        seg1[i][4] = new wxStaticBitmap(this,-1,*seg_vert1);
        seg1[i][5] = new wxStaticBitmap(this,-1,*seg_vert1);
        seg1[i][6] = new wxStaticBitmap(this,-1,*seg_horz1);

        seg0[i][0] = new wxStaticBitmap(this,-1,*seg_horz0);
        seg0[i][1] = new wxStaticBitmap(this,-1,*seg_vert0);
        seg0[i][2] = new wxStaticBitmap(this,-1,*seg_vert0);
        seg0[i][3] = new wxStaticBitmap(this,-1,*seg_horz0);
        seg0[i][4] = new wxStaticBitmap(this,-1,*seg_vert0);
        seg0[i][5] = new wxStaticBitmap(this,-1,*seg_vert0);
        seg0[i][6] = new wxStaticBitmap(this,-1,*seg_horz0);

        for(short j=0;j<7;j++){
            val_seg[i][j] = true;
            seg0[i][j]->Hide();
            seg1[i][j]->Show();
        }

        sseg[i]->Add(16,16);
        sseg[i]->Add(seg1[i][0],0,wxEXPAND);
        sseg[i]->Add(16,16);
        sseg[i]->Add(seg1[i][5],0,wxEXPAND);
        sseg[i]->Add(64,64);
        sseg[i]->Add(seg1[i][1],0,wxEXPAND);
        sseg[i]->Add(16,16);
        sseg[i]->Add(seg1[i][6],0,wxEXPAND);
        sseg[i]->Add(16,16);
        sseg[i]->Add(seg1[i][4],0,wxEXPAND);
        sseg[i]->Add(64,64);
        sseg[i]->Add(seg1[i][2],0,wxEXPAND);
        sseg[i]->Add(16,16);
        sseg[i]->Add(seg1[i][3],0,wxEXPAND);
        sseg[i]->Add(16,16);

        sizer->Add(sseg[i],0,wxEXPAND);

        if(i==1 || i==3){
            sizer->Add(new wxStaticBitmap(this,-1,*bmp_2pt),0,wxEXPAND);
        }
    }

    sizer->Add(1,1,1,wxEXPAND);

    sizerV->Add(1,1,1,wxEXPAND);
    sizerV->Add(sizer,0,wxEXPAND);
    sizerV->Add(1,1,1,wxEXPAND);

    SetSizer(sizerV);

    ShowFullScreen(true);

    wxSafeYield();
    wxSafeYield();
}


void MyFrame::OnClose(wxCloseEvent& event){
    stop = true;

    delete seg_horz0;
    delete seg_horz1;
    delete seg_vert0;
    delete seg_vert1;
    delete bmp_2pt;

    this->Destroy();
}

#endif

// Public

/**
 * @arg n : digit number (0 : hours tens - 5 : seconds units)
 * @arg k : segment number (0-6)
 * @return true : when change
 **/
bool Watch2ChangeSeg(short n, short k, bool val){
#ifdef USE_WX
    if(val==val_seg[n][k])return false;

    if(val){
        sseg[n]->Replace(seg0[n][k],seg1[n][k]);
        seg0[n][k]->Hide();
        seg1[n][k]->Show();
    }else{
        sseg[n]->Replace(seg1[n][k],seg0[n][k]);
        seg1[n][k]->Hide();
        seg0[n][k]->Show();
    }

    val_seg[n][k]=val;

    return true;
#endif
}

/**
 * Function called to update interface
 * WARNING : it's very important to call it
 * @return true when you have to stop
 **/
bool Watch2Update(){
#ifdef USE_WX
	if(!stop){
	    wxGetApp().Yield();
	    if(stop){
	        return true;
	    }
	}else{
	    return true;
	}
	return false;
#endif
}

