
#include <stdio.h>
#include <stdlib.h>

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>

#include "Cx.h"
#include "Prefs.h"
#include "GUI.h"
#include "WheelMouse.h"

#include "PrefsWin.h"

#define WINDOWMODE_ID 1
#define MMBMODE_ID 2
#define FOURTHMODE_ID 3
#define SAVE_ID 4
#define HIDE_ID 5
#define QUIT_ID 6
#define HOTKEY_ID 7
#define XSPEED_ID 8
#define YSPEED_ID 9
#define CLICKFRONT_ID 10
#define CLICKBACK_ID 11

BOOL PrefsWin_Show(struct PrefsWinContext *pwc);
void PrefsWin_Hide(struct PrefsWinContext *pwc);
BOOL PrefsWin_Handle(struct PrefsWinContext *pwc,unsigned long sigs);
void PrefsWin_Dispose(struct PrefsWinContext *pwc);

extern struct WheelMouseContext *MyWM;
extern struct CxContext *MyCx;

char *GadgetTitles[]=
{
  "Scroll window:",
  "Middle button:",
  "Fourth button:",
  "Mouse speed X: %ld%%",
  "Mouse speed Y: %ld%%",
  "Click to front:",
  "Hot key:",
  "Click to back:",
  NULL
};

#define SCROLLWINDOW_TITLE 0
#define MMBMODE_TITLE 1
#define FOURTHMODE_TITLE 2
#define MOUSESPEEDX_TITLE 3
#define MOUSESPEEDY_TITLE 4
#define CLICKFRONT_TITLE 5
#define HOTKEY_TITLE 6
#define CLICKBACK_TITLE 7

BOOL PrefsWin_Show(struct PrefsWinContext *pwc)
{
  struct Gadget *gg;
  int width,width2,leftedge,topedge;

  if(pwc->Visible)
    return(FALSE);

  if(!(pwc->Screen=LockPubScreen(NULL)))
    return(FALSE);

  if(!(pwc->GUI=GUI_Create(pwc->Screen,pwc->Screen->Font,8,8)))
  {
    pwc->Hide(pwc);
    return(FALSE);
  }

  GUI_StringTab(pwc->GUI,GadgetTitles);

  width=GUI_MaxStringWidth(pwc->GUI,MyWM->WindowModeNames);
  width2=GUI_MaxStringWidth(pwc->GUI,MyWM->MMBModeNames);
  if(width2>width) width=width2;
  width2=GUI_MaxStringWidth(pwc->GUI,MyWM->FourthButtonModeNames);
  if(width2>width) width=width2;

  pwc->GUI->InnerWidth=pwc->GUI->TabStop+width+64;

  gg=GUI_BuildCycleGadget(pwc->GUI,GadgetTitles[SCROLLWINDOW_TITLE],MyWM->WindowModeNames,WINDOWMODE_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTCY_Active,
                    pwc->Prefs->GetLong(pwc->Prefs,"WindowMode",0),TAG_DONE);

  gg=GUI_BuildCycleGadget(pwc->GUI,GadgetTitles[MMBMODE_TITLE],MyWM->MMBModeNames,MMBMODE_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTCY_Active,
                    pwc->Prefs->GetLong(pwc->Prefs,"MMBMode",0),TAG_DONE);

  gg=GUI_BuildCycleGadget(pwc->GUI,GadgetTitles[FOURTHMODE_TITLE],MyWM->FourthButtonModeNames,FOURTHMODE_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTCY_Active,
                    pwc->Prefs->GetLong(pwc->Prefs,"FourthMode",0),TAG_DONE);

  gg=GUI_BuildSliderFormatted(pwc->GUI,GadgetTitles[MOUSESPEEDX_TITLE],33,300,100,XSPEED_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTSL_Level,
                    pwc->Prefs->GetLong(pwc->Prefs,"XMouseSpeed",100),TAG_DONE);

  gg=GUI_BuildSliderFormatted(pwc->GUI,GadgetTitles[MOUSESPEEDY_TITLE],33,300,100,YSPEED_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTSL_Level,
                    pwc->Prefs->GetLong(pwc->Prefs,"YMouseSpeed",100),TAG_DONE);

  gg=GUI_BuildCheckBox(pwc->GUI,GadgetTitles[CLICKFRONT_TITLE],CLICKFRONT_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTCB_Checked,
                    pwc->Prefs->GetLong(pwc->Prefs,"ClickFront",TRUE),TAG_DONE);

  gg=GUI_BuildCheckBox(pwc->GUI,GadgetTitles[CLICKBACK_TITLE],CLICKBACK_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTCB_Checked,
                    pwc->Prefs->GetLong(pwc->Prefs,"ClickBack",FALSE),TAG_DONE);

  gg=GUI_BuildString(pwc->GUI,GadgetTitles[HOTKEY_TITLE],255,HOTKEY_ID);
  GT_SetGadgetAttrs(gg,NULL,NULL,GTST_String,
                    pwc->Prefs->GetString(pwc->Prefs,"Hot Key","ctrl alt m"),TAG_DONE);

  GUI_StringTab(pwc->GUI,NULL);

  width=pwc->GUI->InnerWidth;
  leftedge=pwc->GUI->BorderLeft;
  topedge=pwc->GUI->InnerHeight;

  pwc->GUI->InnerWidth=width/3;
  GUI_BuildWideButton(pwc->GUI,"Save",SAVE_ID);

  pwc->GUI->InnerHeight=topedge;
  pwc->GUI->BorderLeft+=width/3;
  GUI_BuildWideButton(pwc->GUI,"Hide",HIDE_ID);

  pwc->GUI->InnerHeight=topedge;
  pwc->GUI->BorderLeft+=width/3;
  GUI_BuildWideButton(pwc->GUI,"Quit",QUIT_ID);

  pwc->GUI->BorderLeft=leftedge;
  pwc->GUI->InnerWidth=width;

  if(!(pwc->GUI->LastGadget))
  {
    pwc->Hide(pwc);
    return(FALSE);
  }

  if(!(pwc->Window=OpenWindowTags(NULL,WA_Left,0,
                                       WA_Top,1+pwc->Screen->BarHeight,
                                       WA_InnerWidth,pwc->GUI->InnerWidth,
                                       WA_InnerHeight,pwc->GUI->InnerHeight,
                                       WA_IDCMP,IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|pwc->GUI->IDCMP,
                                       WA_SizeGadget,FALSE,WA_DragBar,TRUE,
                                       WA_DepthGadget,TRUE,WA_CloseGadget,TRUE,
                                       WA_NewLookMenus,TRUE,
                                       WA_Activate,FALSE,
                                       WA_Title,"FreeWheel V1.1",TAG_DONE)))
  {
    pwc->Hide(pwc);
    return(FALSE);
  }

  pwc->GUI->Attach(pwc->GUI,pwc->Window);

  pwc->Signals=1<<pwc->Window->UserPort->mp_SigBit;

  pwc->Visible=TRUE;
  return(TRUE);
}


void PrefsWin_Hide(struct PrefsWinContext *pwc)
{
  if(pwc->Window)
    CloseWindow(pwc->Window);
  pwc->Window=FALSE;
  pwc->Signals=0;

  if(pwc->GUI)
    pwc->GUI->Dispose(pwc->GUI);
  pwc->GUI=NULL;

  if(pwc->Screen)
    UnlockPubScreen(NULL,pwc->Screen);
  pwc->Screen=FALSE;

  if(pwc->Visible)
    pwc->Visible=FALSE;
}


void PrefsWin_Dispose(struct PrefsWinContext *pwc)
{
  if(pwc)
  {
    if(pwc->Visible)
      pwc->Hide(pwc);
    free(pwc);
  }
}


struct PrefsWinContext *PrefsWin_Create(struct PrefsGroup *pg)
{
  struct PrefsWinContext *pwc;
  if(!(pwc=malloc(sizeof(struct PrefsWinContext))))
    return(NULL);
  memset(pwc,0,sizeof(struct PrefsWinContext));
  pwc->Dispose=PrefsWin_Dispose;
  pwc->Handle=PrefsWin_Handle;
  pwc->Hide=PrefsWin_Hide;
  pwc->Show=PrefsWin_Show;

  pwc->Prefs=pg;

  return(pwc);
}


BOOL PrefsWin_Handle(struct PrefsWinContext *pwc,unsigned long sigs)
{
  BOOL cont=TRUE,close=FALSE;
  long value;
  char *string;
  if(pwc)
  {
    if(sigs&pwc->Signals)
    {
      struct IntuiMessage *im;
      while(im=GT_GetIMsg(pwc->Window->UserPort))
      {
        int class,code,id;
        struct Gadget *gg;
        class=im->Class;
        code=im->Code;
        switch(class)
        {
          case IDCMP_GADGETUP:
            gg=(struct Gadget *)im->IAddress;
            id=gg->GadgetID;
            GT_ReplyIMsg(im);
            switch(id)
            {
              case HOTKEY_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTST_String,&string,TAG_DONE);
                pwc->Prefs->SetString(pwc->Prefs,"Hot Key",string);
                MyCx->SetHotKey(MyCx,string);
                break;
              case WINDOWMODE_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTCY_Active,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"WindowMode",value);
                MyWM->WindowMode=value;
                break;
              case MMBMODE_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTCY_Active,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"MMBMode",value);
                MyWM->MMBMode=value;
                break;
              case FOURTHMODE_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTCY_Active,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"FourthMode",value);
                MyWM->FourthButtonMode=value;
                break;
              case XSPEED_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTSL_Level,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"XMouseSpeed",value);
                MyWM->MouseSpeedX=value;
                break;
              case YSPEED_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTSL_Level,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"YMouseSpeed",value);
                MyWM->MouseSpeedY=value;
                break;
              case CLICKFRONT_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTCB_Checked,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"ClickFront",value);
                MyWM->ClickToFront=value;
                break;
              case CLICKBACK_ID:
                GT_GetGadgetAttrs(gg,pwc->Window,NULL,GTCB_Checked,&value,TAG_DONE);
                pwc->Prefs->SetLong(pwc->Prefs,"ClickBack",value);
                MyWM->ClickToBack=value;
                break;
              case QUIT_ID:
                cont=FALSE;
                break;
              case HIDE_ID:
                close=TRUE;
                break;
              case SAVE_ID:
                pwc->Prefs->Save(pwc->Prefs);
                break;
            }
            break;
          case IDCMP_CLOSEWINDOW:
            GT_ReplyIMsg(im);
            close=TRUE;
            break;
          case IDCMP_REFRESHWINDOW:
            GT_ReplyIMsg(im);
            GT_BeginRefresh(pwc->Window);
            GT_EndRefresh(pwc->Window, TRUE);
            break;
          default:
            GT_ReplyIMsg(im);
            break;
        }
      }
    }
  }
  if(close)
    pwc->Hide(pwc);
  return(cont);
}

