/* PowerWindows: misc.c */

#include <exec/memory.h>
#include <exec/interrupts.h>
#include <dos/dos.h>
#include <graphics/gfx.h>
#include <intuition/intuition.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <utility/utility.h>

#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/utility_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/timer_lib.h>
#include <clib/alib_protos.h>

#pragma header

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include "config.h"
#include "PowerWindows.h"
#include "PWDevelopper.h"


void SendActionMsg(struct ActionMsg* &MyMsg,struct Window *ParentWindow,WORD WinLeft,WORD WinTop,struct Window *IconWindow,struct ScreenEntry *se,WORD Code)
{
	MyMsg=AllocVec(sizeof(struct ActionMsg),MEMF_PUBLIC|MEMF_CLEAR);
	if (MyMsg)
	{
		ObtainSemaphoreShared(&ScreenListSemaphore);
		MyMsg->ExecMessage.mn_Length=sizeof(struct ActionMsg);
		MyMsg->win=ParentWindow;
		MyMsg->x1=WinLeft;
		MyMsg->y1=WinTop;
		MyMsg->IconWindow=IconWindow;
		MyMsg->SEntry=se;
		MyMsg->Code=Code;
		ReleaseSemaphore(&ScreenListSemaphore);
		PutMsg(ActionPort,(struct Message *)MyMsg);
	}
}

BOOL ValidTagList(struct TagItem *tl)
{
	BOOL rc=TRUE;
	
	if ((ULONG)tl&1)
	{
		rc=FALSE;
	} else {
		if (!tl || !TypeOfMem(tl)) rc=FALSE;
	}

	return rc;
}

struct TaskEntry *CheckTask(struct Window *win,struct List *list,BOOL sensitive)
{
	struct Task *t=0;
	struct TaskEntry *te;
	char *name;
	WORD res;
	APTR a;
	
	res=0;
	if (win)
		if (win->UserPort)
			if ((win->UserPort->mp_Flags&PF_ACTION)==PA_SIGNAL)
				if (win->UserPort->mp_SigTask) t=win->UserPort->mp_SigTask;

	if (!t) t=FindTask(0);
	name=t->tc_Node.ln_Name;

	if (t->tc_Node.ln_Type==NT_PROCESS)
	{
		if ((a=BADDR(((struct Process *)t)->pr_CLI)))
		{
			if ((a=BADDR(((struct CommandLineInterface *)a)->cli_CommandName)))
			{
				name=a;
				name++;
			}
		}
	}
		
	if (name)
	{
		te=(struct TaskEntry *)list->lh_Head;
		while (te->te_Node.mln_Succ)
		{
			if (te->te_MatchType==MATCH_NORMAL)
			{
				if (sensitive)
				{
					res=(WORD)(strcmp(name,&te->te_Pattern)==0);
				} else {
					res=(WORD)(stricmp(name,&te->te_Pattern)==0);
				}
			} else if (t->tc_Node.ln_Type==NT_PROCESS) {
				if (sensitive)
				{
					res=(WORD)(MatchPattern(&te->te_Pattern,name)!=0);
				} else {
					res=(WORD)(MatchPatternNoCase(&te->te_Pattern,name)!=0);
				}
			}
			if (res) return te;
			te=(struct TaskEntry *)te->te_Node.mln_Succ;
		}
	}
	
	return 0;
	
}

struct Gadget *FindIconifyGadget(struct Window *win)
{
	struct Gadget *gad;
	ULONG gid;

	gad=win->FirstGadget;
	while (gad)
	{
		if (IsMyButton(gad))
		{
			if (GetAttr(GA_ID,(Object *)gad,&gid))
			{
				if (gid==GADGET_ICONIFY) break;
			}
		}
		gad=gad->NextGadget;
	}
	
	return gad;
}

struct Gadget *FindIconGadget(struct Window *win)
{
	struct Gadget *gad;
	ULONG gid;

	gad=win->FirstGadget;
	while (gad)
	{
		if (IsMyButton(gad))
		{
			if (GetAttr(GA_ID,(Object *)gad,&gid))
			{
				if (gid==GADGET_ICONDRAG) break;
			}
		}
		gad=gad->NextGadget;
	}

	return gad;
}

void KillExt(BPTR &seg,LONG (*&routine)(Msg))
{
	static struct csExit ExitMsg = {CS_EXIT};

	if (seg)
	{
		(*routine)((Msg)&ExitMsg);
	
		UnLoadSeg(seg);
		seg=0;
	}
}

void KillLibrary(struct Library *& lib)
{
	if (lib)
	{
		CloseLibrary(lib);
		lib=0;
	}
}

BOOL IsMyImage(struct Image *im)
{
	BOOL rc=FALSE;
	
	if (im)
	{
		if (im->Depth==CUSTOMIMAGEDEPTH)
		{
			if (OCLASS(im)==MyImageClass) rc=TRUE;
		}
	}
	
	return rc;
}

BOOL IsMyButton(struct Gadget *gad)
{
	BOOL rc=FALSE;
	
	if (gad)
	{		
		if ((gad->GadgetType&GTYP_GTYPEMASK)==GTYP_CUSTOMGADGET)
		{
			if (OCLASS(gad)==MyButtonClass) rc=TRUE;
		}
	}
	
	return rc;
}

BOOL KillMyGadget(struct Gadget *gad,struct Window *win)
{
	struct Image *im;
	BOOL killimage=TRUE;
	BOOL rc=FALSE;

	if (IsMyButton(gad))
	{
		RemoveGadget(win,gad);

		if (gad->Flags&GFLG_GADGIMAGE)
		if ((im=gad->GadgetRender))
//		if ((im->Depth==CUSTOMIMAGEDEPTH))
		{
/*			if (GetAttr(CGA_Task,gad,&gid))
			{
				if (gid==PATCHEDDEPTHGADGETTASKDUMMY)
				{
					killimage=FALSE;
				}
			}*/
			if (/*killimage &&*/ IsMyImage(im))
			{
				gad->GadgetRender=0;
				gad->SelectRender=0;
				DisposeObject(im);
			}
		}

		DisposeObject(gad);
		rc=TRUE;
	}
	return rc;
}

void KillMyGadgets(struct Window *win)
{
	struct Gadget *gad,*ngad;
	
	gad=win->FirstGadget;
	while (gad)
	{
		ngad=gad->NextGadget;
		KillMyGadget(gad,win);
		gad=ngad;
	}
}

void DrawHClipLine(WORD x1,WORD y1,WORD x2)
{
	if (y1>=0 && y1<IO_ScreenEntry->se_NormalHeight)
	{
		if (x1<0) x1=0;
		if (x2<0) x2=0;
		if (x1<IO_ScreenEntry->se_NormalWidth)
		{
			if (x2>=IO_ScreenEntry->se_NormalWidth) x2=IO_ScreenEntry->se_NormalWidth-1;
			if (x2>=x1)
			{
				RectFill(&IO_RP,x1,y1,x2,y1);
			}
		}
	}
}

void DrawVClipLine(WORD x1,WORD y1,WORD y2)
{
	if (x1>=0 && x1<IO_ScreenEntry->se_NormalWidth)
	{
		if (y1<0) y1=0;
		if (y2<0) y2=0;
		if (y1<IO_ScreenEntry->se_NormalHeight)
		{
			if (y2>=IO_ScreenEntry->se_NormalHeight) y2=IO_ScreenEntry->se_NormalHeight-1;
			if (y2>=y1)
			{
				RectFill(&IO_RP,x1,y1,x1,y2);
			}
		}
	}
}

void DrawRect(void)
{
	if (MyConfig.MarkerTyp!=MARKER_NONE && (!OpaqueON))
	{
		
		DrawHClipLine(IO_x1,IO_y1,IO_x2);
		DrawHClipLine(IO_x1,IO_y2,IO_x2);
		DrawVClipLine(IO_x1,IO_y1,IO_y2);
		DrawVClipLine(IO_x2,IO_y1,IO_y2);
		
		if (MyConfig.MarkerTyp==MARKER_EXTENDED)
		{
			if (IO_Win->BorderTop>1) DrawHClipLine(IO_x1,IO_y1+IO_Win->BorderTop-1,IO_x2);
			if (IO_Win->BorderBottom>1) DrawHClipLine(IO_x1,IO_y2-IO_Win->BorderBottom+1,IO_x2);
			if (IO_Win->BorderLeft>1) DrawVClipLine(IO_x1+IO_Win->BorderLeft-1,IO_y1+IO_Win->BorderTop,IO_y2-IO_Win->BorderBottom);
			if (IO_Win->BorderRight>1) DrawVClipLine(IO_x2-IO_Win->BorderRight+1,IO_y1+IO_Win->BorderTop,IO_y2);
		}

	}
}

void ScanWindows(struct Screen *scr)
{
	struct Window *win;
	
	win=scr->FirstWindow;
	while (win)
	{
		After_OpenWindowTagList(win);
		win=win->NextWindow;
	}

}

struct Screen *WorkbenchOpened(void)
{
	struct PubScreenNode *sn;
	struct Screen *rc=0;
	
	sn=(struct PubScreenNode *)LockPubScreenList()->lh_Head;
	while (sn->psn_Node.ln_Succ)
	{
		if (sn->psn_Node.ln_Name)
		{
			if (!strcmp(sn->psn_Node.ln_Name,WORKBENCHNAME))
			{
				rc=sn->psn_Screen;
				break;
			}
		}
		sn=(struct PubScreenNode *)sn->psn_Node.ln_Succ;
	}
	UnlockPubScreenList();
	return rc;
}


