#include <ctype.h>
#include "includes.h"
#include <dos/dostags.h>

#include "vars.h"

/* This file contains empty template routines that
 * the IDCMP handler will call uppon. Fill out these
 * routines with your code or use them as a reference
 * to create your program.
 */

void DoAbout( void )
{
  rtEZRequestTags("Associate, A nice WB Util By Hydra/LSD\n"
                  "\n"
                  "This program is FreeWare! so spread and use it\n"
                  "but do NOT modify it in ANY way at all.\n"
                  "\n"
                  "Permission is GRANTED to use this in\n"
                  "any commercial program, it can also be\n"
                  "included on coverdisks and such like\n",
                  "Cool!",
                  NULL,NULL,RTGS_Flags, GSREQF_CENTERTEXT,
                  RT_Window,AssociateWnd,TAG_END);
}

BOOL SelectFile(char *Filename,char *title,char *wildcards)
{
  char *dirname;
  short chars;
  BOOL retval=FALSE;
	strcpy(tmpstr,FilePart(Filename));

  chars=(short)((int)PathPart(Filename)-(int)Filename);
  if (dirname=AllocMem(chars+1,MEMF_PUBLIC|MEMF_CLEAR))
  {
    strncpy(dirname,Filename,chars);
    rtChangeReqAttr(filereq,RTFI_MatchPat,wildcards,
                            RTFI_Dir, dirname,
                            TAG_DONE);

    if (rtFileRequest (filereq, tmpstr, title,RTFI_Flags,FREQF_PATGAD,TAG_END))
    {
      strcpy(Filename,filereq->Dir);
      AddPart(Filename,tmpstr,MAX_TEMP_STR_LEN);
      retval=TRUE;
    }
    FreeMem(dirname,chars+1);
  }
  return(retval);
}

struct TypeNode *FindTypeNode( void )
{
  struct TypeNode *node=NULL;
  LONG num;

  if (1==GT_GetGadgetAttrs(AssociateGadgets[GD_TypeList],AssociateWnd,NULL,
                    GTLV_Selected,&num,
                    TAG_DONE))
  {
    if (num>=0)
    {
      node=(struct TypeNode *) GetNode(typelist,num);
    }
  }
  return(node);
}

void UpdateLists( void )
{
  GT_SetGadgetAttrs(AssociateGadgets[GD_TypeList], AssociateWnd, NULL,
                    GTLV_Labels, (ULONG)typelist,
                    TAG_END);

  if (temptnode=FindTypeNode())
  {
    GT_SetGadgetAttrs(AssociateGadgets[GD_NamePList], AssociateWnd, NULL,
                      GTLV_Labels, (ULONG)temptnode->nameplist,
                      TAG_END);
    GT_SetGadgetAttrs(AssociateGadgets[GD_FilePList], AssociateWnd, NULL,
                      GTLV_Labels, (ULONG)temptnode->fileplist,
                      TAG_END);
    GT_SetGadgetAttrs(AssociateGadgets[GD_IconStr], AssociateWnd, NULL,
                      GA_Disabled, FALSE,
                      GTST_String, temptnode->IconName,
                      TAG_END);
    GT_SetGadgetAttrs(AssociateGadgets[GD_IconRun],AssociateWnd,NULL,
                      GA_Disabled, FALSE,
                      GTCB_Checked,temptnode->RunInfo,
                      TAG_DONE);
    GT_SetGadgetAttrs(AssociateGadgets[GD_IconInfo],AssociateWnd,NULL,
                      GA_Disabled, FALSE,
                      TAG_DONE);
  }
  else // blank the lists..
  {
    GT_SetGadgetAttrs(AssociateGadgets[GD_NamePList], AssociateWnd, NULL,
                      GTLV_Labels, NULL,
                      TAG_END);
    GT_SetGadgetAttrs(AssociateGadgets[GD_FilePList], AssociateWnd, NULL,
                      GTLV_Labels, NULL,
                      TAG_END);
    GT_SetGadgetAttrs(AssociateGadgets[GD_IconStr], AssociateWnd, NULL,
                      GA_Disabled, TRUE,
                      GTST_String, NULL,
                      TAG_END);
    GT_SetGadgetAttrs(AssociateGadgets[GD_IconRun],AssociateWnd,NULL,
                      GA_Disabled, TRUE,
                      GTCB_Checked,FALSE,
                      TAG_DONE);
    GT_SetGadgetAttrs(AssociateGadgets[GD_IconInfo],AssociateWnd,NULL,
                      GA_Disabled, TRUE,
                      TAG_DONE);
  }
}

int TypeListClicked( void )
{
	/* routine when gadget "File Type" is clicked. */
	
	UpdateLists();
	return(1);
}

int NamePListClicked( void )
{
	/* routine when gadget "Name Patterns" is clicked. */
	return(1);
}

int FilePListClicked( void )
{
	/* routine when gadget "File Patterns" is clicked. */
	return(1);
}

int IconPickClicked( void )
{
	/* routine when gadget "" is clicked. */
	
	if (temptnode=FindTypeNode())
	{
    if (SelectFile(temptnode->IconName,"Select an Icon!","#?.info"))
	  {
      GT_SetGadgetAttrs(AssociateGadgets[GD_IconStr], AssociateWnd, NULL,
                        GTST_String, temptnode->IconName,
                        TAG_END);
	  }
	}
	return(1);
}

int IconStrClicked( void )
{
	/* routine when gadget "Icon Filename" is clicked. */
	
	if (temptnode=FindTypeNode())
	{
    strcpy(temptnode->IconName,GetString(AssociateGadgets[GD_IconStr]));
  }
	return(1);
}

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

char *getparent(char *s)
{
  int l;
  char *outname;

  if (outname=strdup(s))
  {
    addterm(outname);
    l=strlen(outname);

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

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

  char *outstr;
  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 removeinfo( char *str)
{
  short slen;

  // i know this looks tacky but it's fast and small... :-)
  
  slen=strlen(str)-1;
  if (toupper(str[slen])=='O' &&
      toupper(str[slen-1])=='F' &&
      toupper(str[slen-2])=='N' &&
      toupper(str[slen-3])=='I' &&
      toupper(str[slen-4])=='.')
  {
    str[slen-4]=0;
  }
}

void DoInfo( char *fname)
{
	BPTR FL;
	char *drawername;
	char *filename;
	char *wholestr;
	
  if (WorkbenchBase->lib_Version>=39)
  {
    if (wholestr=strdup(fname))      
    {     
      if (wholestr[0])
      {
        removeinfo(wholestr);                                         
        drawername=getparent(wholestr);
        filename=FilePart(wholestr);        
        if (FL=Lock(drawername,ACCESS_READ))
        {
          WBInfo(FL,filename,Scr);
          UnLock(FL);
        }
        free(drawername);
      }
      free(wholestr);
    }
  }
  else rtEZRequest("Sorry, You Need WB 3.0+ to access Icon Info","Damn!",NULL,NULL);  
}

int IconInfoClicked( void )
{
	/* routine when gadget "Icon Info" is clicked. */
  if (temptnode=FindTypeNode())
  {
    if (temptnode->IconName)
    {
      DoInfo(temptnode->IconName);
    }
  }
	return(1);
}
int IconRunClicked( void )
{
	/* routine when gadget "Run Info When activated" is clicked. */
	
	if (temptnode=FindTypeNode())
	{
    GT_GetGadgetAttrs(AssociateGadgets[GD_IconRun],AssociateWnd,NULL,
                      GTCB_Checked,&temptnode->RunInfo,
                      TAG_DONE);
  }                    
	return(1);
}

int TypeAddClicked( void )
{
	/* routine when gadget "Add" is clicked. */

  char *tmpstr;

  if (tmpstr=AllocMem(256,MEMF_PUBLIC|MEMF_CLEAR)) //MEMF_CLEAR to nullify string..
  {
    if (rtGetString(tmpstr,255, "Enter File Type Name", NULL,RT_Window,AssociateWnd, TAG_END))
    {
      NewTypeNode(typelist,tmpstr);
      UpdateLists();
    }
    FreeMem(tmpstr,256);
  }
	return(1);
}

int TypeDeleteClicked( void )
{
	/* routine when gadget "Delete" is clicked. */
  if (temptnode=FindTypeNode())
  {
    if (rtEZRequest("Sure ?","Yeah!|No Way!",NULL,NULL))
    {
      FreeTypeNode(temptnode);
      Remove((struct Node*)temptnode);
      FreeMem(temptnode,sizeof(struct TypeNode));
      UpdateLists();
    }
  }
	return(1);
}

int NamePAddClicked( void )
{
	/* routine when gadget "Add" is clicked. */
  char *tmpstr;
  if (temptnode=FindTypeNode())
  {
    if (tmpstr=AllocMem(256,MEMF_PUBLIC|MEMF_CLEAR)) //MEMF_CLEAR to nullify string..
    {
      if (rtGetString(tmpstr,255, "Enter Name Match String", NULL,RT_Window,AssociateWnd, TAG_END))
      {
        NewNameNode(temptnode->nameplist,tmpstr);
        GT_SetGadgetAttrs(AssociateGadgets[GD_NamePList], AssociateWnd, NULL,
                          GTLV_Labels, (ULONG)temptnode->nameplist,
                          TAG_END);
      }
    }
    FreeMem(tmpstr,256);
  }
	return(1);
}

int NamePDeleteClicked( void )
{
	/* routine when gadget "Delete" is clicked. */

  LONG num;
  struct Node *node;

  if (temptnode=FindTypeNode())
  {
    if (1==GT_GetGadgetAttrs(AssociateGadgets[GD_NamePList],AssociateWnd,NULL,
                    GTLV_Selected,&num,
                    TAG_DONE))
    {
      if (num>=0)
      {
        node=GetNode(temptnode->nameplist,num);
        FreeNameNode(node);
        Remove(node);
        FreeMem(node,sizeof(struct Node));
        UpdateLists();
      }
    }
  }
  
	return(1);
}

int FilePAddClicked( void )
{
	/* routine when gadget "Add" is clicked. */

  char *tmpstr;

  if (temptnode=FindTypeNode())
  {
    if (tmpstr=AllocMem(256,MEMF_PUBLIC|MEMF_CLEAR)) //MEMF_CLEAR to nullify string..
    {
      if (rtGetString(tmpstr,255, "Enter File Match String", NULL,RT_Window,AssociateWnd, TAG_END))
      {
        NewNameNode(temptnode->fileplist,tmpstr);
        GT_SetGadgetAttrs(AssociateGadgets[GD_FilePList], AssociateWnd, NULL,
                          GTLV_Labels, (ULONG)temptnode->fileplist,
                          TAG_END);
      }
    }
    FreeMem(tmpstr,256);
  }
	return(1);
}

int FilePDeleteClicked( void )
{
	/* routine when gadget "Delete" is clicked. */
  LONG num;
  struct Node *node;

  if (temptnode=FindTypeNode())
  {
    if (1==GT_GetGadgetAttrs(AssociateGadgets[GD_FilePList],AssociateWnd,NULL,
                    GTLV_Selected,&num,
                    TAG_DONE))
    {
      if (num>=0)
      {
        node=GetNode(temptnode->fileplist,num);
        FreeNameNode(node);
        Remove(node);
        FreeMem(node,sizeof(struct Node));
        UpdateLists();
      }
    }
  }
  return(1);
}

int SaveClicked( void )
{
	/* routine when gadget "Save" is clicked. */
	SavePrefs();
	return(1);
}

int HelpClicked( void )
{
	/* routine when gadget "Help" is clicked. */
  static ULONG sysargs[] =
  {
    SYS_Input,NULL,
    SYS_Output,NULL,
    SYS_Asynch,FALSE,
    SYS_UserShell,TRUE,
    NP_Priority,0L,
    TAG_DONE
  };

	if (SystemTagList("AmigaGuide Associate.Guide",(struct TagItem *)sysargs)!=0)
	{
    if (SystemTagList("AmigaGuide progdir:Associate.Guide",(struct TagItem *)sysargs)!=0)
    {
      rtEZRequest("Sorry, I Can't find AmigaGuide\n"
                  "and/or the Assoiciate.Guide file",okstr,NULL,NULL);
    }
	}
	return(1);
}

int OKClicked( void )
{
	/* routine when gadget "OK" is clicked. */
	return(0);
}

int TypeEditClicked( void )
{
	/* routine when gadget "Edit" is clicked. */
  LONG num;
  struct Node *node;
  if (1==GT_GetGadgetAttrs(AssociateGadgets[GD_TypeList],AssociateWnd,NULL,
                  GTLV_Selected,&num,
                  TAG_DONE))
  {
    if (num>=0)
    {
      node=GetNode(typelist,num);
      if (rtGetString(node->ln_Name,255, "Edit Filetype Name", NULL,RT_Window,AssociateWnd, TAG_END))
      {
        GT_SetGadgetAttrs(AssociateGadgets[GD_TypeList], AssociateWnd, NULL,
                          GTLV_Labels, (ULONG)typelist,
                          TAG_END);
      }
    }
  }
	return(1);
}

int NamePEditClicked( void )
{
	/* routine when gadget "Edit" is clicked. */
  LONG num;
  struct Node *node;

  if (temptnode=FindTypeNode())
  {
    if (1==GT_GetGadgetAttrs(AssociateGadgets[GD_NamePList],AssociateWnd,NULL,
                    GTLV_Selected,&num,
                    TAG_DONE))
    {
      if (num>=0)
      {
        node=GetNode(temptnode->nameplist,num);
        if (rtGetString(node->ln_Name,255, "Edit Match String", NULL,RT_Window,AssociateWnd, TAG_END))
        {
          GT_SetGadgetAttrs(AssociateGadgets[GD_NamePList], AssociateWnd, NULL,
                            GTLV_Labels, (ULONG)temptnode->nameplist,
                            TAG_END);
        }
      }
    }
  }
	return(1);
}

int FilePEditClicked( void )
{
	/* routine when gadget "Edit" is clicked. */
  LONG num;
  struct Node *node;

  if (temptnode=FindTypeNode())
  {
    if (1==GT_GetGadgetAttrs(AssociateGadgets[GD_FilePList],AssociateWnd,NULL,
                    GTLV_Selected,&num,
                    TAG_DONE))
    {
      if (num>=0)
      {
        node=GetNode(temptnode->fileplist,num);
        if (rtGetString(node->ln_Name,255, "Edit Match String", NULL,RT_Window,AssociateWnd, TAG_END))
        {
          GT_SetGadgetAttrs(AssociateGadgets[GD_FilePList], AssociateWnd, NULL,
                            GTLV_Labels, (ULONG)temptnode->fileplist,
                            TAG_END);
        }
      }
    }
  }
	return(1);
}

int AssociateItem0( void )
{
	/* routine when (sub)item "About" is selected. */
	DoAbout();
	return(1);
}

int AssociateItem1( void )
{
	/* routine when (sub)item "Quit!" is selected. */
	done=TRUE;
	return(0);
}

int AssociateCloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */	
	return(0);
}


int PickTypeClicked( void )
{
	/* routine when gadget "" is clicked. */
	return(1);
}

int PickOkClicked( void )
{
	/* routine when gadget "Ok!" is clicked. */
	
  LONG num;
  int retval=1;
  if (1==GT_GetGadgetAttrs(PickGadgets[GD_PickType],PickWnd,NULL,
                           GTLV_Selected,&num,
                           TAG_DONE))
  {
    if (num>=0)
    {
      temptnode=(struct TypeNode *) GetNode(typelist,num);
      retval=0;
    }
  }
  return(retval);
}

int PickCancelClicked( void )
{
	/* routine when gadget "Cancel" is clicked. */
	temptnode=NULL;
	return(0);
}

int PickCloseWindow( void )
{
	/* routine for "IDCMP_CLOSEWINDOW". */
	// hmm.  does this funtion get called when there is no close gadget ?
	return(0); 
}

int PickVanillaKey( void )
{
	/* routine for "IDCMP_VANILLAKEY". */
	switch (PickMsg.Code)
	{
	  case 13:
	    return(PickOkClicked());
	    break;
	  case 27:
	    temptnode=NULL;
	    return(0);
	    break;
	}
	return(1);
}
