/* 
    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.
*/

#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 0
#define BOX 1
#define STR 2
#define ELL 3
#define REC 4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.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>

struct Library *IntuitionBase,*GfxBase;
struct Library *EGSBase;
struct Library *EGSGfxBase;
struct Library *EGSIntuiBase;
struct Library *EGSRequestBase;
EG_RastPortPtr RP;
USHORT class;	/* Intu event class */
USHORT code;	/* Intu event code */
struct EI_EIntuiMsg *message;
LONG gfx_mode=GSP_GFX,demo_mode=LIN,fill_mode=NOFILL;
long width,height,palettesize=256;

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

int event(void);
void t_Task(void);
void LinesDemo(void);
void BoxDemo(void);
void RectDemo(void);
void TextDemo(void);
void CleanUp(void);
void TestText(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 main(int argc,char *argv[])
{
    int i=0;

    onbreak(CleanUp);

    if (OpenLibs())
    {
        if (argc == 0)
        {
            puts("usage : demo [box/rec[tangle]/lin[e]/tex[t]/ell[ipse]/are[aellipse]]");
        }
        if (strncmp(argv[1],"?",1)==0) {
            puts("usage : demo [box/rec[tangle]/lin[e]/tex[t]/ell[ipse]/are[aellipse]]");
            exit(0);
        }
    
        for (i=1;i<=argc;i++)  {
            if (strncmp(argv[i],"box",3)==0) demo_mode=BOX;
            if (strncmp(argv[i],"rec",3)==0) demo_mode=REC;
            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],"pat",3)==0) fill_mode|=PATTERN_F;
        }

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

    	chkabort();

        switch (demo_mode)
        {
            case BOX :
                BoxDemo();
                break;
            case STR :
                TextDemo();
                break;
            case ELL :
                EllipseDemo();
                break;
            case REC :
                RectDemo();
                break;
            default :
                LinesDemo();
                break;
        }
        CleanUp();
    }
}

void CleanUp(void)
{
    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;

	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);
		}
		if(win->UserPort->mp_SigBit)
		{
			message = (struct EI_EIntuiMsg *)GetMsg(win->UserPort);
			if(message != NULL)
			{   
				class = message->Class;
				code = message->Code;
				ReplyMsg((struct Message *)message);
			}
        }
	}while(event());
    CleanUp();
}
/* --------------------------------------------------------------------------------- */

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

void	BoxDemo(void)
{
	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));

    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);

		if(win->UserPort->mp_SigBit)
		{
			message = (struct EI_EIntuiMsg *)GetMsg(win->UserPort);
			if(message != NULL)
			{
				class = message->Class;
				code = message->Code;
				ReplyMsg((struct Message *)message);
			}
        }
	}while(event());
    CleanUp();
}

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

void __asm Rect(register __a0 EG_RastPortPtr rp,register __d0 x0,register __d1 y0, register __d2 x1, register __d3 y1)
{
    EG_Move(rp,x0,y0);
    EG_Draw(rp,x1,y0);
    EG_Draw(rp,x1,y1);
    EG_Draw(rp,x0,y1);
    EG_Draw(rp,x0,y0);
}

void RectDemo(void)
{
	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));

    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);
        Rect(rp,x,y,x+w,y+h);

		if(win->UserPort->mp_SigBit)
		{
			message = (struct EI_EIntuiMsg *)GetMsg(win->UserPort);
			if(message != NULL)
			{
				class = message->Class;
				code = message->Code;
				ReplyMsg((struct Message *)message);
			}
        }
	}while(event());
    CleanUp();
}

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

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

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

    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);

		if(win->UserPort->mp_SigBit)
		{
			message = (struct EI_EIntuiMsg *)GetMsg(win->UserPort);
			if(message != NULL)
			{
				class = message->Class;
				code = message->Code;
				ReplyMsg((struct Message *)message);
			}
        }
	 }while(event());
    CleanUp();
}

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

void 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));

    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);
        }

		if(win->UserPort->mp_SigBit)
		{
			message = (struct EI_EIntuiMsg *)GetMsg(win->UserPort);
			if(message != NULL)
			{
				class = message->Class;
				code = message->Code;
				ReplyMsg((struct Message *)message);
			}
        }
	}while(event());
    CleanUp();
}

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

int event(void)
{
    chkabort();
    switch(class)
	{
	case EI_iCLOSEWINDOW:
		return(0);
	case EI_iNEWSIZE:
        width  = (win->Width);
        height = (win->Height);
        palettesize = (1<<(win->RPort->Depth));
		return(1);
    }
	return(1);
}
