
#include "appwin.h"
#include "ui/cntroler.h"
#include "ui/dialog.h"
#include "ui/pushbtn.h"

#include <fstream.h>




const long LOOP_COUNT = 10000000L;
enum {
    ID_LABEL     = 3,
    ID_CANCELBTN = 2
};


UI_ViewDescriptor ProgressDialogDesc[] = {
    {View_Label,      ID_LABEL,      50,  20, 200,  20, FALSE,  ""},
    {View_PushButton, ID_CANCELBTN, 110, 100,  80,  40, TRUE,  "Cancel"},
    {View_None, 0}
};

UI_DialogEventDescriptor fini [] = {
    {ID_CANCELBTN,  Event_Select},
    {-1,            Event_None}
};

class ProgressDialog: public UI_Dialog {

public:
    ProgressDialog (UI_CompositeVObject* parent)
    : UI_Dialog (parent, ProgressDialogDesc,
                 UI_Rectangle (100, 100, 300, 200), fini) {};

    bool WantToQuit () {return FALSE;};  // Cannot terminate it.
};



enum {
    ID_BUTTON1 = 11,
    ID_BUTTON2 = 12
};



UI_ViewDescriptor desc[] = {
    {View_PushButton, ID_BUTTON1, 100,  15, 100, 40, TRUE, ""},
    {View_PushButton, ID_BUTTON2,  50,  75, 200, 40, TRUE, ""},
    {View_None, 0}
};
    
AppWindow::AppWindow()
: UI_CompositeVObject (NULL, desc, FALSE, UI_Rectangle (50, 50, 300, 200))
{
    (*this)[ID_BUTTON1]->Title() = "Wait demo";
    (*this)[ID_BUTTON2]->Title() = "Progress dialog demo";
    _title                       = "YACL Wait/Progress Demo";
    _inProgressDemo              = 0;
}


bool AppWindow::HandleChildEvent (const UI_Event& e)
{
    if (e.Origin()->ViewID() == ID_BUTTON1 && e.Type() == Event_Select) {
        WaitDemo ();
        return TRUE;
    }

    if (e.Origin()->ViewID() == ID_BUTTON2 && e.Type() == Event_Select) {
        ProgressDialogDemo ();
        return TRUE;
    }

    return FALSE;
}


void AppWindow::ProgressDialogDemo ()
{
    ProgressDialog* progress = new ProgressDialog (this);
    _inProgressDemo++;
    progress->Title() = "Counting";
    for (long i = 0; i < LOOP_COUNT; i++) {
        // Dummy loop
        if (i % 100000 == 0) {
            (*progress)[ID_LABEL]->Title() = CL_String (i);
            // Must periodically check for pending events, for the "cancel"
            // button to take effect:
            _Controller->DispatchPendingEvents();
            if (progress->LastDialogEvent().id == ID_CANCELBTN)
                break;
        }
    }
    _inProgressDemo--;
    // And now suddenly, it becomes a modal dialog:
    (*progress)[ID_CANCELBTN]->Title() = "Ok";
    progress->ExecuteModal();
    _Application->Destroy (progress);
}

void AppWindow::WaitDemo ()
{
    ProgressDialog* progress = new ProgressDialog (this);
    progress->Title() = "Counting";
    UI_PushButton& btn = (UI_PushButton&) *((*progress)[ID_CANCELBTN]);
    btn.MakeInvisible();
    _Controller->BeginWait ();
    for (long i = 0; i < LOOP_COUNT; i++) {
        if (i % 100000 == 0)
            (*progress)[ID_LABEL]->Title() = CL_String (i);
    };
    _Controller->EndWait ();

    // And now suddenly, it becomes a modal dialog:
    btn.MakeVisible();
    btn.Title() = "Ok";
    progress->ExecuteModal();
    _Application->Destroy (progress);
}



bool AppWindow::WantToQuit ()
{
    return !_inProgressDemo;
}
