/* 
    Demoprogram showing random objects drawn by the 
    graphics.library or/and my own gfx.library.

    name : demo.c
    path : daten:c_src/a2410
    author : jürgen schober
    date : 4.2.94 taken from the dev_con demo files 
    last change : 22.10.94

    Bugs : do not exactly know. But did never try AreaEllipse() in 
           amiga mode. I guess a temp_rast should be allocated.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <graphics/gfx.h>
#include <intuition/intuition.h>
#include <math.h>
#include <graphics/gfxmacros.h>
#include <egs/egs.h>
#include <egs/egsgfx.h>
#include <egs/egsintui.h>

#include <pragmas/egs_pragmas.h>
#include <pragmas/egsgfx_pragmas.h>
#include <pragmas/egsintui_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>

#include <clib/exec_protos.h>
#include <clib/egs_protos.h>
#include <clib/egsgfx_protos.h>
#include <clib/egsintui_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/alib_protos.h>

#define GSP_GFX   1
#define AMIGA_GFX 2

#define PATTERN_B 1 
#define FILL_B 2
#define PATTERN_F (1<<PATTERN_B)
#define FILL_F (1<<FILL_B)
#define NOFILL 0
#define NOPATTERN 0

#define LIN (1<<0)
#define BOX (1<<1)
#define STR (1<<2)
#define ELL (1<<3)

struct Library *IntuitionBase,*GfxBase;
struct Library *EGSBase;
struct Library *EGSGfxBase;
struct Library *EGSIntuiBase;
struct Library *EGSRequestBase;
struct Task *BoxTask = NULL, *TextTask = NULL, *EllipseTask = NULL, *LineTask = NULL;
EG_RastPortPtr RP;
USHORT class;	/* Intu event class */
USHORT code;	/* Intu event code */
struct EI_EIntuiMsg *message;
LONG gfx_mode=GSP_GFX,demo_mode = 0L,fill_mode=NOFILL;
long width,height,palettesize=256;
BOOL  out = FALSE, line_busy = FALSE, box_busy = FALSE, txt_busy = FALSE, ell_busy = FALSE;

/* =================================================================================== */

void LinesDemo(void);
void BoxDemo(void);
void TextDemo(void);
void CleanUp(void);
void EllipseDemo(void);

EI_WindowPtr win;
static struct EI_NewWindow nw = {
    100,50,600,400,
    50,50,800,600,
    NULL,
    EI_WINDOWCLOSE|EI_WINDOWBACK|EI_WINDOWDRAG|EI_WINDOWSIZE,
    NULL,
    "EGS-Fenster",
    EI_GIMMEZEROZERO|EI_SMART_REFRESH|EI_WINDOWACTIVE|EI_QUICKSCROLL,
    EI_iCLOSEWINDOW|EI_iNEWSIZE,
    NULL,
    {1,2,3,4,5,6,7},
    NULL,
    NULL
};

BOOL OpenLibs(void)
{
    EGSBase       = (struct Library *)OpenLibrary("egs.library",0L);
    EGSIntuiBase  = (struct Library *)OpenLibrary("egsintui.library",0L);
    EGSGfxBase    = (struct Library *)OpenLibrary("egsgfx.library",0L);

    if (EGSBase && EGSIntuiBase && EGSGfxBase)
        return(TRUE);

    return(FALSE);
}

void CloseLibs(void)
{
    if (EGSBase)        CloseLibrary(EGSBase);
    if (EGSIntuiBase)   CloseLibrary(EGSIntuiBase);
    if (EGSGfxBase)     CloseLibrary(EGSGfxBase);
}

void __saveds main(int argc,char *argv[])
{
    int i=0;
    ULONG sig,bits;

    onbreak(CleanUp);

    if (OpenLibs())
    {
        if (strncmp(argv[1],"?",1)==0) {
            puts("Demo (c)94 - js -");
            puts("Usage : Demo [BOX/LINe/TEXt/ELLipse/AREaellipse]");
            exit(0);
        }
    
        for (i=1;i<=argc;i++)  {
            if (strncmp(argv[i],"box",3)==0) demo_mode |= BOX;
            if (strncmp(argv[i],"tex",3)==0) demo_mode |= STR;
            if (strncmp(argv[i],"lin",3)==0) demo_mode |= LIN;
            if (strncmp(argv[i],"ell",3)==0) { demo_mode |= ELL; fill_mode=NOFILL; }
            if (strncmp(argv[i],"are",3)==0) { demo_mode |= ELL; fill_mode|=FILL_F; }
            if (strncmp(argv[i],"all",3)==0) demo_mode = LIN|BOX|STR|ELL;
        }
        if (!demo_mode) demo_mode = LIN;

        win = EI_OpenWindow(&nw);
        RP=win->RPort;

        if (demo_mode & BOX)
        {
            BoxTask = CreateTask("DemoBoxTask",0,BoxDemo,20000);
        }
        if (demo_mode & STR)
        {
            TextTask = CreateTask("DemoTextTask",0,TextDemo,20000);
        }
        if (demo_mode & ELL)
        {
            EllipseTask = CreateTask("DemoEllipseTask",0,EllipseDemo,20000);
        }
        if (demo_mode & LIN)
        {
            LineTask = CreateTask("DemoLinesTask",0,LinesDemo,20000);
        }
        sig = (1L<<win->UserPort->mp_SigBit);
        while (!out)
        {
            bits = Wait(sig | SIGBREAKF_CTRL_C);
            chkabort();
    		if (bits & sig)
	    	{
    			if (message = (struct EI_EIntuiMsg *)GetMsg(win->UserPort))
	    		{
    				class = message->Class;
			    	code  = message->Code;
		    		ReplyMsg((struct Message *)message);
                    switch(class)
                	{
                    	case EI_iCLOSEWINDOW:
                                out = TRUE;
                                break;
                    	case EI_iNEWSIZE:
                                Forbid();
                                width  = (win->Width);
                                height = (win->Height);
                                palettesize = (1<<(win->RPort->Depth));
                                Permit();
                                break;
                        default :
                                break;
                    }
	    		}
            }
        }
        CleanUp();
    }
}

void __saveds CleanUp(void)
{
    out = TRUE; // make sure tasks are Waiting on a CTRL-C
    while ((line_busy) || (box_busy) || (txt_busy) || (ell_busy)) ;

    Forbid();

    if (BoxTask)     DeleteTask(BoxTask);
    if (TextTask)    DeleteTask(TextTask);
    if (EllipseTask) DeleteTask(EllipseTask);
    if (LineTask)    DeleteTask(LineTask);

    Permit();
    if (win)    EI_CloseWindow(win);

    CloseLibs();
    exit(0);
}

void __saveds LinesDemo()
{
	int x1,y1,x2,y2;
	int x1v,y1v,x2v,y2v;
	int i,c;
    EG_RastPortPtr rp;
	
    rp=win->RPort;
    width=(win->Width);
    height=(win->Height);
    palettesize=(2<<(win->RPort->BitMap->Depth));

	c = 0;
	x1v = y1v = x2v = y2v = 0;
	x1 = x2 = width/2;
	y1 = y2 = height/2;

    line_busy = TRUE;
	do
	{
		c = ((c)%(palettesize-1))+1;
	
        EG_SetAPen(win->RPort,c);

		x1v = x1v/2 + (rand() & 15) - 7;
		y1v = y1v/2 + (rand() & 15) - 7;
		x2v = x2v/2 + (rand() & 15) - 7;
		y2v = y2v/2 + (rand() & 15) - 7;

		i = 100;

		while(i--)
		{
			x1 += x1v;
			y1 += y1v;
			x2 += x2v;
			y2 += y2v;

			if (x1 < 0)
				{
				x1 = - x1;
				x1v = - x1v;
				y1v += (rand() % 5) - 2;
				}

			if (y1 < 0)
				{
				y1 = - y1;
				y1v = - y1v;
				x1v += (rand() % 5) - 2;
				}

			if (x1 >= width)
				{
				x1 = 2*width - x1 - 2;
				x1v = - x1v;
				y1v += (rand() % 5) - 2;
				}

			if (y1 >= height)
				{
				y1 = 2*height - y1 - 2;
				y1v = -y1v;
				x1v += (rand() % 5) - 2;
				}

			if (x2 < 0)
				{
				x2 = - x2;
				x2v = - x2v;
				y2v += (rand() % 5) - 2;
				}

			if (y2 < 0)
				{
				y2 = - y2;
				y2v = - y2v;
				x2v += (rand() % 5) - 2;
				}

			if (x2 >= width)
				{
				x2 = 2*width - x2 - 2;
				x2v = - x2v;
				y2v += (rand() % 5) - 2;
				}

			if (y2 >= height)
				{
				y2 = 2*height - y2 - 2;
				y2v = - y2v;
				x2v += (rand() % 5) - 2;
				}

            EG_Move(win->RPort,x1,y1);
            EG_Draw(win->RPort,x2,y2);
		}

        chkabort();
	} while (!out);
    line_busy = FALSE;
    Wait(0L);
}
/* --------------------------------------------------------------------------------- */

/* ------------------------------------------------------------------------------- */

void __saveds BoxDemo()
{
	int x,y,w,h,col;
    EG_RastPortPtr rp;
    USHORT areaptrn[] = { 0xf0f0, /*0*/ 0x0f0f, /*1*/ 0xf0f0, 0xf0f0, /*2*/ 0x0f0f, 0x0f0f, 0xf0f0, 0xf0f0,/*3*/
                          0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF /*4*/ };

    rp=win->RPort;
    width=(win->Width);
    height=(win->Height);
    palettesize=(2<<(win->RPort->BitMap->Depth));

    box_busy = TRUE;
    do
	{
		w = rand() % (width-1)+1;
		h = rand() % (height-1)+1;
		x = rand() % (width-w);
		y = rand() % (height-h);
		col = rand() % palettesize;

        EG_SetAPen(rp,col);

        EG_RectFill(rp,x,y,x+w,y+h);

        chkabort();
	} while (!out);
    box_busy = FALSE;
    Wait(0L);
}

/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */

void __saveds TextDemo(void)
{
	int x,y,col;
    EG_RastPortPtr rp;

    rp=win->RPort;
    width=(win->Width);
    height=(win->Height);
    palettesize=(2<<(win->RPort->BitMap->Depth));

    txt_busy = TRUE;
    do
	{
		x = rand() % (width);
		y = rand() % (height);
		col = rand() % palettesize;

        EG_SetAPen(rp,col);
        EG_Move(rp,x,y);
        EG_Text(rp,"Text Demo",9);

        chkabort();
    } while (!out);
    txt_busy = FALSE;
    Wait(0L);
}

/* ------------------------------------------------------------------------------- */
/* ------------------------------------------------------------------------------- */

void __saveds EllipseDemo()
{
	int x,y,w,h,col;
    EG_RastPortPtr rp;
    USHORT areaptrn[] = { 0xf0f0, /*0*/ 0x0f0f, /*1*/ 0xf0f0, 0xf0f0, /*2*/ 0x0f0f, 0x0f0f, 0xf0f0, 0xf0f0,/*3*/
                          0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF /*4*/ };

    rp=win->RPort;
    width=(win->Width);
    height=(win->Height);
    palettesize=(2<<(win->RPort->BitMap->Depth));

    ell_busy = TRUE;
    do
	{
		w = rand() % (width/2);
		h = rand() % (height/2);
		x = rand() % (width);
		y = rand() % (height);
		col = rand() % palettesize;

        EG_SetAPen(rp,col);

        if (fill_mode&FILL_F) 
        {
            EG_AreaCircle(rp,x,y,w);
        }
        else
        {
            EG_Ellipse(rp,x,y,w,h);
        }
        chkabort();
	} while (!out);
    ell_busy = FALSE;
    Wait(0L);
}

/* ------------------------------------------------------------------------------- */
