#include "scrnio.ih"
#ifdef MANX
#include <functions.h>
#endif

#include "scrndef.h"
#include "scrnio.h"
#include "gadgetdef.h"
#include "menudef.h"

#include "bezpt.h"
#include "revolve.h"
#include "control.h"
#include "poly.h"


long BackColor = DefBkPlane;
short DitherMask = 7;

void SetMono( maxrval, maxgval, maxbval )
    short maxrval,
          maxgval,
          maxbval;
{
    long i;
    short range;
    long rval, gval, bval;

    range = (NumColors -1) & 0x1f;  /* max 32 colours */
    for( i = 0; i <= range; i++ ) {
        rval = (maxrval * i )/range;
        gval = (maxgval * i )/range;
        bval = (maxbval * i )/range;

        SetRGB4( &(SurfScrn->ViewPort),  i, rval, gval, bval );
    }
}


void SetRainbow()
{
    long i;
    short range;
    long rval, gval, bval;

    range = NumColors>> 1;
    /*
     * can't do a rainbow with only 2 colors
     */
    if( range < 2) {
        return;
    }

    for( i = 0; i < range; i++ ) {
        long diff;

        diff = (0xf * i )/(range-1);
        rval = 0xf - diff;
        bval = diff;
        gval = 0xf;
        SetRGB4( &(SurfScrn->ViewPort), i, rval, gval, bval);
    }
    for( i = 0; i < range; i++ ) {
        long diff;

        diff = (0xf * i )/(range-1);
        rval = diff;
        bval = 0xf;
        gval = 0xf - diff;
        SetRGB4( &(SurfScrn->ViewPort), i+range, rval, gval, bval);
    }
    SetRGB4( &(SurfScrn->ViewPort), 0L, 0L, 0L, 0L);
}

/*
 * set colours for hourglass pointer
 */
SetHourGlassCol()
{
    SetRGB4( &(SurfScrn->ViewPort),17L, 6L, 2L, 3L );
    SetRGB4( &(SurfScrn->ViewPort),18L, 0L, 0L, 0L );
    SetRGB4( &(SurfScrn->ViewPort),19L, 9L, 7L, 6L );
}



void ClrWindow(drawaxis)
bool drawaxis;
{
    long BkColAdj; /* background color adjusted for number of bit planes */

    BkColAdj = (BackColor * NumColors) / 32;
    SetRast(rp, BackColor);  /* clear the window to colour 0 */
    SetAPen(rp, WinFgCol );
    /*
     * Draw axis on screen
     */
    if( drawaxis) {
        Move( rp, 0, WinVOrig);    /* x axis */
        Draw( rp, (long)SurfWinDef.Width, (long)WinVOrig );

        Move( rp, WinHOrig, 0);     /* y axis */
        Draw( rp, (long)WinHOrig, (long)SurfWinDef.Height );
    }
}





void DrawLine( x1, y1, x2, y2, mode )
int x1, y1, x2, y2;
int mode;
{
    SetDrMd( rp, mode );
    Move( rp, (long)UCntrX(x1), (long)UCntrY(y1));
    Draw(rp, (long)UCntrX(x2), (long)UCntrY(y2) );
}



void PaintPoint(x,y,forecolor)
    short x, y;
    float forecolor;
{
    long shade;
    shade = forecolor * (NumColors-1);

    if( shade >= NumColors) {
        shade = NumColors-1;
    }
    else if ( shade < 0 ) {
        shade = 0;
    }

    SetAPen( rp, shade );
    WritePixel( rp, (long)UCntrX(x), (long)UCntrY(y));
}



void DrawPnt( x, y, op )
int x, y, op;
{
    x = UCntrX(x);
    y = UCntrY(y);
    SetDrMd(rp, op );
    RectFill( rp, (long)x, (long)y, (long)x, (long)y);
}


void DrawSqr(x, y, op )
int x, y, op;
{
    x = UCntrX(x);
    y = UCntrY(y);
    SetDrMd(rp, op );
    RectFill( rp, x - 2L, y -2L, x+ 2L, y+2L );
}


void DrawRhomShade( poly)
Rhomboid *poly;
{
    int i;
    int shade;
    long backcolor, forecolor;


    shade = (int)((poly->intensity) * ColorMax);
    if( shade > ColorMax) {
        shade = ColorMax;
    }

    backcolor = shade >> 3;
    forecolor = backcolor +1;
    if( forecolor >= NumColors ) {
        forecolor = backcolor;
    }

    SetDrMd( rp, JAM2);
    SetAPen( rp, forecolor );
    SetBPen( rp, backcolor );
    SetAfPt( rp, GrayPat[ shade & DitherMask ], 2);

    AreaMove( rp, UCntrX(poly->pt[0].x), UCntrY(poly->pt[0].y));

    for( i = 1; i < 4; i++ ) {
        AreaDraw( rp, UCntrX(poly->pt[i].x), UCntrY(poly->pt[i].y) );
    }
    AreaEnd(rp);

    SetAfPt( rp, GrayPat[8], 2);  /* reset back to solid */

}

void DrawRhomFrame( inlist )
ScrnPair inlist[];
{
    int i;

    SetDrMd( rp, JAM1);
    SetAPen( rp, 0L );
    SetOPen( rp, WinFgCol );

    AreaMove( rp, UCntrX(inlist[0].x), UCntrY(inlist[0].y));

    for( i = 1; i < 4; i++ ) {
        AreaDraw( rp, UCntrX(inlist[i].x), UCntrY(inlist[i].y) );
    }
    AreaEnd(rp);
    BNDRYOFF( rp ); /* turn off outlining */
}




SwitchBox()
{
    struct IntuiMessage mycopy,
                        *orig;

    RefreshGadgets(SurfWinDef.FirstGadget, SurfWin, NULL );

    while(1) {
        long wakeupmask;

        wakeupmask = Wait( SignalMask );
        /*
         * for now, we ignore the wakeupmask,
         * just read messages from each. if I notice a performance problem,
         * I'll fix it then
         */

        /*
         * handle messages for the control window
         */
        while( orig =(struct IntuiMessage *) GetMsg( CntrlWin->UserPort ) ) {

            mycopy = *orig;
            ReplyMsg( orig );

            switch( mycopy.Class ) {
                case MENUPICK:
                    MenuHandler( mycopy.Code );
                    break;

                case GADGETUP:
                    GadgetHandler( (struct Gadget*)mycopy.IAddress );
                    break;

                case CLOSEWINDOW:
                    return;

                default:
                    break;
            }
        }
        /*
         * handle the button window
         */
        while( orig =(struct IntuiMessage *) GetMsg( GadWin->UserPort ) ) {

            mycopy = *orig;
            ReplyMsg( orig );

            switch( mycopy.Class ) {
                case GADGETUP:
                    GadgetHandler( (struct Gadget*)mycopy.IAddress );
                    RefreshGadgets(SurfWinDef.FirstGadget, SurfWin, NULL );
                    break;

                default:
                    break;
            }
        }

        /*
         * handle messages for the other window
         */
        while( orig =(struct IntuiMessage *) GetMsg( SurfWin->UserPort ) ) {

            mycopy = *orig;
            ReplyMsg( orig );

            switch( mycopy.Class ) {
                case MOUSEBUTTONS:
                    HandleMButtons(&mycopy);
                    break;

                case INTUITICKS:
                    HandleTicks(&mycopy);
                    break;

                case MOUSEMOVE:
                    break;

                default:
                    break;
            }
        }
    }
}

/*
 * display error messages inside a requestor
 */
OutErr(errstr)
    char *errstr;
{
    static struct IntuiText errtext =
        { -1, -1, JAM1, 10, 10, NULL, NULL, NULL };
    static struct IntuiText negtext =
        { -1, -1, JAM1, 80, 20, NULL,(UBYTE *)"Onwards", NULL };

    errtext.IText = (UBYTE *)errstr;

    WBenchToFront();
    AutoRequest(CntrlWin, &errtext, NULL, &negtext, NULL, NULL,
        8*strlen(errstr)+ 40, 60 );
    WindowToFront( CntrlWin );

}

