/* showtext.c */

#include "wimp.h"
#include "wimpt.h"
#include "event.h"
#include "kernel.h"
#include "txt.h"
#include "flex.h"
#include "akbd.h"

#define Osfile_Readinfo  17
#define Osfile_Load      255

/* Initialise the ShowText functions ready to roll */
void showtext_init(void)
{
  txt_init();
}

/* Event handler for text routines */
static void txt_event(txt text, void *handle)
{
  txt_eventcode event;
  int visible, move;

  event = txt_get(text);
  switch (event)
  {
    case txt_EXTRACODE + akbd_Fn +127:
      /* Close */
      txt_hide(text);
      *((int *)handle) = 1;
      break;

    case txt_EXTRACODE + akbd_Sh + akbd_Ctl + akbd_UpK:
      /* Scroll up a line */
      txt_movevertical(text, -1, 1);
      break;

    case txt_EXTRACODE + akbd_Sh + akbd_Ctl + akbd_DownK:
      /* Scroll down a line */
      txt_movevertical(text, 1, 1);
      break;

    case txt_EXTRACODE + akbd_Sh + akbd_UpK:
      /* Scroll up a page */
      visible = txt_visiblelinecount(text);
      move = (visible >= 1) ? visible-1 : 0;
      txt_movevertical(text, -move, 1);
      break;

    case txt_EXTRACODE + akbd_Sh + akbd_DownK:
      visible = txt_visiblelinecount(text);
      move = (visible >= 1) ? visible-1 : 0;
      txt_movevertical(text, move, 1);
      /* Scroll down a page */
      break;

    default:
      break;
  }
}

/* Display a named text file in a window */
int showtext_display(const char *text, const char *title)
{
  _kernel_osfile_block block;
  int size, res, done = 0;
  txt ourtext;
  char *buffer;
  wimp_caretstr cstr, cstr2;

  if (res = _kernel_osfile(Osfile_Readinfo, text, &block), res == _kernel_ERROR || res == 0)
    return FALSE;
  else
    size = block.start;

  ourtext = txt_new((char *)title);
    if (ourtext == 0)
      return FALSE;

  if (!txt_setbufsize(ourtext, size))
    goto error;

  txt_eventhandler(ourtext, txt_event, (void *)&done);
  txt_show(ourtext);

  if (!flex_alloc((flex_ptr)&buffer, size))
    goto error;
  
  block.load = (int)buffer;
  block.exec = 0;
  if (_kernel_osfile(Osfile_Load, text, &block) == _kernel_ERROR)
    {
      flex_free((flex_ptr)&buffer);
      goto error;
    }

  wimpt_noerr(wimp_get_caret_pos(&cstr));
  txt_replaceatend(ourtext, 0, buffer, size);
  flex_free((flex_ptr)&buffer);
  txt_setcharoptions(ourtext, txt_CARET, 0);
  wimpt_noerr(wimp_set_caret_pos(&cstr));

  while (!done)
    {
      wimpt_noerr(wimp_get_caret_pos(&cstr));
      event_process();
      wimpt_noerr(wimp_get_caret_pos(&cstr2));
      if (cstr2.w == (wimp_w)txt_syshandle(ourtext))
        {
          txt_setcharoptions(ourtext, txt_CARET, 0);
          wimpt_noerr(wimp_set_caret_pos(&cstr));
        }
    }

  txt_dispose(&ourtext);

  return TRUE;

error:
  txt_dispose(&ourtext);
  return FALSE;
}
