/*--------------------------------------------------------------
 *  File:           BMDEMO.C
 *  Description:    Demo the MPLUS Bar Menu.
 *
 *  Copyright (c) 1989  Michael Yam
 *-------------------------------------------------------------*/

#include <stdio.h>
#include <graph.h>
#include <math.h>

#include "gplus.h"
#include "gscreen.h"
#include "mouser.h"
#include "barmenu.h"

int dummy(), exitfun();
int memfun();
int mres(), hres(), eres(), vres();
int info(), demo1(), demo2();

void sinplot();
void setaxis();

char *bmtitle[] =
{
    "File",
    "System",
    "Video Mode",
    "Help",
    "",
};

char *bftitle[] = 
{
    "Save", "Load", "DOS", "Exit to system", "",
    "Memory", "",
    "Medium Res 4 Color", "Hi Res Black & White", "EGA", "VGA", "",
    "Info", "Demo 1", "Demo 2", "",
    "",
};

int (*funselect[])() =
{
    dummy, dummy, dummy, exitfun, NULL,
    memfun, NULL,
    mres, hres, eres, vres, NULL,
    info, demo1, demo2, NULL,
    NULL,
};

extern struct videoconfig _videoconfig;

/*--------------------------------------------------------------
 *  Function:       main
 *  Description:    demos the bar menu.
 *  Return value:   0 returned to parent process.
 *--------------------------------------------------------------*/
main()
{
    int ret;
    int (*funptr)();
    char ms_flag;

    /*      Try to set video mode to EGA
     */
    if( !setvideomode( _ERESCOLOR ) )
        if( !setvideomode( _HRESBW ) )
        {
            printf("\nUnrecognized video hardware.\n");
            exit(1);
        }

    bm_init( 1, 1, bmtitle, bftitle, funselect ); 
    bm_show( BLACK, CYAN, RED );

    ms_flag = ms_reset();
    ms_setevent(1);
    ms_showcursor();

    if( ms_flag == 0 )
    {
        gdialog( GDINFORM, GDOKAY );
        gdwrite( "No mouse detected but keyboard is\n" );
        gdwrite( "supported.  Press \"O\" to quit dialogue\n");
        gdwrite( "box, then press ALT+first letter of\n");
        gdwrite( "menu title.  See chapter 6.\n");
        gdprompt();
        gdclose();
    }

    funptr = NULL;

    while( funptr != exitfun || ret != 0)
    {
        funptr = bm_run( BLUE, WHITE );
        if ( funptr != NULL)
            ret = funptr();             /* execute selected function */
    }
    setvideomode( _DEFAULTMODE );
    ms_setevent(0);
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       dummy
 *  Description:    Dummy function to invoke from bar menu
 *  Return value:   0
 *--------------------------------------------------------------*/
int dummy()
{
    gdialog( GDINFORM, GDOKAY );
    gdwrite("Function not available.");
    gdprompt();
    gdclose();
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       exitfun
 *  Description:    quit this program
 *  Return value:   0
 *--------------------------------------------------------------*/
int exitfun()
{
    int i;

    gdialog( GDWARN, GDYESNO );
    gdwrite( "Quit bar menu demo?");
    i = gdprompt();
    gdclose();

    return i;
}
/*--------------------------------------------------------------
 *  Function:       memfun
 *  Description:    Display memory info to dialog box
 *  Return value:   0
 *--------------------------------------------------------------*/
int memfun()
{
    char buffer[41];

    gdialog( GDINFORM, GDOKAY );

    sprintf( buffer, "Memory available: %u bytes\n", _memavl() );
    gdwrite( buffer );
    sprintf( buffer, "Max contiguous block: %u bytes\n", _memmax() );
    gdwrite( buffer );

    gdprompt();
    gdclose();

    return 0;
}
/*--------------------------------------------------------------
 *  Function:       mres
 *  Description:    Set the screen to medium resolution, 4 color
 *  Return value:   0
 *--------------------------------------------------------------*/
int mres()
{
    char buffer[41];
    int i;

    gdialog( GDINFORM, GDOKCAN );
    gdwrite( "Reset mode to four color,\nmedium resolution?" );
    i = gdprompt();
    gdclose();

    if( i == 0 )
    {
        if( setvideomode( _MRES4COLOR ) == 0 )
        {
            gdialog( GDERROR, GDOKAY );
            gdwrite( "Video mode not supported by hardware." );
            gdprompt();
            gdclose();
        }
        else
        {
            _selectpalette(1);
            bm_init( 1, 1, bmtitle, bftitle, funselect );
            bm_show( 1, 2, 3 );
            ms_showcursor();
        }
    }
    
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       hres
 *  Description:    Set the screen to black and white hi res
 *  Return value:   0
 *--------------------------------------------------------------*/
int hres()
{
    char buffer[41];
    int i;

    gdialog( GDINFORM, GDOKCAN );
    gdwrite( "Reset mode to black and white,\nhigh resolution?" );
    i = gdprompt();
    gdclose();

    if( i == 0 )
    {
        if( setvideomode( _HRESBW ) == 0 )
        {
            gdialog( GDERROR, GDOKAY );
            gdwrite( "Video mode not supported by hardware." );
            gdprompt();
            gdclose();
        }
        else
        {
            bm_init( 1, 1, bmtitle, bftitle, funselect );
            bm_show( 0x00, 0x07, 0x07 );
            ms_showcursor();
        }
    }
    
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       eres
 *  Description:    Set the screen to ega, 16 color
 *  Return value:   0
 *--------------------------------------------------------------*/
int eres()
{
    char buffer[41];
    int i;

    gdialog( GDINFORM, GDOKCAN );
    gdwrite( "Reset mode to ega color?" );
    i = gdprompt();
    gdclose();

    if( i == 0 )
    {
        /*      Microsoft is weird.  If we go from VGA to EGA, we get
         *      43 line EGA.  Avoid this by going thru a graphics mode.
         */
        setvideomode( _MRES4COLOR );
        if( setvideomode( _ERESCOLOR ) == 0 )
        {
            gdialog( GDERROR, GDOKAY );
            gdwrite( "Video mode not supported by hardware." );
            gdprompt();
            gdclose();
        }
        else
        {
            bm_init( 1, 1, bmtitle, bftitle, funselect );
            bm_show( BLACK, CYAN, RED );
            ms_showcursor();
        }
    }
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       vres
 *  Description:    Set the screen to vga res 
 *  Return value:   0
 *--------------------------------------------------------------*/
int vres()
{
    char buffer[41];
    int i;

    gdialog( GDINFORM, GDOKCAN );
    gdwrite( "Reset mode to vga color?" );
    i = gdprompt();
    gdclose();

    if( i == 0 )
    {
        if( setvideomode( _VRES16COLOR ) == 0 )
        {
            gdialog( GDERROR, GDOKAY );
            gdwrite( "Video mode not supported by hardware." );
            gdprompt();
            gdclose();
        }
        else
        {
            bm_init( 1, 1, bmtitle, bftitle, funselect );
            bm_show( BLACK, CYAN, RED );
            ms_showcursor();
        }
    }
    
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       info
 *  Description:    info function invoked from bar menu
 *  Return value:   0
 *--------------------------------------------------------------*/
int info()
{
    int device;
    int ch;
    struct ms_status ms_status;
    GWDW *gwptr;

    if( _videoconfig.numtextcols <= 40 )
    {
        gdialog( GDINFORM, GDOKAY );
        gdwrite( "Please change to\n");
        gdwrite( "hi-res mode to\n");
        gdwrite( "view info." );
        gdprompt();
        gdclose();
        return 0;
    }

    gwptr = gwdwtopen( 5, 12, 17, 65, _GBORDER, BRIGHTWHITE, GREEN );
    if( (char *)gwptr == NULL )
    {
        gdialog( GDWARN, GDOKAY );
        gdwrite( "Insufficient memory.\n");
        gdwrite( "Set video mode to B/W Hi-res and\n");
        gdwrite( "try again." );
        gdprompt();
        gdclose();
        return 0;
    }
    outtext("         The MPLUS Graphic Interface Library\n", LIGHTYELLOW, -1);
    outtext("         Copyright 1989, 1990 by Michael Yam\n\n", LIGHTYELLOW, -1 );
    outtext("MPLUS is a user supported program.  If you find this\n", BRIGHTWHITE, -1);
    outtext("package useful, please register your copy by sending\n", BRIGHTWHITE, -1);
    outtext("thirty five dollars ($35) to:\n\n", BRIGHTWHITE, -1 );
    outtext("     Michael Yam\n", BRIGHTWHITE, -1 );
    outtext("     230 East 88th St.  #6B\n", BRIGHTWHITE, -1 );
    outtext("     New York, NY  10128\n\n", BRIGHTWHITE, -1 );
    outtext("Thank you for your support!   ", BRIGHTWHITE, -1 );
    outtext("Press a key...", BLACK, -1 );
    while(1)
    {
        device = dev_ready( &ch, &ms_status );
        if( device == _KB )
        {
            if( ch != 0 )
                break;
        }
        if( device == _MS )
        {
            if( ms_status.rbtn || ms_status.lbtn )
                break;
        }
    }
    gwdwclose( gwptr );
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       demo1
 *  Description:    plot a sine wave
 *  Return value:   0
 *--------------------------------------------------------------*/
int demo1()
{
    extern struct videoconfig _videoconfig;

    short fg, bg, highlite;
    int ch;
    int device;
    double pi;
    struct ms_status ms_status;
    GWDW *gwptr1;
    GWDW *gwptr2;

    /*      Although MPLUS is geared for EGA and VGA modes, try to
     *      accomodate low res graphics.
     */
    if( _videoconfig.mode == _MRES4COLOR )
    {
        _selectpalette(1);
        fg = 1;
        bg = 2;
        highlite = 3;
    }
    else if( _videoconfig.mode == _HRESBW )
    {
        fg = 7;
        bg = 0;
        highlite = 7;
    }
    else
    {
        fg = MAGENTA;
        bg = LIGHTYELLOW;
        highlite = BLUE;
    }

    pi = 3.141592654;
    gwptr1 = gwdwopen( 20, 20, 300, 150, _GBORDER, fg, bg );
    _setcolor( highlite );
    setaxis( gwptr1 );
    sinplot( -2*pi, 2*pi, 280, 50 );

    gwptr2 = gwdwtopen( 22, 1, 24, 40, _GFILLINTERIOR, bg, fg );
    outtext( "Press a key or mouse button...", highlite, -1 );

    while (1)
    {
        /*      Wait for keystroke or mouse buttons.
         */
        device = dev_ready( &ch, &ms_status );
        if( device == _MS )
        {
            if( ms_status.lbtn || ms_status.rbtn )
                break;
        }
        else if( device == _KB )
        {
            if( ch != 0 )
                break;
        }
    }
    gwdwclose( gwptr2 );
    gwdwclose( gwptr1 );
    return 0;
}
/*--------------------------------------------------------------
 *  Function:       sinplot
 *  Description:    plot a sine wave
 *  Return value:   none
 *--------------------------------------------------------------*/
void sinplot( range1, range2, xpixels, ysf )
double range1;
double range2;
short xpixels;                  /* x pixels available */
int ysf;                        /* y scale factor */
{
    int i;
    int cursor;
    double numperxpix;
    double xpixpernum;
    double x, y;

    cursor = ms_cursor();
    ms_hidecursor();
    numperxpix = (fabs(range2-range1))/(double)xpixels;
    xpixpernum = 1/numperxpix;

    /*      Calculate first point.  Position cursor with _moveto.
     *      Adjust sign for y axis.
     */
    x = range1;
    y = sin( x );
    _moveto( range1/numperxpix, -( y*ysf ) );

    for( i=1; i<xpixels; ++i)
    {
        x += numperxpix;
        y = sin( x );
        _lineto( x * xpixpernum, -(y*ysf) );
    }
    if( cursor )
        ms_showcursor();
}
/*--------------------------------------------------------------
 *  Function:       setaxis
 *  Description:    draw axis and set logical origin to center
 *                  of screen.
 *  Return value:   none
 *--------------------------------------------------------------*/
void setaxis( gwptr )
GWDW *gwptr;
{
    int cursor;
    short xctr, yctr;

    cursor = ms_cursor();
    ms_hidecursor();
    xctr = (gwptr->x2-gwptr->x1)/2;
    yctr = (gwptr->y2-gwptr->y1)/2;

    _moveto( xctr, 0 );
    _lineto( xctr, gwptr->y2-gwptr->y1 );
    _moveto( 0, yctr );
    _lineto( gwptr->x2-gwptr->x1, yctr );

    gwdwsetorg( gwptr, xctr, yctr );
    if( cursor )
        ms_showcursor();
}
/*--------------------------------------------------------------
 *  Function:       demo2
 *  Description:    
 *  Return value:   0
 *--------------------------------------------------------------*/
int demo2()
{
    gdialog( GDINFORM, GDOKAY );
    gdwrite("This is it.");
    gdprompt();
    gdclose();

    return 0;
}
/*-------------------------------------------------------------*
 *                      End of BMDEMO.C                        *
 *-------------------------------------------------------------*/
