#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <libraries/reqtools.h>
#include <libraries/dos.h>
#include <clib/reqtools_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/macros.h>


#include "afcopy_defines.h"
#include "afcopy_protos.h"
#include "afcopy_vars.h"          /* define external vars */


#define SPACEBETWEENGADGETS 0

char *upcase(char *str)
{
  // converts str into uppercase and returns a pointer to a new
  // string.
  // returns NULL if it fails.

  char *outstr=NULL;
  short loop;

  if (outstr=strdup(str))
  {
    for (loop=0;str[loop];loop++) outstr[loop]=toupper(str[loop]);
  }
  return(outstr);
}

short position(char *substr,char *str)
{
  // returns an character offset of a substring in a string
  // this version is CASE SENSITIVE
  // returns -1 if substring not found in the string

  char *whstr;
  return((short)((whstr=strstr(str,substr)) ? (short)((LONG)whstr-(LONG)str) : -1));
}

short iposition(char *substr,char *str)
{
  // returns an character offset of a substring in a string
  // this version is CASE INSENSITIVE
  // returns -1 if substring not found in the string
  //      or -2 if memory allocation error

  short where=-2;
  char *isubstr,*istr;

  if (isubstr=upcase(substr))
  {
    if (istr=upcase(str))
    {
      where=position(isubstr,istr);
      free(isubstr);
    }
    free(istr);
  }
  return(where);
}

void strpad(char *str,int newlength)
{
  short loop;

// slow way of doing it ..  while (strlen(str)<newlength) strcat(str," ");

  for (loop=strlen(str);loop<newlength;loop++)
  {
    str[loop]=32;
  }
  str[newlength]=0;
}

void OutTextXY(struct Window *Win,UWORD X,UWORD Y, char *string)
{
  Move(Win->RPort,X,Y);
  Text(Win->RPort,string,strlen(string) < 70 ? strlen(string) : 70);
}

void addterm(char *s)
{
  if (s[strlen(s)-1]!=':' && s[strlen(s)-1]!='/') strcat(s,"/");
}

void delterm(char *s)
{
  if (s[strlen(s)-1]=='/') s[strlen(s)-1]='\0';
}

void getparent(char *s)
{
  int l;

  addterm(s);
  l=strlen(s);
  if (s[l-1]=='/')
  {
    l--;
    while (s[l-1]!='/' && s[l-1]!=':') l--;
    s[l]='\0';
  }
}

BOOL inrect(int X,int Y,int X1,int Y1,int X2, int Y2)
{
  if (X>=X1 && X<=X2 && Y>=Y1 && Y<=Y2) return(TRUE); else return(FALSE);
}

void IoErrMsg(char *MsgString,int ErrorNum)
{
  switch (ErrorNum)
  {
    case 1:strcpy(MsgString,"Operation Cancelled");break;
    case 103:strcpy(MsgString,"No Free Store");break;
    case 105:strcpy(MsgString,"Task Table Full");break;
    case 114:strcpy(MsgString,"Bad Template");break;
    case 115:strcpy(MsgString,"Bad Number");break;
    case 116:strcpy(MsgString,"Required Arg Missing");break;
    case 117:strcpy(MsgString,"Key Needs Arg");break;
    case 118:strcpy(MsgString,"Too Many Args");break;
    case 119:strcpy(MsgString,"Unmatched Quotes");break;
    case 120:strcpy(MsgString,"Line Too Long");break;
    case 121:strcpy(MsgString,"File Not Object");break;
    case 122:strcpy(MsgString,"Invalid Resident Library");break;
    case 201:strcpy(MsgString,"No Default Dir");break;
    case 202:strcpy(MsgString,"Object In Use");break;
    case 203:strcpy(MsgString,"Object Exists");break;
    case 204:strcpy(MsgString,"Dir Not Found");break;
    case 205:strcpy(MsgString,"Object Not Found");break;
    case 206:strcpy(MsgString,"Bad Stream Name");break;
    case 207:strcpy(MsgString,"Object Too Large");break;
    case 209:strcpy(MsgString,"Action Not Known");break;
    case 210:strcpy(MsgString,"Invalid Component Name");break;
    case 211:strcpy(MsgString,"Invalid Lock");break;
    case 212:strcpy(MsgString,"Object Wrong Type");break;
    case 213:strcpy(MsgString,"Disk Not Validated");break;
    case 214:strcpy(MsgString,"Disk Write Protected");break;
    case 215:strcpy(MsgString,"Rename Across Devices");break;
    case 216:strcpy(MsgString,"Directory Not Empty");break;
    case 217:strcpy(MsgString,"Too Many Levels");break;
    case 218:strcpy(MsgString,"Device Not Mounted");break;
    case 219:strcpy(MsgString,"Seek Error");break;
    case 220:strcpy(MsgString,"Comment Too Big");break;
    case 221:strcpy(MsgString,"Disk Full");break;
    case 222:strcpy(MsgString,"Delete Protected");break;
    case 223:strcpy(MsgString,"Write Protected");break;
    case 224:strcpy(MsgString,"Read Protected or Read Error");break;
    case 225:strcpy(MsgString,"Not a DOS Disk");break;
    case 226:strcpy(MsgString,"No Disk");break;
    case 232:strcpy(MsgString,"No More Entries");break;
    case 233:strcpy(MsgString,"Is Soft Link");break;
    case 234:strcpy(MsgString,"Object Linked");break;
    case 235:strcpy(MsgString,"Bad Hunk");break;
    case 236:strcpy(MsgString,"Not Implemented");break;
    case 240:strcpy(MsgString,"Record Not Locked");break;
    case 241:strcpy(MsgString,"Lock Collision");break;
    case 242:strcpy(MsgString,"Lock Timeout");break;
    case 243:strcpy(MsgString,"Unlock Error");break;
    default:strcpy(MsgString,"Undefined Error!");break;
  }
}

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

          Main Gadget And Gadget Config Routines.

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


struct Gadget *createAllGadgets(struct Gadget **glistptr, void *vi,
    UWORD topborder, struct Gadget *my_gads[])
{
  struct NewGadget ng;
  struct Gadget *gad;

  gad = CreateContext(glistptr);

  ng.ng_TopEdge    = 1+topborder;
  ng.ng_LeftEdge   = 286-18;
  ng.ng_Width      = 17;
  ng.ng_Height     = 11;
  ng.ng_TextAttr   = &ScreenFontAttr;
  ng.ng_VisualInfo = vi;

  ng.ng_GadgetText = "S";
  ng.ng_GadgetID   = G_SortLeft;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_SortLeft] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_LeftEdge   -= (ng.ng_Width+1);
  ng.ng_GadgetText = "D";
  ng.ng_GadgetID   = G_DisplayLeft;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_DisplayLeft] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_GadgetText = "S";
  ng.ng_LeftEdge   = 286+68+1;
  ng.ng_GadgetID   = G_SortRight;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_SortRight] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_LeftEdge   += (ng.ng_Width+1);
  ng.ng_GadgetText = "D";
  ng.ng_GadgetID   = G_DisplayRight;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_DisplayRight] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);


  ng.ng_Height     = (lines_per_side*FILEHEIGHT+83) / 23;
  ng.ng_Width      = 68;
  ng.ng_LeftEdge   = 286;
  ng.ng_GadgetText = "_Copy";
  ng.ng_GadgetID   = G_Copy;
  my_gads[G_Copy] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Swap";
  ng.ng_GadgetID   = G_Swap;
  my_gads[G_Swap] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Rename";
  ng.ng_GadgetID   = G_Rename;
  my_gads[G_Rename] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Delete";
  ng.ng_GadgetID   = G_Delete;
  my_gads[G_Delete] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Cl_one";
  ng.ng_GadgetID   = G_Clone;
  my_gads[G_Clone] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_View";
  ng.ng_GadgetID   = G_View;
  my_gads[G_View] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Re_ad";
  ng.ng_GadgetID   = G_Read;
  my_gads[G_Read] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Edit";
  ng.ng_GadgetID   = G_Edit;
  my_gads[G_Edit] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Hear";
  ng.ng_GadgetID   = G_Hear;
  my_gads[G_Hear] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Info";
  ng.ng_GadgetID   = G_Info;
  my_gads[G_Info] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "E_xecute";
  ng.ng_GadgetID   = G_Execute;
  my_gads[G_Execute] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Run";
  ng.ng_GadgetID   = G_Run;
  my_gads[G_Run] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Commen_t";
  ng.ng_GadgetID   = G_Comment;
  my_gads[G_Comment] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Protect";
  ng.ng_GadgetID   = G_Protect;
  my_gads[G_Protect] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Archive";
  ng.ng_GadgetID   = G_Archive;
  my_gads[G_Archive] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Unarc";
  ng.ng_GadgetID   = G_Unarc;
  my_gads[G_Unarc] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_MakeDir";
  ng.ng_GadgetID   = G_Makedir;
  my_gads[G_Makedir] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Mark";
  ng.ng_GadgetID   = G_Mark;
  my_gads[G_Mark] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "UnMark";
  ng.ng_GadgetID   = G_Unmark;
  my_gads[G_Unmark] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Reverse";
  ng.ng_GadgetID   = G_Reverse;
  my_gads[G_Reverse] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);
  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Dos";
  ng.ng_GadgetID   = G_Dos;
  my_gads[G_Dos] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "_Batch";
  ng.ng_GadgetID   = G_Batch;
  my_gads[G_Batch] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_TopEdge    += SPACEBETWEENGADGETS+ng.ng_Height;
  ng.ng_GadgetText = "Vo_lumes";
  ng.ng_GadgetID   = G_Volumes;
  my_gads[G_Volumes] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_LeftEdge   = filexpos[0]-1;
  ng.ng_TopEdge    = lines_per_side * FILEHEIGHT+2+FILEYPOS+topborder; /* + 2 to avoid border clash! */
  ng.ng_Width      = FILEWIDTH-12;
  ng.ng_Height     = 14;
  ng.ng_GadgetText = NULL;
  ng.ng_GadgetID   = G_Pathleft;
  my_gads[G_Pathleft] = gad = CreateGadget(STRING_KIND, gad, &ng,
                     GTST_String,   NULL,
                     GTST_MaxChars, 300,
                     TAG_END);
  ng.ng_LeftEdge   = filexpos[1]+14;
  ng.ng_Width      = ng.ng_Width;
  ng.ng_GadgetID   = G_Pathright;
  my_gads[G_Pathright] = gad = CreateGadget(STRING_KIND, gad, &ng,
                     GTST_String,   NULL,
                     GTST_MaxChars, 300,
                     TAG_END);
  ng.ng_LeftEdge   = 268;
  ng.ng_TopEdge    = FILEYPOS+topborder-1;
  ng.ng_Width      = 17;
  ng.ng_Height     = lines_per_side * FILEHEIGHT+2;
  ng.ng_GadgetText = NULL;
  ng.ng_GadgetID   = G_Sliderleft;
  ng.ng_Flags      = NG_HIGHLABEL;
  my_gads[G_Sliderleft] = gad = CreateGadget(SCROLLER_KIND, gad, &ng,
                     GTSC_Top,         0,
                     GTSC_Total,       1,
                     GTSC_Visible,     1,
                     GTSC_Arrows,      10,
                     PGA_Freedom,      LORIENT_VERT,
                     GT_Underscore,    '_',
                     TAG_END);

  ng.ng_LeftEdge   = 355;
  ng.ng_GadgetID   = G_Sliderright;
  my_gads[G_Sliderright] = gad = CreateGadget(SCROLLER_KIND, gad, &ng,
                     GTSC_Top,         0,
                     GTSC_Total,       1,
                     GTSC_Visible,     1,
                     GTSC_Arrows,      10,
                     PGA_Freedom,      LORIENT_VERT,
                     GT_Underscore,    '_',
                     TAG_END);
  ng.ng_LeftEdge   = 268;
  ng.ng_TopEdge   += ng.ng_Height+1;
  ng.ng_Width      = 17;
  ng.ng_Height     = 14;
  ng.ng_GadgetText = "/";
  ng.ng_GadgetID   = G_Parentleft;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_Parentleft] = gad = CreateGadget(BUTTON_KIND, gad, &ng,
                     TAG_END);
  ng.ng_Width      = 14;
  ng.ng_LeftEdge  -= ng.ng_Width+1;
  ng.ng_GadgetText = "R";
  ng.ng_GadgetID   = G_Regetleft;
  my_gads[G_Regetleft] = gad = CreateGadget(BUTTON_KIND, gad, &ng,
                     TAG_END);

  ng.ng_LeftEdge   = 355;
  ng.ng_Width      = 17;
  ng.ng_GadgetID   = G_Parentright;
  ng.ng_GadgetText = "/";
  my_gads[G_Parentright] = gad = CreateGadget(BUTTON_KIND, gad, &ng,
                     TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_Width      = 14;
  ng.ng_GadgetText = "R";
  ng.ng_GadgetID   = G_Regetright;
  my_gads[G_Regetright] = gad = CreateGadget(BUTTON_KIND, gad, &ng,
                     TAG_END);

/* Device Gadgets Bottom Left First Row */

  ng.ng_LeftEdge   = filexpos[0]-1;
  ng.ng_TopEdge   += ng.ng_Height+1;
  ng.ng_Width      = 45;
  ng.ng_Height     = 10;
  ng.ng_GadgetText = devicegadnames[0][0];
  ng.ng_GadgetID   = G_Deviceleft0;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_Deviceleft0] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][1];
  ng.ng_GadgetID   = G_Deviceleft1;
  my_gads[G_Deviceleft1] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][2];
  ng.ng_GadgetID   = G_Deviceleft2;
  my_gads[G_Deviceleft2] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][3];
  ng.ng_GadgetID   = G_Deviceleft3;
  my_gads[G_Deviceleft3] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][4];
  ng.ng_GadgetID   = G_Deviceleft4;
  my_gads[G_Deviceleft4] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][5];
  ng.ng_GadgetID   = G_Deviceleft5;
  ng.ng_Width      = 44;
  my_gads[G_Deviceleft5] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* Device Gadgets Bottom Right First Row */

  ng.ng_LeftEdge   = 355;
  ng.ng_Width      = 45;
  ng.ng_GadgetText = devicegadnames[1][0];
  ng.ng_GadgetID   = G_Deviceright0;
  my_gads[G_Deviceright0] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][1];
  ng.ng_GadgetID   = G_Deviceright1;
  my_gads[G_Deviceright1] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][2];
  ng.ng_GadgetID   = G_Deviceright2;
  my_gads[G_Deviceright2] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][3];
  ng.ng_GadgetID   = G_Deviceright3;
  my_gads[G_Deviceright3] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][4];
  ng.ng_GadgetID   = G_Deviceright4;
  my_gads[G_Deviceright4] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][5];
  ng.ng_GadgetID   = G_Deviceright5;
  ng.ng_Width      = 44;
  my_gads[G_Deviceright5] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);


/* Device Gadgets Bottom Left Second Row */

  ng.ng_LeftEdge   = filexpos[0]-1;
  ng.ng_Width      = 45;
  ng.ng_TopEdge   += ng.ng_Height+1;
  ng.ng_GadgetText = devicegadnames[0][6];
  ng.ng_GadgetID   = G_Deviceleft6;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_Deviceleft6] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][7];
  ng.ng_GadgetID   = G_Deviceleft7;
  my_gads[G_Deviceleft7] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][8];
  ng.ng_GadgetID   = G_Deviceleft8;
  my_gads[G_Deviceleft8] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][9];
  ng.ng_GadgetID   = G_Deviceleft9;
  my_gads[G_Deviceleft9] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][10];
  ng.ng_GadgetID   = G_Deviceleft10;
  my_gads[G_Deviceleft10] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[0][11];
  ng.ng_GadgetID   = G_Deviceleft11;
  ng.ng_Width      = 44;
  my_gads[G_Deviceleft11] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* Device Gadgets Bottom Right Second Row */

  ng.ng_LeftEdge   = 355;
  ng.ng_Width      = 45;
  ng.ng_GadgetText = devicegadnames[1][6];
  ng.ng_GadgetID   = G_Deviceright6;
  my_gads[G_Deviceright6] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][7];
  ng.ng_GadgetID   = G_Deviceright7;
  my_gads[G_Deviceright7] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][8];
  ng.ng_GadgetID   = G_Deviceright8;
  my_gads[G_Deviceright8] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][9];
  ng.ng_GadgetID   = G_Deviceright9;
  my_gads[G_Deviceright9] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][10];
  ng.ng_GadgetID   = G_Deviceright10;
  my_gads[G_Deviceright10] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+2;
  ng.ng_GadgetText = devicegadnames[1][11];
  ng.ng_GadgetID   = G_Deviceright11;
  ng.ng_Width      = 44;
  my_gads[G_Deviceright11] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* User Gadgets Bottom Left First Row */

  ng.ng_LeftEdge   = filexpos[0]-1;
  ng.ng_TopEdge   += ng.ng_Height+1;
  ng.ng_Width      = 55;
  ng.ng_Height     = 10;
  ng.ng_GadgetText = usergadnames[0][0];
  ng.ng_GadgetID   = G_Userleft0;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_Userleft0] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][1];
  ng.ng_GadgetID   = G_Userleft1;
  my_gads[G_Userleft1] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][2];
  ng.ng_GadgetID   = G_Userleft2;
  my_gads[G_Userleft2] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][3];
  ng.ng_GadgetID   = G_Userleft3;
  my_gads[G_Userleft3] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][4];
  ng.ng_GadgetID   = G_Userleft4;
  my_gads[G_Userleft4] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* User Gadgets Bottom Right First Row */

  ng.ng_LeftEdge   = 355;
  ng.ng_GadgetText = usergadnames[1][0];
  ng.ng_GadgetID   = G_Userright0;
  my_gads[G_Userright0] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][1];
  ng.ng_GadgetID   = G_Userright1;
  my_gads[G_Userright1] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][2];
  ng.ng_GadgetID   = G_Userright2;
  my_gads[G_Userright2] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][3];
  ng.ng_GadgetID   = G_Userright3;
  my_gads[G_Userright3] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][4];
  ng.ng_GadgetID   = G_Userright4;
  my_gads[G_Userright4] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);


/* User Gadgets Bottom Left Second Row */

  ng.ng_LeftEdge   = filexpos[0]-1;
  ng.ng_TopEdge   += ng.ng_Height+0;
  ng.ng_GadgetText = usergadnames[0][5];
  ng.ng_GadgetID   = G_Userleft5;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_Userleft5] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][6];
  ng.ng_GadgetID   = G_Userleft6;
  my_gads[G_Userleft6] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][7];
  ng.ng_GadgetID   = G_Userleft7;
  my_gads[G_Userleft7] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][8];
  ng.ng_GadgetID   = G_Userleft8;
  my_gads[G_Userleft8] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][9];
  ng.ng_GadgetID   = G_Userleft9;
  my_gads[G_Userleft9] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* User Gadgets Bottom Right Second Row */

  ng.ng_LeftEdge   = 355;
  ng.ng_GadgetText = usergadnames[1][5];
  ng.ng_GadgetID   = G_Userright5;
  my_gads[G_Userright5] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][6];
  ng.ng_GadgetID   = G_Userright6;
  my_gads[G_Userright6] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][7];
  ng.ng_GadgetID   = G_Userright7;
  my_gads[G_Userright7] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][8];
  ng.ng_GadgetID   = G_Userright8;
  my_gads[G_Userright8] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][9];
  ng.ng_GadgetID   = G_Userright9;
  my_gads[G_Userright9] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* User Gadgets Bottom Left third Row */

  ng.ng_LeftEdge   = filexpos[0]-1;
  ng.ng_TopEdge   += ng.ng_Height+0;
  ng.ng_GadgetText = usergadnames[0][10];
  ng.ng_GadgetID   = G_Userleft10;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  my_gads[G_Userleft10] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][11];
  ng.ng_GadgetID   = G_Userleft11;
  my_gads[G_Userleft11] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][12];
  ng.ng_GadgetID   = G_Userleft12;
  my_gads[G_Userleft12] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][13];
  ng.ng_GadgetID   = G_Userleft13;
  my_gads[G_Userleft13] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[0][14];
  ng.ng_GadgetID   = G_Userleft14;
  my_gads[G_Userleft14] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/* User Gadgets Bottom Right third Row */

  ng.ng_LeftEdge   = 355;
  ng.ng_GadgetText = usergadnames[1][10];
  ng.ng_GadgetID   = G_Userright10;
  my_gads[G_Userright10] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][11];
  ng.ng_GadgetID   = G_Userright11;
  my_gads[G_Userright11] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][12];
  ng.ng_GadgetID   = G_Userright12;
  my_gads[G_Userright12] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][13];
  ng.ng_GadgetID   = G_Userright13;
  my_gads[G_Userright13] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);
  ng.ng_LeftEdge  += ng.ng_Width+1;
  ng.ng_GadgetText = usergadnames[1][14];
  ng.ng_GadgetID   = G_Userright14;
  my_gads[G_Userright14] = gad = CreateGadget(BUTTON_KIND, gad, &ng,TAG_END);

/*
 * Keys used in underscore of gadgets are as follows...
 *
 * CSRDOVEAHXTPUM
 * S Swap
 * R Rename
 * D Delete
 * O Clone
 * V View
 * E Edit
 * A Read
 * H Hear
 *

 * Keys that'll be used for other stuff
 *
 * ' Run
 * + Mark All
 * - Mark All
 * * Reverse Marks
 *
 */

return(gad);
}


void blankusergads( void )
{
  int loop1,loop2;
  for (loop1=0;loop1<2;loop1++)
  {
    for (loop2=0;loop2<10;loop2++)
    {
      strcpy(usergadnames[loop1][loop2],"");
      strcpy(usergadactual[loop1][loop2],"");
      usergadflags[loop1][loop2]=0;
    }
  }
}

void strfcpy(char *dest,char *source,int from)
{
  /*
     copy all chars from "source" to "dest" starting at offset "from"
     (kinda the reverse from strncpy() )
   */
  int loop=from,pos=0;
  if (from<=strlen(source)-1)
  {
    while (source[loop])
    {
      dest[pos]=source[loop];
      loop++;
      pos++;
    }
  }
  dest[pos]=0;
}


void stripcr(char *s)   /* Strips \n From End Of String */
{
  if (s[strlen(s)-1]==10) s[strlen(s)-1]=0;
}

void mfgets(char *str,int len,FILE *f)
{
  char c;

  fgets(str,len+2,f);  /* +1 for the ! and +1 cos array starts at 0 */
  c=fgetc(f);
  if (c!=10) ungetc(c,f);
  stripcr(str);
}

void swapem(short side,int i, int j)
{
  BOOL tag;
  char string[MAX_FILE_LEN+1];
  LONG type;
  struct DateStamp ds;
  strcpy(string,filename[side][i]);
  strcpy(filename[side][i],filename[side][j]);
  strcpy(filename[side][j],string);
  tag=filetags[side][i];
  filetags[side][i]=filetags[side][j];
  filetags[side][j]=tag;
  type=filetype[side][i];
  filetype[side][i]=filetype[side][j];
  filetype[side][j]=type;
  type=filesize[side][i];
  filesize[side][i]=filesize[side][j];
  filesize[side][j]=type;
  ds=filedate[side][i];
  filedate[side][i]=filedate[side][j];
  filedate[side][j]=ds;
}

void qsortdirs(short side,int l,int r)
{
  int i,j;
  int x;


#ifdef DEBUGALL
  puts("qsortdirs()");
#endif


  i=l;j=r;x=filetype[side][(l+r) / 2];
  do
  {
    while (filetype[side][i]>x) i++;
    while (x>filetype[side][j]) j--;
    if (i<=j)
    {
      swapem(side,i,j);

      i++;j--;
    }
  } while (i<=j);
  if (l<j) qsortdirs(side,l,j);
  if (i<r) qsortdirs(side,i,r);
}

void qsortall(short side,int l,int r)
{
  int i,j;
  LONG sz;
  char x[MAX_FILE_LEN+1];

#ifdef DEBUGALL
  puts("qsortall()");
#endif

  i=l;j=r;
  switch(sortmode[side])
  {
    case S_NAME:
      strcpy(x,filename[side][(l+r) / 2]);
      break;
    case S_DATE:
      sz=filedate[side][(l+r) / 2].ds_Days;
      break;
    case S_SIZE:
      sz=filesize[side][(l+r) / 2];
      break;
  }
  do
  {
    switch (sortmode[side])
    {
      case S_DATE:
        while (filedate[side][i].ds_Days>sz) i++;
        while (sz>filedate[side][j].ds_Days) j--;
        if (i<=j)
        {
          swapem(side,i,j);

          i++;j--;
        }
        break;
      case S_NAME:
        while (stricmp(filename[side][i],x)<0) i++;
        while (stricmp(x,filename[side][j])<0) j--;
        if (i<=j)
        {
          swapem(side,i,j);

          i++;j--;
        }
        break;
      case S_SIZE:
        while (filesize[side][i]>sz) i++;
        while (sz>filesize[side][j]) j--;
        if (i<=j)
        {
          swapem(side,i,j);

          i++;j--;
        }
        break;
    }
  } while (i<=j);
  if (l<j) qsortall(side,l,j);
  if (i<r) qsortall(side,i,r);
}


void qsortfiles(short side,int l,int r)
{
  int offs=0;

  if ((totalfiles[side]>0) && (sortmode[side]!=S_NONE) )
  {
    if (!mixfilesanddraws)
    {
      qsortdirs(side,l,r);
      while (offs<totalfiles[side] && filetype[side][offs]>0) offs++;
      qsortall(side,0, offs > 1 ? offs-1 : 0);
      if (offs!=totalfiles[side])
      {
        qsortall(side,offs,totalfiles[side]-1);
      }
    }
    else
    {
      qsortall(side,l,r);
    }
  }
}



BOOL DoDiskInfo(short side,char *path)
{
  BOOL retval=TRUE;
  BPTR FL;
  struct InfoData *di;
  char outputstr[51]="Error";

#ifdef DEBUG
  puts("DoDiskInfo()");
#endif

  if (pathok[side] && (FL=Lock(path,ACCESS_READ)))
  {
    if ((di=AllocMem(sizeof(struct InfoData),MEMF_PUBLIC)))
    {
      if (Info(FL,di))
      {
        sprintf(outputstr,"                 %3.0f%% %7.0fk",((float)di->id_NumBlocksUsed/(float)di->id_NumBlocks)*100,
               (float)((di->id_NumBlocks-di->id_NumBlocksUsed) * di->id_BytesPerBlock) / (float)1024);
        outputstr[35]='\0';
      }
      FreeMem(di,sizeof(struct InfoData));
    }
    UnLock(FL);
  }
  else
  {
    strcpy(outputstr,"No Directory");
    retval=FALSE;
  }
  strpad(outputstr,MAX_FILE_LEN);
  SetAPen(W->RPort,2);
  SetBPen(W->RPort,0);
  switch (side)
  {
    case 0:
      OutTextXY(W,filexpos[side]+2,FONTBASELINE+topborder+3,outputstr);
      DrawBevelBox(W->RPort,filexpos[side]-1,topborder+1,(FILEWIDTH+3)-17,11,
                   GT_VisualInfo,vi,TAG_DONE);
      break;
    case 1:
      OutTextXY(W,filexpos[side]+2+17,FONTBASELINE+topborder+3,outputstr);
      DrawBevelBox(W->RPort,filexpos[side]-1+17,topborder+1,(FILEWIDTH+3)-17,11,
                   GT_VisualInfo,vi,TAG_DONE);
      break;
  }
  updateselected(side);
  return(retval);
}

void clearside(short side)
{

#ifdef DEBUG
  puts("clearside()");
#endif

  SetAPen(W->RPort,0);
  SetBPen(W->RPort,0);
  RectFill(W->RPort,filexpos[side]+1,topborder+FILEYPOS,
                    filexpos[side]+FILEWIDTH-1,topborder+FILEYPOS+(FILEHEIGHT*lines_per_side)-1);
}

void updateslider(short side,int offset)
{
#ifdef DEBUG
  puts("updateslider()");
#endif

  GT_SetGadgetAttrs(my_gads[G_Sliderleft+side], W, NULL,
                    GTSC_Top, offset < lines_per_side ? 0 : offset+lines_per_side>totalfiles[side] ? totalfiles[side]-lines_per_side : offset,
                    GTSC_Total, totalfiles[side],
                    GTSC_Visible, totalfiles[side] < lines_per_side ? totalfiles[side] : lines_per_side,
                    TAG_END);
}

void replace(char *dest,char *compare,char *from,char *to)
{

  /*
     replace all occurences of "from" in "compare" with "to" and store result in "dest"
     (note: this is dead usefull!!!)
   */
  int where;
  char *mystring=strdup(compare);

  strcpy(dest,"");

  do
  {
    where=position(from,mystring);
    if (where!=-1)
    {
      strncat(dest,mystring,where);                    /* copy first part of string */
      strcat(dest,to);                                 /* add repeaced chars */
      strfcpy(mystring,mystring,where+strlen(from));   /* copy rest of string  so we find first position of from */
    }
  } while (where!=-1);                                 /* keep doing until "from" is not found */
  strcat(dest,mystring);                               /* add the rest of the string */
}

void getextension(char *dest,char *source)
{
  int loop;

  strcpy(dest,"");
  if (position(".",source)!=-1)
  {
    for (loop=strlen(source);source[loop-1]!='.';loop--);
    strfcpy(dest,source,loop);
  }
}

void getname(char *dest,char *source)
{
  int loop;

  if (position(".",source)!=-1)
  {
    strcpy(dest,"");
    for (loop=strlen(source)-1;source[loop]!='.';loop--);
    strncpy(dest,source,loop);  /* copy from start to position of last "." in "source" -1 */
    dest[loop]='\0'; /* due to an error with strncpy!!! */
  }
  else strcpy(dest,source);
}


void createstring(char *tmpstr,char *batchstr,short side,int current,int opts)
{
  char temp[33]="";


  switch (opts)
  {
    case CS_ALL:
      replace(tmpstr,batchstr,"@F@",filename[side][current]);
      /* note: there is no, and should not be, a "break;" here. */
    case CS_NOFILES:
      getextension(temp,filename[side][current]);
      if (stricmp(temp,"")) replace(tmpstr,tmpstr,"@E@",temp);
      getname(temp,filename[side][current]);
      if (stricmp(temp,"")) replace(tmpstr,tmpstr,"@N@",temp);
      replace(tmpstr,tmpstr,"@<@",cpath[side]);
      replace(tmpstr,tmpstr,"@>@",cpath[1-side]);
      replace(tmpstr,tmpstr,"@S@",screenname);
      break;
  }
}


struct Gadget *createStatGadgets(struct Gadget **glistptr, void *vi,
    UWORD topborder, struct Gadget *gads[])
{
  struct NewGadget ng;
  struct Gadget *gad;

#ifdef DEBUG
  puts("createStatGadgets()");
#endif

  gad = CreateContext(glistptr);

  ng.ng_LeftEdge   = 5;
  ng.ng_TopEdge    = 1+topborder;
  ng.ng_Width      = STATWIDTH-10;
  ng.ng_Height     = 10;
  ng.ng_GadgetText = "Cancel";
  ng.ng_TextAttr   = &ScreenFontAttr;
  ng.ng_VisualInfo = vi;
  ng.ng_GadgetID   = G_StatCancel;
  ng.ng_Flags      = NG_HIGHLABEL|PLACETEXT_IN;
  gads[G_StatCancel] = gad = CreateGadget(BUTTON_KIND, gad, &ng,GT_Underscore, '_',TAG_END);

  ng.ng_LeftEdge   = 5;
  ng.ng_TopEdge    = topborder+55;
  ng.ng_Width      = STATWIDTH-10;
  ng.ng_Height     = 64;
  ng.ng_GadgetText = NULL;
  ng.ng_VisualInfo = vi;
  ng.ng_GadgetID   = G_ErrorList;
  ng.ng_Flags      = 0L;
  gads[G_ErrorList] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng,
                                          GTLV_Labels,ErrorList,
                                          GTLV_Top,0,
                                          GTLV_ScrollWidth,20,
                                          TAG_END);
  return(gad);
}

struct Window *OpenStatWindow(void)

{

  struct Window *win;
  if (win=OpenWindowTags(NULL,
                          WA_Left,W->LeftEdge+STATLEFT,
                          WA_Top,W->TopEdge+STATTOP,
                          WA_Width,STATWIDTH,
                          WA_Height,STATHEIGHT,
                          WA_AutoAdjust,    FALSE,
                          WA_DragBar,       TRUE,
                          WA_DepthGadget,   TRUE,
                          WA_Activate,      TRUE,
                          WA_SmartRefresh,  TRUE,
                          WA_Zoom,          zoomcoords,
                          WA_IDCMP,         BUTTONIDCMP | LISTVIEWIDCMP,
                          WA_Title,"Status!",
                          WA_PubScreen, mysc,
                          WA_Gadgets,statglist,
                          WA_ScreenTitle,screentitle,
                          TAG_END))
  {
    GT_RefreshWindow(win, NULL);
  }
  return(win);
}

void remspaces(char *dest,char *source)
{
  /* remove white space space from the front of a string */
  while (source[0]==' ' || source[0]=='\t') strfcpy(dest,source,1);
}
