//****************
//
// Name : OnGo.c
//
//****************

//**** Header files

//** OS3.1
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <libraries/wbstart.h>
#include <libraries/commodities.h>
#include <intuition/intuitionbase.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <dos/dos.h>

//** OS3.1 Prototypes
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <clib/commodities_protos.h>
#include <clib/utility_protos.h>
#include <clib/dos_protos.h>
#include <clib/wbstart_protos.h>

//** OS3.1 Inline pragmas
#include <pragmas/intuition_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/commodities_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/wbstart_pragmas.h>

//** ANSI header files
//#include <stdio.h>
#include <string.h>

//** Application Header files
#include "MPMGClass.h"
#include "Librarian.h"
#include "Read.h"
#include "CX.h"
#include "Launch.h"
#include "Prefs.h"
#include "App.h"
#include "VScreen.h"
#include "Tree.h"
#include "Win.h"
#include "GrList.h"
#include "TDEBUG.H"

//**** Local application Storage

UBYTE VersTag[]="\0$VER: " ONGOVERS " " ONGODATE " © 1996 Tak Tang";

static ULONG    MyMenus;
static ULONG    done    = FALSE;
static BOOL     Active  = TRUE;
static BOOL     Reload  = FALSE;
static ULONG    Depth   = 1;
static BPTR     GIQD    = NULL;
static char     GIQF[33];


//**** Local Main handlers


static void MainHandleIntui(void) {
  struct IntuiMessage *msg;
  struct TagItem *tags;
  ULONG class;
  UWORD code;
  struct Gadget *gad;
  struct trunk *tr;

  struct TagItem *ti, *tistate;
  ULONG pn;
  ULONG TempMenu;
  ULONG id;
  ULONG Key;
  UWORD gadId;
  char *a;
  UBYTE NuScreen;


  while (msg = (struct IntuiMessage *)
    //** Get the message information
    GetMsg((struct MsgPort *)OnGoWin->UserPort)) {
    class   = msg->Class;
    code    = msg->Code;
    switch (class) {
      case IDCMP_IDCMPUPDATE:
	tags=CloneTagItems(msg->IAddress);
	break;
      case IDCMP_GADGETUP:
	gad=(struct Gadget *)msg->IAddress;
	break;
      default:
	break;
    } // switch
    ReplyMsg((struct Message *)msg);

    //** Now act on it!

    switch (class) {

      case IDCMP_IDCMPUPDATE:
	tistate=tags;
	while (ti=NextTagItem(&tistate)) {
	  switch (ti->ti_Tag) {
	    case GA_ID:
	      DPRINT("\nDepth = %d    ",Depth);
	      DPRINT("Tree  = %d\n",TreeHeight);
	      break;
	    case MPMG_PromiseRequest:
	      DPRINT("OnGo: PromiseRequest = %u\n",ti->ti_Data);

	      id=ti->ti_Data;
	      a=FindNthBranch(id);
	      if (a) {
		if (0==strcmp(a,"#?:"))
		  tr=ScanVol();
		else
		  tr=ScanDir(a);
		Depth++;
		tr->Menu=TempMenu=MakeMenuFromTree();
		if (TempMenu) {
		  SetGadgetAttrs(MyGadgets[0],OnGoWin,NULL,
		    MPMG_PromiseFullfill,TempMenu,
		    MPMG_PromiseKey,id,
		    TAG_END);
		} else {
		  DPRINT("OnGo: PromiseRequest: MakeMenuFromTree() failed\n",0);
		}
	      } else {
		DPRINT("OnGo: PromiseRequest: FindNthBranch() failed\n",0);
	      }
	      break;
	    case MPMG_PromiseCancel:
	      DPRINT("OnGo: PromiseCancel = %u\n",ti->ti_Data);
	      DeleteLevel();
	      Depth--;
	      break;
	    case MPMG_PromiseKey:
	      Key=ti->ti_Data;
	      break;
	    case MPMG_GrabItQuick:
	      if (Depth>1) {
		id=ti->ti_Data;
		DPRINT("OnGo: Grabing %d\n",id);
		a=FindNthBranch(id);
		if (a) {
		  struct trunk *tr;
		  tr=GetTop();
		  GIQD=DupLock(tr->DirLock);
		  strncpy(GIQF,a,32);
		  DPRINT("OnGo: Grabbed %s\n",a);
		}
	      }
	      break;
	    default:
	      DPRINT("Other (%u) =",ti->ti_Tag);
	      DPRINT(" %u\n",ti->ti_Data);
	      break;
	  } // switch
	} // while
	FreeTagItems(tags);
	break; // IDCMP_IDCMPUPDATE

      case IDCMP_REFRESHWINDOW:
	BeginRefresh(OnGoWin);
	  if ( (AutoHide==1) && (FALSE==Hidden))
	    DrawBevelBorder(OnGoWin->RPort,2,1,0,0,OnGoWin->Width,OnGoWin->Height);
	  else
	    DrawBevelBorder(OnGoWin->RPort,2,1,0,0,OnGoWin->Width,OnGoWin->Height+1);
	EndRefresh(OnGoWin,TRUE);
	break; // case IDCMP_REFRESHWINDOW

      case IDCMP_VANILLAKEY:
	if (OnGoWin) {
	  if ((' '==code) || ('0'==code) || ('\''==code)) {
	    ActivateGadget( MyGadgets[0],OnGoWin, NULL );
	  } else if ((code>'0') && (code <='9')) {
	    NuScreen=code-'0';
	    if ((NuScreen<=NumVScreens)&&(NuScreen!=VScreen)) {
	      SetGadgetAttrs(MyGadgets[VScreen],OnGoWin,NULL,GA_Selected,FALSE,TAG_END);
	      SwitchToScreen(NuScreen);
	      SetGadgetAttrs(MyGadgets[VScreen],OnGoWin,NULL,GA_Selected,TRUE,TAG_END);
	    }
	  }
	}
	break; // case IDCMP_VANILLAKEY

      case IDCMP_GADGETUP:
	gadId=gad->GadgetID;
	if (0==gadId) {
	  switch (code) {
	    case ACT_QUIT:
	      done=TRUE;
	      break;
	    case ACT_RUN:
	      GetAttr(MPMG_SelectUserData,MyGadgets[0],&pn);
	      Launch((struct ProgNode *)pn,0,NULL);
	      break;
	    case ACT_HIDE:
	      my_cx_show=0;
	      break;
	    case ACT_RELOAD:
	      Reload=TRUE;
	      break;
	    case ACT_RUNW:
	      if (GIQD) {
		DPRINT("Act_Run Depth=%d\n",Depth);
		WBStartTags(WBStart_Name, GIQF, WBStart_DirectoryLock, GIQD, TAG_END);
		UnLock(GIQD);
	      }
	      GIQD=NULL;
	      break;
	    case ACT_RUNC:
	      break;
	    default:
	      DPRINT("OnGo: GadgetUp %d\n",code);
	      break;
	  } // switch code
	} else if (gadId<NumVScreens+1) // was a VScreen Button
	  if (VScreen!=gad->GadgetID) {
	    SetGadgetAttrs(MyGadgets[VScreen],OnGoWin,NULL,GA_Selected,FALSE,TAG_END);
	    SwitchToScreen(gad->GadgetID);
	    SetGadgetAttrs(MyGadgets[VScreen],OnGoWin,NULL,GA_Selected,TRUE,TAG_END);
	  } else {
	    SetGadgetAttrs(MyGadgets[gad->GadgetID],OnGoWin,NULL,GA_Selected,TRUE,TAG_END);
	  }
	else {
	  DoUnIconify(gad);
	} // if GadgetID
	break; // IDCMP_GADGETUP
      case IDCMP_INACTIVEWINDOW:
	if ( (AutoHide==1) && (FALSE==Hidden)) {
	  HideWindow();
	  DPRINT("Plop!\n",0);
	}
      default:
	break;
    } // switch

  } // while
} // MainHandleIntui



static void MainHandleCX(void) {
  ULONG cxmsgid, cxmsgtype;
  CxMsg *cxmsg;

  while(cxmsg = (CxMsg *)GetMsg(nb.nb_Port)) {
    cxmsgid=CxMsgID(cxmsg);
    cxmsgtype=CxMsgType(cxmsg);
    ReplyMsg((struct Message *)cxmsg);
    switch(CxMsgType(cxmsg)) {
      case CXM_COMMAND:
	switch(cxmsgid) {
	  case CXCMD_DISABLE:
	    if (TRUE==Active) {
	      ActivateCxObj(broker, 0L);
	      Active = FALSE;
	      if (MyGadgets[0]) SetGadgetAttrs(MyGadgets[0],OnGoWin,NULL,MPMG_Menus,NULL,TAG_END);
	    }; // if
	    break;
	  case CXCMD_ENABLE:
	    if (FALSE==Active) {
	      ActivateCxObj(broker, 1L);
	      Active = TRUE;
	      if (MyGadgets[0]) SetGadgetAttrs(MyGadgets[0],OnGoWin,NULL,MPMG_Menus,MyMenus,TAG_END);
	    }; // if
	    break;
	  case CXCMD_UNIQUE:
	  case CXCMD_APPEAR:
	    my_cx_show=1;
	    break;
	  case CXCMD_DISAPPEAR:
	    my_cx_show=0;
	    break;
	  case CXCMD_KILL:
	    done=TRUE;
	    break;
	} // switch
	break;
      case CXM_IEVENT:
	if (0==cxmsgid) {
	  my_cx_show=(my_cx_show?0:1);
	} else if (NumVScreens+1==cxmsgid) {
	  if (OnGoWin) DoIconify();
	} else {
	  if ((OnGoWin)&&(cxmsgid!=VScreen)) {
	    SetGadgetAttrs(MyGadgets[VScreen],OnGoWin,NULL,GA_Selected,FALSE,TAG_END);
	    SwitchToScreen(cxmsgid);
	    SetGadgetAttrs(MyGadgets[VScreen],OnGoWin,NULL,GA_Selected,TRUE,TAG_END);
	  }
	}
	break;
      default: break;
    } // switch
  } // while GetMsg
} // MainHandleCX()


//**** Main Loop

static void MainLoop(void) {
  struct AppMessage   *appmsg;
  ULONG  sig_w, sig_c, sig_a, sret;
  struct Screen *wb;
  WORD x,y;

  sig_c = 1 << CX_Port->mp_SigBit;

  while (done == FALSE) {
    if (TRUE==Reload) {
      // Reload toolsfile
      if (MyGadgets[0]) SetGadgetAttrs(MyGadgets[0],OnGoWin,NULL,MPMG_Menus,NULL,TAG_END);
      MyMenuFree(MyMenus);
      MyMenus=MyMenuMake(ToolsFileName);
      if (MyGadgets[0]) SetGadgetAttrs(MyGadgets[0],OnGoWin,NULL,MPMG_Menus,MyMenus,TAG_END);
      Reload=FALSE;
    } // if reload

    if ((OnGoWin) && (0==my_cx_show)) MyCloseWindow();
    if ((NULL==OnGoWin) && (my_cx_show)) MyOpenWindow(MyMenus);

    if (OnGoWin) sig_w = 1 << OnGoWin->UserPort->mp_SigBit;
    else sig_w=0;

    if (AppMenu) sig_a = 1 << AppMenu->mp_SigBit;
    else sig_a=0;

    sret = Wait(SIGBREAKF_CTRL_C |SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_F  |  sig_w | sig_c | sig_a);
    if (sret & sig_w) {
      MainHandleIntui();
    } else if (sret & sig_c) {
      MainHandleCX();
    } else if (sret & sig_a) {
      while(appmsg=(struct AppMessage *)GetMsg(AppMenu)) {
	Launch( (struct ProgNode *)appmsg->am_UserData,
		(long)appmsg->am_NumArgs,
		(struct WBArg *)appmsg->am_ArgList);
	// Let workbench know we're done with the message
	ReplyMsg((struct Message *)appmsg);
      } // while GetMsg
    } else if (sret & SIGBREAKF_CTRL_C) {
      done=TRUE;
    } else if (sret & SIGBREAKF_CTRL_D) {
      Reload=TRUE;
    } else if (sret & SIGBREAKF_CTRL_F) {
      if ((AutoHide==1) && (Hidden==TRUE)) {

	if (wb = LockPubScreen("Workbench")) {
	  struct Screen *ascr;
	  ULONG lock=LockIBase(0);
	  ascr=((struct IntuitionBase *)IntuitionBase)->ActiveScreen;
	  UnlockIBase(lock);
	  x=wb->MouseX;
	  y=wb->MouseY;
	  UnlockPubScreen(NULL, wb);
	  if (ascr==wb) {
	    if (((MyWinPos==0) && (y>=ScrHeight)) ||
	      ((MyWinPos==1) && (y<(OnGoWin->TopEdge+2)))) {
	      UnHideWindow();
	      DPRINT("Plip!\n",0);
	    } // if in place
	  } // if ActiveScreen is workbench
	} else {
	  DPRINT("Unable to lock workbench\n",0);
	}
      } // if AutoHide
    } else {
      DPRINT("OnGo: Strange sret\n",0);
    }
  } // while

} // mainloop


//**** Main

void main(int argc, char **argv) {
  if (TRUE==OpenLibs()) {
    InitTree();
    InitGrList();
    ReadPrefs(argc, argv);
    if (TRUE==MyBeginCX()) {
      MyMenus=MyMenuMake(ToolsFileName);
      MainLoop();
      MyCloseWindow();
      MyMenuFree(MyMenus);
      MyEndCX();
    } else {
      DPRINT("OnGo: BeginCX() failed\n",0);
      //Error: MyBeginCX() failed
      // Already running?
    } // if begincx
    FreePrefs();
    DeleteLevel();
    FlushNodesGr();
    CloseLibs();
  } else {
    DPRINT("OnGo: Cannot open libs\n",0);
  } // if openlibs
} // main

//******** End of file

