#include <exec/types.h>
#include <intuition/intuition.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/icon.h>
#include <proto/wb.h>
#include "window.h"

struct PatternHdr {
	LONG whoknows[4];
	WORD size;
	WORD depth;
};

#define PHSIZE sizeof(struct PatternHdr)


/* image for our pattern icon */
struct Image PatternI1 =
{
    0, 0,			/* Upper left corner */
    16, 16, 0,			/* Width, Height, Depth */
    NULL,			/* Image data */
    ~0, 0,			/* PlanePick, PlaneOnOff */
    NULL			/* Next image */
};

/* tooltypes for our pattern icon */
UBYTE *PatternToolTypes[] =
{
    "ACTION=use",
    "WORKBENCH",
    NULL
};

UBYTE *PatternTool = "SYS:Prefs/WBPattern";	/* default Default Tool */

struct DiskObject PatternObj =
{
    WB_DISKMAGIC,		/* Magic Number */
    WB_DISKVERSION,		/* Version */
    {				/* Embedded Gadget Structure */
	NULL,			/* Next Gadget Pointer */
	0, 0, 16, 17,		/* Left,Top,Width,Height */
	GADGIMAGE | GADGBACKFILL,	/* Flags */
	RELVERIFY | GADGIMMEDIATE,		/* Activation Flags */
	BOOLGADGET,		/* Gadget Type */
	(APTR)&PatternI1,	/* Render Image */
	NULL,			/* Select Image */
	NULL,			/* Gadget Text */
	NULL,			/* Mutual Exclude */
	NULL,			/* Special Info */
	0,			/* Gadget ID */
	(APTR) 0x0001,		/* User Data (Revision) */
    },
    WBPROJECT,			/* Icon Type */
    NULL,			/* Default Tool */
    NULL,			/* Tool Type Array */
    NO_ICON_POSITION,		/* Current X */
    NO_ICON_POSITION,		/* Current Y */
    NULL,			/* Drawer Structure */
    NULL,			/* Tool Window */
    0				/* Stack Size */
};

struct IntuitionBase *IntuitionBase;
struct Library *IconBase;
struct Library *GadToolsBase;
struct WorkbenchBase *WorkbenchBase;

void
CloseLibs()
{
	if (IntuitionBase) CloseLibrary(IntuitionBase);
	if (GadToolsBase) CloseLibrary(GadToolsBase);
	if (IconBase) CloseLibrary(IconBase);
	if (WorkbenchBase) CloseLibrary(WorkbenchBase);
}

BOOL
OpenLibs()
{
	if ((IntuitionBase = (void *)OpenLibrary("intuition.library", 37L)) &&
	    (GadToolsBase = OpenLibrary("gadtools.library", 37L)) &&
	    (IconBase = OpenLibrary("icon.library", 37L)) &&
	    (WorkbenchBase = (void *)OpenLibrary("workbench.library", 37L)))
		return TRUE;
	CloseLibs();
	return FALSE;
}

BOOL
MakeIcon(char *name)
{
	BPTR fh;
	struct DiskObject *oldobj;
	UBYTE *imagedata;
	struct PatternHdr ph;
	BOOL rc = FALSE;

	if (fh = Open(name, MODE_OLDFILE))
	{
		if (Read(fh, &ph, PHSIZE) == PHSIZE)
		{
			if (imagedata = AllocMem(ph.size+1, 0L))
			{
				/* alloc 1 more than we need to check file size... */
				if (Read(fh, imagedata, ph.size+1) == ph.size)
				{
					if (oldobj = GetDiskObject(name))
					{
						PatternObj.do_DefaultTool = oldobj->do_DefaultTool;
						PatternObj.do_ToolTypes = oldobj->do_ToolTypes;
					}
					else
					{
						PatternObj.do_DefaultTool = PatternTool;
						PatternObj.do_ToolTypes = PatternToolTypes;
					}
					PatternI1.Depth = ph.depth;
					PatternI1.ImageData = (UWORD *)imagedata;
					rc = PutDiskObject(name, &PatternObj);
					if (oldobj)
						FreeDiskObject(oldobj);
				}
				FreeMem(imagedata, ph.size+1);
			}
		}
		Close(fh);
	}
	return rc;
}

void
_main()
{
    struct MsgPort *msgport;
    struct AppWindow *appwindow;    
    struct IntuiMessage *imsg;
    struct AppMessage *appmsg;
    BOOL ABORT = FALSE;

    if (!OpenLibs())
        return;

    if (msgport = CreateMsgPort())        /* for wb messages */
    {
        if (!SetupScreen())        /* get screen info etc. */
        {
            if (!OpenAppWindow())    /* open window */
            {
                if (appwindow = AddAppWindow(1, NULL, AppWnd, msgport, NULL))
                {
                    do {
                        /* Wait for either a CLOSEWINDOW or an AppMessage */
                        Wait(1 << AppWnd->UserPort->mp_SigBit |
                             1 << msgport->mp_SigBit);
                        while (imsg = (struct IntuiMessage *)GetMsg(AppWnd->UserPort))
                        {
                            if (imsg->Class = CLOSEWINDOW)
                                ABORT = TRUE;
                            ReplyMsg((struct Message *) imsg);
                        }

                        while (appmsg = (struct AppMessage *)GetMsg(msgport))
                        {
			    struct WBArg *argptr = appmsg->am_ArgList;
			    UWORD i;

                            for (i = 0; i < appmsg->am_NumArgs; i++)
                            {
				BPTR oldlock = CurrentDir(argptr->wa_Lock);
				MakeIcon(argptr->wa_Name);
				CurrentDir(oldlock);
                                argptr++;
			    }

                            ReplyMsg((struct Message *) appmsg);
			}

                    } while (ABORT == FALSE);

                    RemoveAppWindow(appwindow);
		}

		CloseAppWindow();

	    }

	    CloseDownScreen();
	}

	DeleteMsgPort(msgport);
    }

    CloseLibs();

} /* main */