/*
 * file ckmrem.c
 *
 * Module of MacKermit containing code for remote commands and the display
 * of remote commands.
 *
 */

/*
 Copyright (C) 1985, Trustees of Columbia University in the City of New York.
 Permission is granted to any individual or institution to use, copy, or
 redistribute this software so long as it is not sold for profit, provided this
 copyright notice is retained. 
*/

#include "ckcker.h"
#include "ckmdef.h"			/* General Mac defs */
#include "ckmres.h"			/* Resource file defs */
#include "mac/quickdraw.h"		/* Macintosh C interface */
#include "mac/osintf.h"
#include "mac/toolintf.h"
#include "mac/packintf.h"

int isbehind;

typedef struct {
  int resid;
  char scode,*name,*hlp1,*hlp2;
} RCMDTBL;

RCMDTBL remotecmds[] = {
  {CWD_REMO,  'C',  "CWD",        "Directory",  "Password"},
  {DEL_REMO,  'E',  "Delete",     "Filespec",   ""},
  {DIR_REMO,  'D',  "Directory",  "Filespec",   ""},
  {HELP_REMO, 'H',  "Help",       "Topic",      ""},
  {HOST_REMO, ' ',  "Host",       "Command",    ""},
  {SPAC_REMO, 'U',  "Space",      "Area",       ""},
  {TYPE_REMO, 'T',  "Type",       "Filespec",   ""},
  {WHO_REMO,  'W',  "Who",        "User ID",    "Options"},
  {0,0,NILPTR,NILPTR,NILPTR}};


/* Remote command dialog */

/*
 * remotedialog - returns FALSE if cancel hit, TRUE otherwise with
 *    	      	  generic command setup in gstr.
 *
 */

int remotedialog(rid,gstr)
int rid;
char *gstr;
{
 int itemhit,itemtype,i;
 DialogPtr remoteDialog;
 Handle itemhdl;
 Rect itemrect;
 RCMDTBL *rcmdh = (RCMDTBL *) NULL;
 char arg1[256],arg2[256];

 for (i=0; remotecmds[i].resid != 0; i++) /* locate remote command */
  if (remotecmds[i].resid == rid)	/* record for this command */
   rcmdh = &remotecmds[i];		/* set our handle */
 
 if (rcmdh == (RCMDTBL *) NULL)		/* find anything? */
 {
  printerr("Can't find remote command info for ",rid); /* ugh... */
  return(FALSE);
 }
 
 remoteDialog = GetNewDialog(REMOTEBOXID,NILPTR,(WindowPtr) -1);
 ParamText(rcmdh->name,rcmdh->hlp1,rcmdh->hlp2,"");	/* setup variables */
 
 if (strlen(rcmdh->hlp2) == 0)		/* second argument? */
 {					/* no, remove from screen */
  GetDItem(remoteDialog,RRES_ARG2,&itemtype,&itemhdl,&itemrect);
  if (itemtype != editText)
    printerr("RRES_ARG2 is not editText!",0); /* ugh now we die! */
  itemtype |= itemDisable;		/* disable it */
  SetRect(&itemrect,1044,20,1145,116);	/* off the end of our world */
  SetDItem(remoteDialog,RRES_ARG2,itemtype,itemhdl,&itemrect);
 }

 ShowWindow(remoteDialog);
 
 for (;;) {
  
   ModalDialog(NILPROC,&itemhit);
   switch (itemhit) {
     case OKBtn:
       GetDItem(remoteDialog,RRES_ARG1,&itemtype,&itemhdl,&itemrect);
       GetIText(itemhdl,arg1);
       GetDItem(remoteDialog,RRES_ARG2,&itemtype,&itemhdl,&itemrect);
       GetIText(itemhdl,arg2);
       if (rid == HOST_REMO)
	strcpy(gstr,arg1);
       else
        setgen(gstr,rcmdh->scode,arg1,arg2,""); /* setup the command */
       
     case QuitBtn:			/* fall through */
       DisposDialog(remoteDialog);	/* all done, answer on cterm screen */
       if (itemhit == OKBtn)		/* want to do the command?/ */
       {
	 conoc(CR);			/* output CR to delimit */
	 conoll("-----");		/* and dashes followed by CR */
         if (isbehind)			/*  response window behind?/ */
	  rcmdwshow();			/*  yes, so show it */
       }
       return(itemhit == OKBtn);	/* and return ok or bad... */
   }
 }
}


/* Remote command response window */

extern MenuHandle menus[];

WindowPtr rcmdwindow;
WindowRecord rcmdwr;
Rect teviewr,dragrect,growrect;
TEHandle teh;
ControlHandle vscroll,hscroll;
Point theorigin;


/* initrcmdw - ini */

initrcmdw() {
WindowPtr oldw;

  isbehind = TRUE;			/* from 0 above */

  GetPort(&oldw);			/* save old stuff */
  rcmdwindow = GetNewWindow(RCMDBOXID,&rcmdwr,(WindowPtr) 0);
  SetPort(rcmdwindow);			/* set new stuff */  
  
  SetWTitle(rcmdwindow,"Remote Commands");
  SetWRefCon(rcmdwindow,RCD_WREF);	/* setup reference handle */
  
  vscroll = GetNewControl(RCMDVSCROLL,rcmdwindow);
  SetCtlMin(vscroll,0);			/* min is always zero */
  SetCtlMax(vscroll,0);			/* max starts at zero */
  
  hscroll = GetNewControl(RCMDHSCROLL,rcmdwindow);
  SetCtlMin(hscroll,0);			/* min is always zero */
  
  sizescrollbars();			/* make controls adjust to wind size */
  sizeteviewr();			/* resize text edit rect */  
  
  teh = TENew(&teviewr,&teviewr);	/* create text edit portion */
  (*teh)->crOnly = -1;			/* only break lines at CR */
  (*teh)->txFont = monaco;		/* fixed spaced font */
  (*teh)->txSize = 12;			/* 12 pts (big) */
  consette(teh);			/* setup for low lvl console rtns */
  
  theorigin.h = 0;
  theorigin.v = 0;
  SetRect(&dragrect,4,24,508,338);
  SetRect(&growrect,100,60,512,302);

  SetPort(oldw);			/* restore old stuff */  

}

togglercmdw()
{
  if (isbehind)
   rcmdwshow();
  else
   rcmdwhide();
}

rcmdwhide()
{
  HideWindow(rcmdwindow);		/* hide it */
  HideControl(vscroll);			/* these will be shown on select */
  HideControl(hscroll);  
  SetItem(menus[REMO_MENU],RESP_REMO,"Show Response");
  isbehind = TRUE;
}

rcmdwshow()
{
  ShowWindow(rcmdwindow);		/* show it */  
  BringToFront(rcmdwindow);  
  SelectWindow(rcmdwindow);
  SetItem(menus[REMO_MENU],RESP_REMO,"Hide Response");
  isbehind = FALSE;
}

/* rcdactivate - activate event on rcd window */

rcdactivate(mod)
{
  WindowPtr oldw;
  
  GetPort(&oldw);
  SetPort(rcmdwindow);

  DrawGrowIcon(rcmdwindow);
  if (mod & activeFlag)
  {
/*  TEActivate(teh); */
    ShowControl(vscroll);
    ShowControl(hscroll);
  } 
  else {
/*  TEDeactivate(teh); */
    HideControl(vscroll);
    HideControl(hscroll);
  }
  SetPort(oldw);
}

/* rcdmouse - mouse event on rcd window */

rcdmouse(wcode,evt)
EventRecord *evt;
{
  int actrlcode,scroll(),t;
  ControlHandle acontrol;
  WindowPtr oldw;

  GetPort(&oldw);
  SetPort(rcmdwindow);

  switch (wcode) {
    case inDrag:
      DragWindow(rcmdwindow,&evt->where,&dragrect);
      break;

    case inGoAway:
      if (TrackGoAway(rcmdwindow,&evt->where))
      	rcmdwhide();			/* put it away */
      break;

    case inGrow:
      if (rcmdwindow == FrontWindow())
      	growwindow(rcmdwindow,&evt->where);
      else
      	SelectWindow(rcmdwindow);
      break;

    case inContent:
      if (rcmdwindow != FrontWindow())
      {
      	SelectWindow(rcmdwindow);
	break;
      }

      GlobalToLocal(&evt->where);	/* convert to local */
      if (PtInRect(&evt->where,&teviewr)) /* in text edit? */
      	break;				/* yes, do nothing */
      actrlcode = FindControl(&evt->where,rcmdwindow,&acontrol);
      switch (actrlcode) {
	case inUpButton:
	  t = TrackControl(acontrol,&evt->where,scroll);
	  break;
	case inDownButton:
	  t = TrackControl(acontrol,&evt->where,scroll);
	  break;
	case inPageUp:
	  pagescroll(actrlcode,-10,acontrol);
	  break;
	case inPageDown:
	  pagescroll(actrlcode,10,acontrol);
	  break;
	case inThumb:
	  t = TrackControl(acontrol,&evt->where,(ProcPtr)NIL);
	  scrollbits();
	  break;
      }
   }   
   SetPort(oldw);			/* back to old space */
}


growwindow(w,p)
WindowPtr w;
Point *p;
{
  int gr;
  int height,width;
  Rect tmpr;

  gr = GrowWindow(w,p,&growrect);
  if (gr == 0)
    return;
  height = HiWord(gr);
  width = LoWord(gr);

  SizeWindow(w,width,height,TRUE);	/* size the window */
  sizescrollbars();			/* size the scroll bars */
  sizeteviewr();			/* size for text edit */
  (*teh)->viewRect = teviewr;		/* set it */
  InvalRect(&w->portRect);		/* cause all to be redrawn */
}

rcdupdate(w)
WindowPtr w;
{
  ClipRect(&w->portRect);
  EraseRect(&w->portRect);
  DrawGrowIcon(w);
/*  setscrollmax();			/* set our max */
  DrawControls(w);
  TEUpdate(&teviewr,teh);
}

scrollbits()
{
  Point oldorigin;
  int dh,dv;

  oldorigin = theorigin;
  theorigin.h = GetCtlValue(hscroll);
  theorigin.v = GetCtlValue(vscroll);
  dh = (oldorigin.h - theorigin.h);
  dv = (oldorigin.v - theorigin.v) * (*teh)->lineHeight;
  TEScroll(dh,dv,teh);
}

rcdwscroll()
{
 WindowPtr oldw;
 int ctlm;
 
 GetPort(&oldw);
 SetPort(rcmdwindow);			/* our window is the port */
 setscrollmax();			/* set the max */
 SetCtlValue(vscroll,GetCtlMax(vscroll)); /* and set control */
 scrollbits();				/* do scroll */
 SetPort(oldw);				/* back to old port */
}

struct tcargs {
  short theCode;
  ControlHandle whichControl;
};

scroll()
{
  struct tcargs a;
  register int amount = 0;

  getpargs(&a,sizeof a);
  
  if (a.theCode == inUpButton) amount = -1;
  if (a.theCode == inDownButton) amount = 1;
  if (amount == 0) return;
  SetCtlValue(a.whichControl,GetCtlValue(a.whichControl)+amount);
  scrollbits();
}

pagescroll(code,amount,ctrlh)
ControlHandle ctrlh;
{
  Point myPt;

  do {
      GetMouse(&myPt);
      if (TestControl(ctrlh, &myPt) != code)
      	continue;
      SetCtlValue(ctrlh,GetCtlValue(ctrlh)+amount);
      scrollbits();
     } while (StillDown());
}

/* setscrollmax - sets the vertical scroll control's maximum value.
 *    	      	  The max is the total number of lines in the te record
 *    	      	  minus the number of lines that can be displayed in the
 *    	      	  viewing rectangle (plus 1).  This makes the max setting
 *    	      	  of the control result in the display of the last chunk
 *    	      	  of text.
 */

setscrollmax()
{
 int maxv;

 maxv = (*teh)->nLines + 1 -
     (((*teh)->viewRect.bottom-(*teh)->viewRect.top)/(*teh)->lineHeight);
 if (maxv < 0)				/* for less than one page */
  maxv = 0;				/*  use this value as max */
 SetCtlMax(vscroll,maxv);		/* set it... */
}
 
/* sizescrollbars - called when window is created and after a window grow
 *    	      	    sequence to resize the scroll window's bars.
 */
 
sizescrollbars()
{
  register Rect *r;
  
  r = &rcmdwindow->portRect;		/* window size */
  HideControl(vscroll);
  HideControl(hscroll);
  
/*  setscrollmax();			/* set vertical scroll max */
  MoveControl(vscroll,r->right-15,r->top-1);
  SizeControl(vscroll,16,r->bottom-r->top-13);

  MoveControl(hscroll,r->left-1,r->bottom-15);
  SizeControl(hscroll,r->right-r->left-13,16);
  
  ShowControl(vscroll);  
  ShowControl(hscroll);
}

sizeteviewr()
{
  teviewr = rcmdwindow->portRect;
  teviewr.left = teviewr.left+4; 
  teviewr.right = teviewr.right-15;
  teviewr.bottom = teviewr.bottom-15;
}
