/* 
    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 <a2410/typedefs.h>
#include <a2410/devtiga.h>
#include <a2410/ti_function_nums.h> 
#include <exec/types.h>
#include <dos/dos.h>
#include <exec/memory.h>
#include <graphics/gfx.h>
#include <intuition/intuition.h>
#include <math.h>
#include <graphics/gfxmacros.h>

#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/alib_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>

#include "tiga_macros.h"
#include "gfx_pragmas.h"
#include "graphics.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=NULL;
struct Library *GraphicsBase,*DiskfontBase;
struct Window *win;
struct Task *BoxTask = NULL, *TextTask = NULL, *EllipseTask = NULL, *LineTask = NULL;
struct RastPort *RP;
USHORT class;	/* Intu event class */
USHORT code;	/* Intu event code */
struct IntuiMessage *message;
CONFIG	config;
LONG gfx_mode=AMIGA_GFX,demo_mode=0L,fill_mode=NOFILL;
BOOL  out = FALSE, line_busy = FALSE, box_busy = FALSE, txt_busy = FALSE, ell_busy = FALSE;


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

int event(void);
void t_Task(void);
void LinesDemo(void);
void BoxDemo(void);
void TextDemo(void);
void CleanUp(void);
void TestText(void);
void EllipseDemo(void);

void main(int argc,char *argv[])
{
    int i=0;
    ULONG sig,bits;
    POINT pt[]={{100,100},{1000,500},{300,700},{1000,1000},{100,800},{50,500}};
    WORD *area;
    UBYTE strg[]="Hallo, Tiga scrolling Demo,....";

    onbreak(CleanUp);

    if (strncmp(argv[1],"?",1)==0) {
        puts("demo of gsp_gfx.library, (c)94 - js -");
        puts("usage : demo [TIGa] [PATtern] [BOX/LINe/TEXt/ELLipse/AREaellipse]");
        puts("tiga  : use Tiga - default = amiga");
        puts("pattern : use pattern    - default = nopattern");
        puts("box     : box/lines-demo - default = lines");
        exit(0);
    }
    
    for (i=1;i<=argc;i++)  {
        if (strncmp(argv[i],"tig",3)==0) gfx_mode=GSP_GFX;
        if (strncmp(argv[i],"ami",3)==0) gfx_mode=AMIGA_GFX;
        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],"pat",3)==0) fill_mode|=PATTERN_F;
    }
    if (!demo_mode) demo_mode = LIN;


    if (gfx_mode != AMIGA_GFX)
        if ((GraphicsBase=(struct Library *)OpenLibrary("gfx.library",0L))==NULL)
        {
            puts("could not open gfx.library ...");
            return;
        }
    if ((DiskfontBase=(struct Library *)OpenLibrary("diskfont.library",0L))==NULL)
    {
        puts("could not open diskfont.library ...");
        return;
    }
    if ((GfxBase=(struct Library *)OpenLibrary("graphics.library",0L))==NULL)
    {
        puts("could not open graphics.library ...");
        return;
    }
    if ((IntuitionBase=(struct Library *)OpenLibrary("intuition.library",0L))==NULL)
    {
         puts("could not open intuition.library ...");
         return;
    }
    win=(struct Window *)OpenWindowTags(NULL,
                        WA_Title,"My GfxDemo",
//                        WA_Backdrop,TRUE,
                        WA_AutoAdjust,TRUE,
                        WA_Left,50,
                        WA_Top,50,
                        WA_Width,640,
                        WA_Height,480,
                        WA_MaxWidth,2000,
                        WA_MaxHeight,2000,
                        WA_MinWidth,10,
                        WA_MinHeight,10,
                        WA_DepthGadget,TRUE,
                        WA_CloseGadget,TRUE,
                        WA_SizeGadget,TRUE,
                        WA_DragBar,TRUE,
                        WA_IDCMP,IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE,
                        WA_GimmeZeroZero,TRUE,
                        TAG_DONE);

    RP=win->RPort;

	chkabort();
    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 IntuiMessage *)GetMsg(win->UserPort))
   	    	{
    			class = message->Class;
	        	code  = message->Code;
    	    	ReplyMsg((struct Message *)message);
                switch(class)
		    	{
   			    	case CLOSEWINDOW:
                        out = TRUE;
                        break;
		    	    case NEWSIZE:
                        Forbid();
                        config.mode.disp_hres=(win->Width);
                        config.mode.disp_vres=(win->Height);
                        config.mode.palet_size=(2<<(win->RPort->BitMap->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();

    SetDrPt(RP,0xFFFF);
    RP->Flags|=(AREAOUTLINE);  // Outline löschen
    if (win)           CloseWindow(win);
    if (GfxBase)       CloseLibrary(GfxBase);
    if (GraphicsBase)  CloseLibrary(GraphicsBase);
    if (IntuitionBase) CloseLibrary(IntuitionBase);
    if (DiskfontBase)  CloseLibrary(DiskfontBase);

    exit(0);
}

void __saveds LinesDemo()
{
	int x1,y1,x2,y2;
	int x1v,y1v,x2v,y2v;
	int i,c;
    struct RastPort *my_rport;
	
    my_rport=win->RPort;
    config.mode.disp_hres=(win->Width);
    config.mode.disp_vres=(win->Height);
    config.mode.palet_size=(2<<(win->RPort->BitMap->Depth));

	c = 0;
	x1v = y1v = x2v = y2v = 0;
	x1 = x2 = config.mode.disp_hres/2;
	y1 = y2 = config.mode.disp_vres/2;

    if (fill_mode&PATTERN_F) 
        SetDrPt(my_rport,0xf0f0);

    line_busy = TRUE;
	do
	{

		c = ((c)%(config.mode.palet_size-1))+1;
	
        SetAPen(my_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 >= config.mode.disp_hres)
				{
				x1 = 2*config.mode.disp_hres - x1 - 2;
				x1v = - x1v;
				y1v += (rand() % 5) - 2;
				}

			if (y1 >= config.mode.disp_vres)
				{
				y1 = 2*config.mode.disp_vres - 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 >= config.mode.disp_hres)
				{
				x2 = 2*config.mode.disp_hres - x2 - 2;
				x2v = - x2v;
				y2v += (rand() % 5) - 2;
				}

			if (y2 >= config.mode.disp_vres)
				{
				y2 = 2*config.mode.disp_vres - y2 - 2;
				y2v = - y2v;
				x2v += (rand() % 5) - 2;
				}

            Move(my_rport,x1,y1);

            if (gfx_mode==GSP_GFX)
                GfxDraw(my_rport,x2,y2);
            else
                Draw(my_rport,x2,y2);
		}
	}while(!out);
    line_busy = FALSE;
    Wait(0L);
}
/* --------------------------------------------------------------------------------- */

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

void __saveds BoxDemo()
{
	int x,y,w,h,col;
    struct RastPort *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;
    config.mode.disp_hres=(win->Width);
    config.mode.disp_vres=(win->Height);
    config.mode.palet_size=(2<<(win->RPort->BitMap->Depth));

    SetDrPt(rp,0xF0F0);

    if (fill_mode&PATTERN_F) 
        {SetAfPt(rp,areaptrn,1);}
    else 
        SetAfPt(rp,NULL,1);

    rp->Flags&=(~AREAOUTLINE);  // Outline löschen
    box_busy = TRUE;
    do
	{
		w = rand() % (config.mode.disp_hres-1)+1;
		h = rand() % (config.mode.disp_vres-1)+1;
		x = rand() % (config.mode.disp_hres-w);
		y = rand() % (config.mode.disp_vres-h);
		col = rand() % config.mode.palet_size;

        SetAPen(rp,col);

        if (gfx_mode==GSP_GFX)
            GfxRectFill(rp,x+w,y,x,y+h);
        else
            RectFill(rp,x,y,x+w,y+h);

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

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

void __saveds TextDemo(void)
{
	int x,y,col;
    struct RastPort *rp;

    rp=win->RPort;
    config.mode.disp_hres=(win->Width);
    config.mode.disp_vres=(win->Height);
    config.mode.palet_size=(2<<(win->RPort->BitMap->Depth));

    txt_busy = TRUE;
    do
    {
		x = rand() % (config.mode.disp_hres);
		y = rand() % (config.mode.disp_vres);
		col = rand() % config.mode.palet_size;

        SetAPen(rp,col);

        Move(rp,x,y);

        if (gfx_mode==GSP_GFX)
            GfxText(rp,"Text Demo",9);
        else
            Text(rp,"Text Demo",9);

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

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

void __saveds EllipseDemo()
{
	int x,y,w,h,col;
    struct RastPort *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;
    config.mode.disp_hres=(win->Width);
    config.mode.disp_vres=(win->Height);
    config.mode.palet_size=(2<<(win->RPort->BitMap->Depth));

    SetDrPt(rp,0xF0F0);

    if (fill_mode&PATTERN_F) 
        {SetAfPt(rp,areaptrn,1);}
    else 
        SetAfPt(rp,NULL,1);

    rp->Flags&=(~AREAOUTLINE);  // Outline löschen
    ell_busy = FALSE;
    do
	{
		w = rand() % (config.mode.disp_hres/2);
		h = rand() % (config.mode.disp_vres/2);
		x = rand() % (config.mode.disp_hres);
		y = rand() % (config.mode.disp_vres);
		col = rand() % config.mode.palet_size;

        SetAPen(rp,col);

        if (fill_mode&FILL_F) 
        {
            if (gfx_mode==GSP_GFX)
                GfxAreaEllipse(rp,x,y,w,h);
            else
                AreaEllipse(rp,x,y,w,h);
        }
        else
        {
            if (gfx_mode==GSP_GFX)
                GfxDrawEllipse(rp,x,y,w,h);
            else
                DrawEllipse(rp,x,y,w,h);
        }

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

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