/*****************************************************************************
 *
 * Demonstration of a main menu bar containing members that send commands
 *   instead of further drop down menus.
 *
 *
 * The way the menus are constructed in reality looks like this:
 *
 *    TMenuBar -> TMenu -> TMenuItem  { -> TMenu -> TMenuItem ... }
 *                             |
 *                         TMenuItem  { -> TMenu -> TMenuItem ... }
 *                             |
 *                         TMenuItem  { -> TMenu -> TMenuItem ... }
 *                             |
 *                            ...
 *
 * The vertical column of TMenuItems (above) is the main menu bar.  If
 * there is a drop down menu bar for a given label, then the information
 * in the curly bracket's applies, and further submenus may be instantiated
 * in more nested TMenu objects.
 *
 * For a coded example of the above structure, see the initMenuBar()
 * function in this program.
 *
 *****************************************************************************/

#define Uses_TKeys
#define Uses_TRect
#define Uses_TEvent
#define Uses_TMenu
#define Uses_TMenuBar
#define Uses_TMenuItem
#define Uses_TApplication
#define Uses_MsgBox
#include <tv.h>                 // TV header file

#include <string.h>

const int cmOne = 110;          // Commands sent by various menu items
const int cmTwoA = 120;
const int cmTwoB = 121;
const int cmThree = 130;
const int cmFourA = 140;
const int cmFourB = 141;

class testApp : public TApplication         // Application class
{

public:

    testApp() : TProgInit( &testApp::initStatusLine,
                           &testApp::initMenuBar,
                           &testApp::initDeskTop ) { }
    static TMenuBar *initMenuBar( TRect r );
    void handleEvent( TEvent& event );

};


TMenuBar *testApp::initMenuBar( TRect r )
{
    r.b.y =  r.a.y + 1;

//
// The individual menus are created as a sequence TMenuItems, each taking
// a pointer to the previous as the last parameter in the constructor.
// The drop down portions are created with nested calls to the new operator
// for a TMenu, then for the sub menu items.
//
    TMenuItem *four =
        new TMenuItem( "~F~our", 0,
            new TMenu(
                *new TMenuItem( "Four A", cmFourA, kbNoKey, hcNoContext, 0,
                 new TMenuItem( "Four B", cmFourB, kbNoKey )
            )));

    TMenuItem *three =
        new TMenuItem( "~T~hree", cmThree, kbNoKey, hcNoContext, 0, four );

    TMenuItem *two =
        new TMenuItem( "~T~wo", 0,
            new TMenu(
                *new TMenuItem( "Two A", cmTwoA, kbNoKey, hcNoContext, 0,
                 new TMenuItem( "Two B", cmTwoB, kbNoKey )
            )),
            hcNoContext, three);

    TMenuItem *one =
        new TMenuItem( "~O~ne", cmOne, kbNoKey, hcNoContext, 0, two );

//
// Finally, we collect the list into one final TMenu object and pass that
// to TMenuBar, which we return to the application.
//
    return new TMenuBar( r, new TMenu( *one ) );
}


void testApp::handleEvent( TEvent& event )
{
    static char buffer[80] = "Received message ";

    TApplication::handleEvent(event);

    if( event.what == evCommand )
    {
        switch( event.message.command )
        {
        case cmOne:
            strcpy(&buffer[17], "cmOne.   ");
            break;
        case cmTwoA:
            strcpy(&buffer[17], "cmTwo A. ");
            break;
        case cmTwoB:
            strcpy(&buffer[17], "cmTwo B. ");
            break;
        case cmThree:
            strcpy(&buffer[17], "cmThree. ");
            break;
        case cmFourA:
            strcpy(&buffer[17], "cmFour A.");
            break;
        case cmFourB:
            strcpy(&buffer[17], "cmFour B.");
            break;
        default:
            return;
        }
        messageBox( buffer, mfOKButton | mfInformation );
        clearEvent( event );
    }
}


void main(void)
{
    testApp lessonTwo;

    lessonTwo.run();
}
