/*->c.help     */

/* Ovation!   (c) D. J. Pilling,     April 1989                       */
/*                   Filing System  Interface                         */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>
#include <stdarg.h>


#include "h.os"
#include "h.wimp"
#include "h.sprite"
#include "h.bbc"
#include "h.flex"
#include "h.wimpt"
#include "h.akbd"
#include "h.werr"
#include "h.swis"


#include "h.Drawlevel0"



#include "h.wos"
#include "h.timex"
#include "h.fsx"
#include "h.strdef"
#include "h.dir"
#include "h.ram"
#include "h.mym"
#include "h.pr"
#include "h.xext"
#include "h.serial"
#include "h.file"
#include "h.batch"
#include "h.view"
#include "h.script"
#include "h.config"
#include "h.buffer"
#include "h.code"
#include "h.link"
#include "h.pic"
#include "h.vx"
#include "h.sched"
#include "h.group"
#include "h.state"
#include "h.con"
#include "h.newfax"
#include "h.serialdev"
#include "h.trans"
#include "h.csv"
#include "h.tw"
#include "h.log"
#include "h.replay"
#include "h.dbug"
#include "h.ftpglue"
#include "h.band"


#include "h.help"



/* 

   Help file format

   Name,icon,icon,icon,string

 */






static char * menunames[MSIZE]=
{                                                                                "null_menu",
 "disp_menu",
 "rename_menu",
 "dbug_menu",
 "spare2_menu",
 "scan_menu",
 "info_menu",
 "tdirpassword_menu",
 "tdirprefix_menu",
 "tdirsearch_menu",
 "tdirgroup_menu",
 "tdir_menu",
 "vxbmain_goto",
 "vxbmain_menu",
 "schedpri_menu",
 "schedbit_menu",
 "schedsel_menu",
 "schedule_menu",
 "action_menu",
 "view_menu",
 "group_menu",
 "rate_menu",
 "width_menu",
 "length_menu",
 "logfile_menu",
 "driver_menu",
 "font_menu",
 "entry_menu",
 "voice_menu",
 "server_menu",
 "band_menu",

};



#define EXTRA 1

#define MAXTAGS (MAXI+MSIZE+EXTRA)

#define ICONBARTAG (MAXI+MSIZE)


typedef struct iconstr
{
 char           icon;
 char           bits;
 unsigned short offset;

} iconstr;


#define ICONCHUNK   (sizeof(iconstr)*32)
#define STRINGCHUNK (512)



static int tagptr[MAXTAGS];     /* pointers into icon structure */

static int       icons;
static iconstr * iconptr;          /* pointers into strings */

static int    hstrings;
static char * hstringptr;


static int findtag(char * name)
{
 int i;

 for(i=0;i<MAXI;i++)
 {
  if(windownames[i].name && !cstrcmp(name,windownames[i].name)) 
                                          return(windownames[i].tag);
 }

 for(i=0;i<MSIZE;i++)
 {
  if(menunames[i] && !cstrcmp(name,menunames[i]))
  {
   return(i+MAXI);
  }
 }

 if(!cstrcmp(name,"IconBar")) return(ICONBARTAG);

 return(-1);
}


void inithelp(void)
{
 os_error * err;
 FILE     * fp;
 char     * p;
 char     * q;
 char       temp[512];
 int        tag;
 int        n;
 int        ch;

          err=flex_alloce((flex_ptr)&iconptr,0);
 if(!err) err=flex_alloce((flex_ptr)&hstringptr,0);

 if(!err)
 {
  icons=1;
  hstrings=0;


  fp=fopen("<ArcFaxRes$Dir>.Help","rb");
  if(fp)
  {
   while((p=fgets(temp,sizeof(temp),fp))!=NULL)                                    {
    while(*p==' ') p++;
    if((*p)=='/' || (*p)<' ') continue;               /* !!!!!!! */

    q=p;

    while(*p>=' ' && *p++!=',');
    *(p-1)=0;

    /* map string to tag */

    tag=findtag(q);
    if(tag>=0)
    {
     if(!tagptr[tag])
     {
      tagptr[tag]=icons;
     }
     else
     {
      iconptr[icons-1].bits&=~0x1;
     }

     while(1)
     {
      n=0;                                                                            while((ch=*p++)!=0)
      {
       if(ch==',' || ch==':') break;
       else 
       if(isdigit(ch)) n=n*10+(ch-'0');
      }

      err=flex_chunke((flex_ptr)&iconptr,(icons+1)*sizeof(iconstr),ICONCHUNK);
      if(err) break;

      icons++;
      iconptr[icons-1].icon=n;
      iconptr[icons-1].offset=hstrings;
      iconptr[icons-1].bits=0;

      if(ch!=',')
      {
       iconptr[icons-1].bits|=0x1;
       break;
      }
     }

     if(err) break;
     if(ch!=':') break;

     q=p;
     while(*p++>=' ');
     *(p-1)=0;

     err=flex_chunke((flex_ptr)&hstringptr,(hstrings+p-q),STRINGCHUNK);
     if(err) break;

     strcpy(hstringptr+hstrings,q);

     hstrings+=p-q;
    }
   }
   fclose(fp);
  }
 }
 report(err);
}


static char * findtagstring(int tag,int icon)
{
 iconstr * iconp;

 if(tagptr[tag])
 {
  iconp=iconptr+tagptr[tag];

  while(1)
  {
   if(iconp->icon==icon || (iconp->icon==255 && icon==-1) || iconp->icon==254)
   {
    return(hstringptr+iconp->offset);
   }
  
   if(iconp->bits & 0x1) break;
   iconp++;
  }
 }
 
 return(NULL);
}


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




static int findmenu(int handle,int icon,int * entry)
{
 os_regset rx;
 int       buffer[16];
 int     * menu;
 int       i;
 int       index;

 rx.r[0]=1;
 rx.r[1]=(int)buffer;
 rx.r[2]=handle;
 rx.r[3]=icon;

 if(!os_swix(Wimp_GetMenuState,&rx) && buffer[0]>=0 && lastmenu)
 {
  menu=lastmenu;
  i=0;
  index=0;  /* compiler */

  while(1)
  {
   index=buffer[i++];
   if(buffer[i]==-1) break;

   menu=(int*)(*(menu+(7+1+6*index)));
   if(!menu) break;
  }

  if(menu)
  {
   for(i=0;i<MSIZE;i++)
   {
    if(menus[i]==menu)
    {
     *entry=index;
     return(i);
    }
   }
  }
 }

 return(-1);
}



/* 

   get help message,

   take out special handles, like fax viewers
   look up general window handles and map to tags
   try to map to a menu

   take help tag, plus icon and look up text for it,
   send text back

 */



void helpmessage(void)
{
 int    handle;
 int    icon;
 char * p;
 int    i;
 int    vxn;
 int    entry;

 handle=wimpevent.data.msg.data.helprequest.m.w;
 icon=wimpevent.data.msg.data.helprequest.m.i;

 p=NULL;

 if(handle==-2 && icon==iconbaricon)
 {
  p=findtagstring(ICONBARTAG,icon);
 }
 else
 if(handle>=0)
 {
  if((vxn=getvx(handle))>=0)      i=VX;
  else
  if((vxn=gettoolsvx(handle))>=0) i=VXTOOLS;
  else
  if((vxn=getsn(handle))>=0)
  {
   i=SX;
   icon=noviewsched(vxn);
  }
  else
  if((vxn=getgn(handle))>=0)      i=GROUP;
  else
  if(getview(handle))
  {
   i=FILER;
   icon=view;
  }
  else
  if(getentry(handle))            i=ENTRY;
  else
  {
   for(i=0;i<MAXI;i++)
   {
    if(whandle[i]==handle) break;
   }
  }

  if(i<MAXI)
  {
   p=findtagstring(i,icon);
  }
  else   /* try to map to a menu */
  {
   i=findmenu(handle,icon,&entry);
   if(i>=0) p=findtagstring(i+MAXI,entry);
  }
 }

 if(p)
 {
  strcpy(wimpevent.data.msg.data.helpreply.text,p);
  wimpevent.data.msg.hdr.size=((48+strlen(p)) & 0xFFFFFFFC);
  wimpevent.data.msg.hdr.your_ref=wimpevent.data.msg.hdr.my_ref;
  wimpevent.data.msg.hdr.action=0x503;
  wimp_sendmessage(17,&wimpevent.data.msg,wimpevent.data.msg.hdr.task);
 }
}

