//-------------------------------------
//
// SuperCode (c) 1996 by T.Kühn 
//
// Programmiersprache:	ANSI-C
// Projektstart:			27.12.94
//
// Modul:				Messages
//						Ports
//
//-------------------------------------


/*-------------------------------------
VOID Msg_GetWin();
VOID Msg_GetWb();
VOID Msg_GetCx();
VOID Wait_All();
VOID Draw_Border(struct WinBlk *Blk,struct GadInfo *Info);
VOID Draw_NextBorder(struct GadInfo *Info);
-------------------------------------*/


#include <workbench/startup.h>

#include <pragma/gadtools_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/keymap_lib.h>
#include <pragma/wb_lib.h>
#include <workbench/workbench.h>

#include <intuition/gadgetclass.h>

#include <pragma/commodities_lib.h>
#include <libraries/commodities.h>

#include <Struct.h>

//-------------------------------------
// Vars
//-------------------------------------


struct MsgPort			*Port_Win,*Port_Wb,*Port_Cx;

CxObj *Broker;
/*
struct NewBroker NewB=
{
	5,"Name","Title 09/1994",
	"Info",
	NBU_UNIQUE|NBU_NOTIFY,
	COF_SHOW_HIDE,
	0,0,0
};
*/

/*
//-------------------------------------
VOID Command_CmpID(struct Gadget *gad,struct WinMsg *msg)
{
	struct GadInfo *info=gad->UserData;

	if (msg)
	{
		msg->Info=info;
//		if      (msg->Class==IDCMP_GADGETDOWN)			  msg->Blk->DownID=info;
//		else if (msg->Class==IDCMP_MOUSEMOVE && !info) msg->Info=info=msg->Blk->DownID;
//		else if (msg->Class==IDCMP_GADGETUP)  			  msg->Blk->DownID=0;
	}
	if (info)
	{
		switch (info->kind)
		{
			case BUTTON_CALC:
				break;
		}
		if (msg->Class==IDCMP_GADGETUP && info->func) (*info->func)(msg);
	}
}
//-------------------------------------
//-------------------------------------
VOID Command_Key(struct WinMsg *Msg)
{
	struct WinBlk *Blk=Msg->Blk;
	struct Window *Win=Msg->Win;
	struct GadInfo *Info;
	struct Gadget *Gad=0;
	struct InputEvent Input;
	UBYTE Str[5];
	UWORD Raw,Asc,Qual;
//	VOID (*Func)();
	WORD c;
	BOOL Up=FALSE;

	if (Blk && Win )
	{
		if (Msg->Code & 0x80) Up=TRUE;
		Raw=Msg->Code & 0x7F;
		Qual=Msg->Qualifier;
		if (Raw<0x60 || Raw>0x67)
		{
			if (!Up)
			{
				if (!(Qual&IEQUALIFIER_REPEAT))
				{
					if(Raw==0x45 && (Qual&ALT) )			// Esc
					{
						Window_Close(Blk);
					}
					else if(Raw==0x42 && (Qual&ALT) )
					{
						c=0;
						if (Qual&SHFT)
						{
							Blk=(APTR)Blk->Node.ln_Pred;
							while (!Blk->WinPtr && c<=1)
							{
								Blk=(APTR)Blk->Node.ln_Pred;
								if ((APTR)Blk->Node.ln_Pred==(APTR)&Blk_Head) {Blk=(APTR)Blk_Head.lh_TailPred;c++}
							}
						}
						else
						{
							Blk=(APTR)Blk->Node.ln_Succ;
							while (!Blk->WinPtr && c<=1)
							{
								Blk=(APTR)Blk->Node.ln_Succ;
								if (!Blk->Node.ln_Succ) {Blk=(APTR)Blk_Head.lh_Head;c++}
							}
						}
						if (Blk->WinPtr)
						{
							ActivateWindow(Blk->WinPtr);
							WindowToFront(Blk->WinPtr);
						}
					}
					else if(Raw==0x42)			// Tab
					{
						Info=Blk->LastGadInfo;
						do
						{
							if (Qual&SHFT)
							{
								if (Info && (!LFrst(Info)) ) Info=LPrev(Info);
								else if (!Empty(&Blk->GadInfo)) Info=(struct GadInfo*)Blk->GadInfo.lh_TailPred;
							}
							else
							{
								if (Info && (!LLast(Info)) ) Info=LNext(Info);
								else if (!Empty(&Blk->GadInfo)) Info=(struct GadInfo*)Blk->GadInfo.lh_Head;
							}
//						}while(Info && ((Info->Kind==TEXT_KIND)||(Info->Kind==BORDER_KIND)) && (Info!=Blk->LastGadInfo));
						Draw_NextBorder(Info);
					}
					else
					{
						Str[0]=0;
						Input.ie_NextEvent=0;
						Input.ie_Class=IECLASS_RAWKEY;
						Input.ie_SubClass=0;
						Input.ie_Code=Raw;
						Input.ie_Qualifier=Qual&~SHFT;
						MapRawKey(&Input,Str,4,0);
						Asc=Str[0];
//printf("Raw:%X\n",Raw);
						if (Raw==0x40 || Raw==0x43 || Raw==0x44 || Raw==0x4c || Raw==0x4d || Raw==0x4e || Raw==0x4f )
						{
							Gadget_Action(Blk,Raw,Qual);
						}
						else
						{
							Info=(struct GadInfo*)Blk->GadInfo.lh_Head;
							while(LNext(Info))
							{
								if (Info->Key==Asc)
								{
									Draw_NextBorder(Info);
									break;
								}
								Info=LNext(Info);
							}
						}
					}
				}
			}
		}
	}
}
//-------------------------------------
*/

//-------------------------------------
VOID Wait_All()
{
	ULONG Mask=0;

	if (Port_Cx)  Mask|=1<<Port_Cx ->mp_SigBit;
	if (Port_Win) Mask|=1<<Port_Win->mp_SigBit;
	if (Port_Wb)  Mask|=1<<Port_Wb ->mp_SigBit;
	if (Mask) Wait(Mask);
}
//-------------------------------------
ULONG wait_mask(ULONG mask)
{
	if (mask) mask=Wait(mask);
	return mask;
}
//-------------------------------------

/*
//-------------------------------------
VOID Msg_GetWin()
{
	struct Window *Win;
	register struct WinBlk *MsgBlk;
	struct IntuiMessage *Msg;
	struct WinMsg GadMsg;

	while (Msg=(struct IntuiMessage*)GetMsg(Port_Win))
	{
		Win=Msg->IDCMPWindow;
		MsgBlk=(Win) ? (APTR)Win->UserData : 0;
		GadMsg.Win=Win;
		GadMsg.Blk=MsgBlk;
		GadMsg.Gad=(APTR)Msg->IAddress;
		GadMsg.Class=Msg->Class;
		GadMsg.Code=Msg->Code;
		GadMsg.Qualifier=Msg->Qualifier;
		GadMsg.MouseX=Msg->MouseX;
		GadMsg.MouseY=Msg->MouseY;
		GadMsg.Sec=Msg->Seconds;
		GadMsg.Mic=Msg->Micros;

		if (Msg->Class!=IDCMP_SIZEVERIFY) ReplyMsg((struct Message*)Msg);

		if (MsgBlk && Win)
		{
			switch (GadMsg.Class)
			{
				case IDCMP_NEWPREFS:
					Window_Dispatcher(MsgBlk,Mode_Prefs);
					break;
				case INTUITICKS:
//					if (Blk_Help->WinPtr) Command_Help(&GadMsg);
					Window_Dispatcher(MsgBlk,Mode_Ticks);
					break;
				case IDCMP_CHANGEWINDOW:
					Window_StoreSize(MsgBlk);
					break;
				case IDCMP_RAWKEY:
					if (MsgBlk->KeyCheck) (MsgBlk->KeyCheck)(&GadMsg);
					break;
				case IDCMP_SIZEVERIFY:
					Window_ChangeSizeVerify(MsgBlk);
					ReplyMsg((struct Message*)Msg);
					break;
				case IDCMP_NEWSIZE:
					Window_ChangeSize(MsgBlk);
					break;
				case IDCMP_MENUPICK:
					Command_Menu(MsgBlk,GadMsg.Code);
					break;
				case IDCMP_CLOSEWINDOW:
					Window_Close(MsgBlk);
					break;
				case IDCMP_GADGETDOWN:
				case IDCMP_GADGETUP:
				case IDCMP_MOUSEMOVE:
					GadMsg.GadID=GadMsg.Gad->GadgetID;
					Command_CmpID(GadMsg.Gad,&GadMsg);
					break;
				case IDCMP_INACTIVEWINDOW:
					Window_Dispatcher(MsgBlk,Mode_InAct);
					break;
			}
		}
	}
}
//-------------------------------------
*/

//-------------------------------------
VOID Msg_GetCx()
{
	CxMsg *Msg=0;
	LONG ID;

	if (Port_Cx)
	{
		while ((Msg=(APTR)GetMsg(Port_Cx)))
		{
			ID=CxMsgID(Msg);
			ReplyMsg((APTR)Msg);

			switch (ID)
			{
				case CXCMD_KILL:
						Quit();
						break;
				case CXCMD_ENABLE:
						ActivateCxObj(Broker,TRUE);
						break;
				case CXCMD_DISABLE:
						ActivateCxObj(Broker,FALSE);
						break;
				case CXCMD_UNIQUE:
				case CXCMD_APPEAR:
//						if (Blk_ActWin->WinPtr) ActivateWindow(Blk_ActWin->WinPtr);
						if (Scrn.Scrn) ScreenToFront(Scrn.Scrn);
						break;
				case CXCMD_DISAPPEAR:
						break;
			}
		}
	}
}
//-------------------------------------
UBYTE IconFile[DLEN+2];
//-------------------------------------
VOID Msg_GetWb()
{
	struct AppMessage *Msg=0;
	BPTR IconPath;
	UBYTE *IconName;
	struct MsgBlk *Blk;

//struct AppMessage
//    UWORD am_Type;		/* message type */
//    ULONG am_UserData;		/* application specific */
//    ULONG am_ID;		/* application definable ID */
//    LONG am_NumArgs;		/* # of elements in arglist */
//    struct WBArg *am_ArgList;	/* the arguements themselves */
//    WORD am_MouseX;		/* mouse x position of event */
//    WORD am_MouseY;		/* mouse y position of event */

	if (Port_Wb)
	{
		while ((Msg=(APTR)GetMsg(Port_Wb)))
		{
			switch (Msg->am_Type)
			{
				case AMTYPE_APPWINDOW:
					Blk=(APTR)Msg->am_UserData;
					IconPath=Msg->am_ArgList[0].wa_Lock;
					IconName=Msg->am_ArgList[0].wa_Name;
					if (IconPath && IconName)
						if (NameFromLock(IconPath,IconFile,DLEN))
						{
							AddPart(IconFile,IconName,DLEN);
//							...
						}
					break;
			}
			ReplyMsg((APTR)Msg);
		}
	}
}
//-------------------------------------


//-------------------------------------
VOID Command_Menu(struct Menu *Menu,LONG Code)
{
	struct MenuItem *MenuHit;
	struct tkNewMenu *Data;

	if (Menu)
	{
		while ((MenuHit=ItemAddress(Menu,Code)) && (Code!=MENUNULL))
		{
			Data=GTMENUITEM_USERDATA(MenuHit);
			Code=MenuHit->NextSelect;
			if (Data->Func) (*Data->Func)();
		}
	}
}
//-----------------------------------



//-------------------------------------
struct MsgPort *MakeMsgPort()
{
	struct MsgPort *port;

	do	{ port=CreateMsgPort();
		} while((!port) && ASK_AGAIN==display_error(ERR_PORT,ASK_EXIT|ASK_AGAIN|ASK_CONT));

	return port;
}
//-------------------------------------
VOID FreeMsgPort(struct MsgPort **Port)
{
	struct Message *Msg;

	if (Port && *Port)
	{
		while ((Msg=GetMsg(*Port)))
		{
			ReplyMsg(Msg);
		}
		DeleteMsgPort(*Port);
		*Port=0;
	}
}
//-------------------------------------
VOID MsgPort_Init()
{
	Port_Win=MakeMsgPort();
	Port_Wb=MakeMsgPort();
	Port_Cx=MakeMsgPort();
}
//-------------------------------------
VOID MsgPort_Free()
{
	FreeMsgPort(&Port_Cx);
	FreeMsgPort(&Port_Wb);
	FreeMsgPort(&Port_Win);
}
//-------------------------------------

