#define MYLIB_BOOPSI

#ifndef INTUITION_GADGETCLASS_H
#include <intuition/gadgetclass.h>
#endif

#ifndef INTUITION_IMAGECLASS_H
#include <intuition/imageclass.h>
#endif

#include <proto/layers.h>

#include "xmris.h"
#include "ConfigKeys.h"
#include "BOOPSILib.h"

#include "Catalog.h"

/************************************************************************/

struct Window *ConfigKeysWindow;

/************************************************************************/

static Object *Contents;
static Object *StringGroup, *UseButton;

static struct TagItem WindowTags[]=
{
  {WA_Left, ~0},
  {WA_Top, ~0},
  {WA_Height, 0},
  {WA_Width, 0},
  {WA_CustomScreen, (ULONG)NULL},
  {WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_GADGETUP | IDCMP_ACTIVEWINDOW | IDCMP_NEWSIZE},
  {WA_MaxWidth, 0},
  {WA_MaxHeight, 0},
  {WA_MinWidth, 0},
  {WA_MinHeight, 0},
  {WA_Gadgets, NULL},
  {WA_Flags, WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SIMPLE_REFRESH | WFLG_ACTIVATE | WFLG_RMBTRAP | WFLG_NEWLOOKMENUS | WFLG_NOCAREREFRESH},
  {TAG_DONE}
};

/************************************************************************/

void CloseConfigKeysWindow(void)

{
  if (ConfigKeysWindow!=NULL)
    {
      LockLayerInfo(ConfigKeysWindow->WLayer->LayerInfo);
      WindowTags[0].ti_Data=ConfigKeysWindow->LeftEdge;
      WindowTags[1].ti_Data=ConfigKeysWindow->TopEdge;
      WindowTags[2].ti_Data=ConfigKeysWindow->Height;
      WindowTags[3].ti_Data=ConfigKeysWindow->Width;
      UnlockLayerInfo(ConfigKeysWindow->WLayer->LayerInfo);
      CloseWindowSafely(ConfigKeysWindow);
      ConfigKeysWindow=NULL;
    }
  DisposeObject(Contents);
  Contents=NULL;
  FreeBOOPSIClasses();
}

/************************************************************************/

void OpenConfigKeysWindow(void)

{
  if (ConfigKeysWindow==NULL)
    {
      if (CreateBOOPSIClasses())
	{
	  Object *LabelGroup, *DefaultGroup;
	  Object *TheObject;
	  char *UseLabel, *CancelLabel;
	  int Key;

	  UseLabel=GetString(MSG_USE_BUTTON);
	  CancelLabel=GetString(MSG_CANCEL_BUTTON);
	  Contents=TheObject=BOOPSILibO(Root),
	             BOOPSILibA_Group_Spacing, (1<<16)|1,
	             BOOPSILibA_Group_Child, BOOPSILibO(Group),
	               BOOPSILibA_Group_Horizontal, TRUE,
	               BOOPSILibA_Group_Child, LabelGroup=BOOPSILibO(Group),
	                 BOOPSILibA_Group_Spacing, (1<<16)|2,
	    	     BOOPSILibA_Group_Justify, BOOPSILibV_Group_Justify_Left,
	    	     BOOPSILibO_End,  /* Group */
	               BOOPSILibA_Group_Child, StringGroup=BOOPSILibO(Group),
	                 BOOPSILibA_Group_Spacing, (1<<16)|2,
	    	     BOOPSILibO_End,  /* Group */
	               BOOPSILibA_Group_Child, DefaultGroup=BOOPSILibO(Group),
	                 BOOPSILibA_Group_Spacing, (1<<16)|2,
	    	     BOOPSILibA_Group_Justify, BOOPSILibV_Group_Justify_Left,
	    	     BOOPSILibO_End,  /* Group */
	    	   BOOPSILibO_End,  /* Group */

	             BOOPSILibA_Group_Child, BOOPSILibO(Group),
	               BOOPSILibA_Group_Horizontal, TRUE,
	               BOOPSILibA_Group_SameSize, TRUE,

	               BOOPSILibA_Group_Child, BOOPSILibO(Frame),
	                 IA_FrameType, FRAME_BUTTON,
	    	     BOOPSILibA_Frame_Space, (40<<8),
	                 BOOPSILibA_Frame_Gadget, UseButton=BOOPSILibO(Button),
	                   GA_Text, UseLabel+1,
	    	       BOOPSILibA_ControlChar, *UseLabel,
	                   GA_ID, MSG_USE_BUTTON,
	                   BOOPSILibO_End,  /* Button */
	                 BOOPSILibO_End,  /* Frame */

	               BOOPSILibA_Group_Child, BOOPSILibO(Frame),
	                 IA_FrameType, FRAME_BUTTON,
	    	     BOOPSILibA_Frame_Space, (40<<8),
	                 BOOPSILibA_Frame_Gadget, BOOPSILibO(Button),
	                   GA_Text, CancelLabel+1,
	    	       BOOPSILibA_ControlChar, *CancelLabel,
	                   GA_ID, MSG_CANCEL_BUTTON,
	                   BOOPSILibO_End,  /* Button */
	                 BOOPSILibO_End,  /* Frame */

	    	   BOOPSILibO_End,  /* Group */

	    	 BOOPSILibO_End;  /* Root */

	  for (Key=0; TheObject!=NULL && Key<KEYS; Key++)
	    {
	        TheObject=BOOPSILibO(Frame),
	      	      IA_FrameType, FRAME_RIDGE,
	      	      BOOPSILibA_Frame_Fake, TRUE,
	      	      BOOPSILibA_Frame_Gadget, BOOPSILibO(Label),
	      		  GA_Text, GetString(MSG_DEMO_UP+Key),
	      		BOOPSILibO_End,  /* Label */
	      	      BOOPSILibO_End;  /* Frame */
	        if (TheObject!=NULL)
	          {
		    Object *String;

	            DoMethod(LabelGroup,OM_ADDMEMBER,TheObject);
	            TheObject=BOOPSILibO(Frame),
	      		  IA_FrameType, FRAME_RIDGE,
	      		  BOOPSILibA_Frame_Gadget, String=BOOPSILibO(String),
	      		    GA_ID, MSG_DEMO_UP,
	      		    GA_UserData, Key,
	      		    STRINGA_MaxChars, 100,
	      		    BOOPSILibO_End,  /* String */
	      		  BOOPSILibO_End;  /* Frame */
	            if (TheObject!=NULL)
		      {
			if (data.keysyms[Key].Description!=GetString(MSG_KEY_UP+Key))
			  {
			    SetAttrs(String,STRINGA_TextVal,data.keysyms[Key].Description,TAG_DONE);
			  }
			DoMethod(StringGroup,OM_ADDMEMBER,TheObject);
			TheObject=BOOPSILibO(Frame),
	      		            IA_FrameType, FRAME_RIDGE,
	      		            BOOPSILibA_Frame_Fake, TRUE,
	      		            BOOPSILibA_Frame_Gadget, BOOPSILibO(Label),
	      			      GA_Text, GetString(MSG_KEY_UP+Key),
	      			      BOOPSILibO_End,  /* Label */
	      		            BOOPSILibO_End;  /* Frame */
			if (TheObject!=NULL)
			  {
			    DoMethod(DefaultGroup,OM_ADDMEMBER,TheObject);
			  }
		      }
	          }
	      }

	  WindowTags[4].ti_Data=(ULONG)display.Screen->Screen;
	  WindowTags[5].ti_Tag=WA_IDCMP;
	  if (DoMethod(Contents,BOOPSILibM_Root_Init,WindowTags,50)==0)
	    {
	      WindowTags[5].ti_Tag=TAG_IGNORE;
	      ConfigKeysWindow=OpenWindowTags(NULL,
					      WA_ScreenTitle, display.window->ScreenTitle,
					      WA_Title, GetString(MSG_CONFIGKEYS_TITLE),
					      TAG_MORE, WindowTags);
	      if (ConfigKeysWindow!=NULL)
		{
		  ConfigKeysWindow->UserPort=&WindowPort;
		  if (ModifyIDCMP(ConfigKeysWindow,WindowTags[5].ti_Data))
		    {
		      return;
		    }
		}
	    }
	}
      CloseConfigKeysWindow();
    }
  else
    {
      ShowWindow(ConfigKeysWindow);
    }
}

/************************************************************************/

static INLINE int UseKeys(void)

{
  struct Requester Requester;
  APTR State;
  Object *NewKey;
  int Result;

  Result=TRUE;
  InitRequester(&Requester);
  Requester.Flags|=NOREQBACKFILL | SIMPLEREQ;
  Request(&Requester,ConfigKeysWindow);
  State=((struct MinList *)AttrGet(StringGroup,BOOPSILibA_Group_Children))->mlh_Head;
  while (Result && (NewKey=NextObject(&State))!=NULL)
    {
      char *KeyDesc;
      char *t;

      NewKey=(Object *)AttrGet(NewKey,BOOPSILibA_Frame_Gadget);
      KeyDesc=(char *)AttrGet(NewKey,STRINGA_TextVal);
      for (t=KeyDesc; *t!='\0' && *t==' '; t++)
	;
      if (*t=='\0')
	{
	  KeyDesc=NULL;
	}
      if (!ChangeKey((int)((struct ExtGadget *)NewKey)->UserData,KeyDesc))
	{
	  Result=FALSE;
	}
    }
  if (ConfigKeysWindow->FirstRequest!=NULL)
    {
      EndRequest(&Requester,ConfigKeysWindow);
    }
  if (!Result)
    {
      ActivateGadget((struct Gadget *)NewKey,ConfigKeysWindow,NULL);
    }
  return Result;
}

/************************************************************************/

void ProcessConfigKeysWindow(struct IntuiMessage *Message)

{
  if ((Message=(struct IntuiMessage *)DoMethod(Contents,BOOPSILibM_Root_ProcessMessage,Message))!=NULL)
    {
      switch (Message->Class)
	{
	case IDCMP_GADGETUP:
	  switch (((struct ExtGadget *)Message->IAddress)->GadgetID)
	    {
	    case MSG_DEMO_UP:
	      {
		APTR Strings;
		Object *Next;

		Strings=((struct MinList *)AttrGet(StringGroup,BOOPSILibA_Group_Children))->mlh_Head;
		while ((APTR)AttrGet(NextObject(&Strings),BOOPSILibA_Frame_Gadget)!=Message->IAddress)
		  ;
		if ((Next=NextObject(&Strings))==NULL)
		  {
		    Next=UseButton;
		  }
		else
		  {
		    Next=(Object *)AttrGet(Next,BOOPSILibA_Frame_Gadget);
		  }
		ActivateGadget((struct Gadget *)Next,ConfigKeysWindow,NULL);
	      }
	      break;

	    case MSG_USE_BUTTON:
	      if (!UseKeys())
		{
		  break;
		}
	      /* fall through */

	    case MSG_CANCEL_BUTTON:
	      DoMethod(Contents,BOOPSILibM_Root_ReplyMessage,Message);
	      CloseConfigKeysWindow();
	      return;
	    }
	  break;

	case IDCMP_CLOSEWINDOW:
	  DoMethod(Contents,BOOPSILibM_Root_ReplyMessage,Message);
	  CloseConfigKeysWindow();
	  return;
	}
      DoMethod(Contents,BOOPSILibM_Root_ReplyMessage,Message);
    }
}
