/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * title: help.c
 * Author: William Stoye
 * History:
 *   13-Dec-89: started.
 *   14-Dec-89: WRS: bug shot, spotted by JC: i and i++ in same statement!
 *                   is it also in c.event?
 *   13-May-91: ECN: use SWI names instead of numbers
 *   01-Jul-91: IDJ: made help_process check event was a recorded delivery msg.
 */

#include <string.h>
#include "h.os"
#include "h.wimp"
#include "h.wimpt"
#include "h.werr"
#include "h.trace"
#include "h.event"
#include "h.dbox"
#include "h.msgs"
#include "h.help"
#include "h.swis"

static           void *help__handle = 0;
static event_menu_proc help__handler = 0;

void help_register_handler(event_menu_proc handler, void *handle)
{
  help__handle = handle;
  help__handler = handler;
}

BOOL help_process(wimp_eventstr *e)
{
  if (help__handler == 0) return(FALSE);
  if (e->e != wimp_ESENDWANTACK || e->data.msg.hdr.action != wimp_MHELPREQUEST)
    return(FALSE);
  else
  {
    /* some interactive help - perhaps menu help? */
    wimp_w w = e->data.msg.data.helprequest.m.w;
    wimp_i i = e->data.msg.data.helprequest.m.i;
    int buffer[25];

    wimpt_complain(
      os_swi4(
        os_X | Wimp_GetMenuState,
        1,              /* Fill up buffer with menu depth, terminate with -1 */
        (int) &buffer[0],
        w,              /* Fill only up to this window/icon */
        i));

    if (buffer[0] == -1)
    {
      return(FALSE);
    }
    else
    {
      int i;
      char a[20];
      for (i = 0; buffer[i] != -1; i++) {a[i] = 1 + buffer[i];}
      a[i] = 0;
      help__handler(help__handle, a);
      return(TRUE);
    }
  }
}

static char help__encode(int i)
/* Take a small number >= 0 and encode it as a printing character. */
{
  char c;
  if (i <= 9) c = '0' + i;
  else if (i <= 35) c = 'a' + i - 10;
  else c = 'z';
  return(c);
}

void help_reply(char *m)
/* Reply to the help message in wimpt_last_event() with (already translated)
message m. */
{
  wimp_eventstr *e = wimpt_last_event();

  e->data.msg.hdr.your_ref = e->data.msg.hdr.my_ref;
  e->data.msg.hdr.action = wimp_MHELPREPLY;
  e->data.msg.hdr.size = 256; /* be generous! */
  strcpy(e->data.msg.data.helpreply.text, m);
  wimpt_noerr(
   wimp_sendmessage(wimp_ESEND, &e->data.msg, e->data.msg.hdr.task));
}

BOOL help_genmessage(char *prefix, char *hit)
{
  int prefixlen = strlen(prefix);
  char tag[50];
  char *message;
  int i = 0;  /* to get past "help", below */

  /* werr(FALSE, "help_genmessage %i %i %i.", hit[0], hit[1], hit[2]); */

  strcpy(tag, prefix); /* Menu Interactive Help - 3 characters */
  while (hit[i] > 0 && i < 25) {tag[i + prefixlen] = help__encode(hit[i] - 1); i++;}
  tag[i + prefixlen] = 0; /* terminate the string */
  message = msgs_lookup(tag);
  /* werr(FALSE, "try interactive help tag '%s'.", tag); */

  if (strcmp(message, tag) != 0)
  {
    help_reply(message);
    return(TRUE);
  } else { /* no pre-canned message */
    /* werr(FALSE, "interactive help, no message available.\n"); */
    return(FALSE);
  }
}

void help_simplehandler(void *handle, char *hit)
{
  help_genmessage((char*) handle, hit);
}

BOOL help_dboxrawevents(dbox d, void *event, void *handle)
{
  wimp_eventstr *e = wimpt_last_event();

  if (
       (e->e == wimp_ESEND || e->e == wimp_ESENDWANTACK)
       &&
       e->data.msg.hdr.action == wimp_MHELPREQUEST
     )
  {
    wimp_i icon = e->data.msg.data.helprequest.m.i;
    char tag[50];
    int taglen = strlen((char*) handle);
    char *message;

    d = d; /* to prevent compiler warning */
    event = event; /* to prevent compiler warning */
    strcpy(tag, (char*) handle);
    tag[taglen] = help__encode(icon);
    tag[taglen + 1] = 0;
    message = msgs_lookup(tag);
    if (strcmp(message, tag) != 0) help_reply(message);
    else
    {
      tag[taglen] = 0;
      message = msgs_lookup(tag);
      if (strcmp(message, tag) != 0) help_reply(message);
    }
    return(TRUE); /* message has been handled. */
  }
  else
    return(FALSE);
}