

#include "ui/label.h"
#include "ui/menu.h"
#include "ui/strview.h"
#include "ui/stddlg.h"
#include "ui/applic.h"
#include "ui/dialog.h"

#include "box.h"


#define ID_APP1    10
#define ID_APPEND  20
#define ID_REMOVE  21
#define ID_QUIT    22
#define ID_EMPTY   25
#define ID_MODIFY  26
#define ID_SORT    28


#define ID_SINGLE_VIEW  200
#define ID_MULTI_VIEW   201


#define ID_SSEL_LBL    310
#define ID_MSEL_LBL    311

#define ID_DLGLABEL 31
#define ID_STRING   32



UI_MenuItemDescriptor AppMenu [] = {
  {"&Append item"       , ID_APPEND}
, {"&Remove selection"  , ID_REMOVE}
, {"&Make empty"        , ID_EMPTY }
, {"&Sort"              , ID_SORT  }
, {"M&odify..."         , ID_MODIFY}
, {UIMenu_Separator     , 0        }
, {"&Quit"              , ID_QUIT  }
, {NULL                            }
};



UI_MenuItemDescriptor MainMenuDesc [] = {
    {"&Action"  , ID_APP1, AppMenu}
  , {NULL       ,       0, NULL    }
};




static const char* cities[] = {
    "Chicago",        "New York",        "Atlanta",        "Bangalore",
    "Beijing",        "Bombay",          "Columbia",       "San Francisco",
    "Los Angeles",    "Copenhagen",      "Amsterdam",      "Berlin",
    "London",         "Bonn",            "Zurich",         "Vienna",
    "Brussels",
    0
};

static const char* moreCities [] = {
    "Madrid",         "Tokyo",           "Osaka",          "Manila", 
    "Santiago",       "Bogota",          "Rio",            "Paris",  
    "Barcelona",      "Athens",          "Budapest",       "Moscow",
    0
};



UI_ViewDescriptor dialogDesc[] = {
{View_Label,        ID_DLGLABEL, 10, 10,  70, 30, FALSE, "String:", NULL},
{View_StringEditor, ID_STRING,   80, 10, 100, 30, TRUE,  "",         NULL},
{View_PushButton,   UI_IDOK,     60, 50,  70, 30, TRUE, "Ok",       NULL},
{View_None,         0}
};

Box::Box ()
: UI_CompositeVObject (NULL, UI_Rectangle (100, 100, 480, 400)),
  _strseq (cities), _auxSet (moreCities)
{
    // Set the title
    Title() = "YACL Shared Model Demo";
    
    // Create the menu bar
    new UI_MenuBar (this, MainMenuDesc);

    // Create the two StringViews that share the model
    _singl = new UI_StringViewSingleSel
        (this, &_strseq, UI_Rectangle (40,  80, 130, 160), ID_SINGLE_VIEW);
    _multi = new UI_StringViewMultiSel
        (this, &_strseq, UI_Rectangle (200, 80, 130, 160), ID_MULTI_VIEW);

    // Create the two labels that show selections
    UI_Label* sl1 = new UI_Label (this, UI_Rectangle (40, 260, 150, 20),
                                  ID_SSEL_LBL);
    UI_Label* slm = new UI_Label (this, UI_Rectangle (200, 260, 150, 20),
                                  ID_MSEL_LBL);
    sl1->SetTextStyle (UIText_Left);
    slm->SetTextStyle (UIText_Left);

    // Create an informational label
    UI_Label* msg = new UI_Label (this, UI_Rectangle (10, 40, 400, 20));
    msg->Title() = "Two StringView objects with the same model:";

}


Box::~Box()
{
}


bool Box::HandleChildEvent (const UI_Event& e)
{
    if (e.Type() != Event_Select)
        return FALSE;
    switch (e.Origin()->ViewID()) {
    case ID_SINGLE_VIEW: // Single-select's selection changed
        (*this)[ID_SSEL_LBL]->Title() = "Selection: " +
            _singl->Selection().AsString();
        break;
        
    case ID_MULTI_VIEW:  // Multi-select's selection changed
        (*this)[ID_MSEL_LBL]->Title() = "Selection: " +
            _multi->Selection().AsString();
        break;

    case ID_MODIFY: {
        long n = _singl->Selection();
        if (n >= 0) {
            UI_Dialog* dlg = new UI_Dialog
                (this, dialogDesc, UI_Rectangle (30, 30, 200, 100));
            dlg->Title() = "Enter a string";
            if (dlg->ExecuteModal().id == UI_IDOK)
                _strseq[n] = (*dlg)[ID_STRING]->Model();
            YACLApp()->Destroy (dlg);
        }
        else
            UI_StandardDialog
                ("Please select a string to modify on left StringView",
                 "Info");
        break;
    }
        
    case ID_APPEND:
        // Append the largest item in the auxSet to the model
        if (_auxSet.Size())
            _strseq.Add (_auxSet.Remove (_auxSet.Largest()));
        else
            UI_StandardDialog ("Sorry, auxiliary set is empty", "Info");
        break;

    case ID_REMOVE: {
        // Remove the selection (if any) in the single select view and add
        // it to auxSet.
        long n = _singl->Selection();
        if (n >= 0) {
            _auxSet.Add (_strseq[n]);
            _strseq.Remove (n);
            // Clear out the selections of both StringViews:
            _singl->Selection() = -1;
            _multi->Selection().MakeEmpty();
            (*this)[ID_SSEL_LBL]->Title() = "";
            (*this)[ID_MSEL_LBL]->Title() = "";
        }
        else
            UI_StandardDialog
                ("Please select a string on left StringView", "Info");
        break;
    }

    case ID_EMPTY: {
        // Move all the strings in the sequence into the auxiliary set
        for (long i = _strseq.Size()-1; i >= 0; i--)
            _auxSet.Add (_strseq[i]);
        _strseq.MakeEmpty ();
        break;
    }
        
    case ID_SORT:
        _strseq.Sort();
        break;
        
    case ID_QUIT:
        YACLApp()->End();
        break;
    }
    return TRUE;
}

