/*
 * msg.c
 * 20/9/03
 * Anything to do with the Messages file
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "kernel.h"
#include "swis.h"
#include "inttypes.h"
#include "msg.h"
#include "ka_mem.h"

static int msg_desc[5];
static char * msg_buf;

/*
 * msg_open
 * --------
 */
int msg_open(const char * name)
{
  _kernel_swi_regs regs;

  if(msg_desc[4])
    return 1; // already open

  regs.r[1] = (int)name;
  if(_kernel_swi(MessageTrans_FileInfo, &regs, &regs))
    return 0; // error opening file

  if(regs.r[0] & 1)
    return 0; // already in memory

  if((msg_buf = ka_mem_alloc(regs.r[2])) == NULL)
    return 0; // out of memory

  regs.r[0] = (int)&msg_desc;
  regs.r[1] = (int)name;
  regs.r[2] = (int)msg_buf;
  _kernel_swi(MessageTrans_OpenFile, &regs, &regs);
  msg_desc[4] = 1;

  return 1;
}

/*
 * msg_close
 * ---------
 */
void msg_close(void)
{
  _kernel_swi_regs regs;

  regs.r[0] = (int)&msg_desc;
  _kernel_swi(MessageTrans_CloseFile, &regs, &regs);
  msg_desc[4] = 0;

  if(msg_buf)
  {
    ka_mem_free(msg_buf);
    msg_buf = NULL;
  }
}

/*
 * msg_lookup
 * ----------
 * Converts a message token to text. Requires the base token string and
 * a numeric qualifier.
 * If qualifier is negative, uses token directly with no appended numeric.
 */
int msg_lookup(const char * token, int num, char * dest, int dstsize)
{
  _kernel_swi_regs regs;
  char tok[32];

  if(num < 0)
    regs.r[1] = (int)token;
  else
  {
    snprintf(tok, sizeof(tok), "%s%d", token, num);
    regs.r[1] = (int)&tok;
  }

  // Messages file must have been opened
  if(msg_desc[4])
  {
    regs.r[0] = (int)&msg_desc;
    regs.r[2] = (int)dest;
    regs.r[3] = dstsize;
    regs.r[4] = 0;
    regs.r[5] = 0;
    regs.r[6] = 0;
    regs.r[7] = 0;
    if(!_kernel_swi(MessageTrans_Lookup, &regs, &regs))
      return 1;
  }

  // Not found, may just be some text
  snprintf(dest, dstsize, "%s", (char*) regs.r[1]);

  return 1;
}

/*
 * msg_load_menu
 * -------------
 * copies text from messages file to menu structures
 */
void msg_load_menu(const char* token, menu_block_t* blk)
{
  menu_item_t* item = (menu_item_t*) (blk + 1);
  char* str;
  _kernel_swi_regs regs;

  regs.r[0] = (int)&msg_desc;
  regs.r[1] = (int)token;
  regs.r[2] = 0;
  regs.r[3] = 0;
  regs.r[4] = 0;
  regs.r[5] = 0;
  regs.r[6] = 0;
  regs.r[7] = 0;
  if(_kernel_swi(MessageTrans_Lookup, &regs, &regs))
    return;

  if ((str = ka_mem_alloc(regs.r[3] + 1)) == NULL)
    return;

  memcpy(str, (char*) regs.r[2], regs.r[3]);
  str[regs.r[3]] = 0;

  // title
  blk->title = str;
  str = strchr(str, ',');
  if (str)
  {
    *str++ = 0;
    blk->len = str - blk->title;
  }
  else
  {
    blk->len = strlen(blk->title) + 1;
    return;
  }
  // Mark in first item that title is indirected
  item->item_flags |= 0x100;

  // items
  while(1)
  {
    item->text = str;
    str = strchr(str, ',');
    if (str)
    {
      *str++ = 0;
      item->len = str - item->text;
    }
    else
    {
      item->len = strlen(item->text) + 1;
      return;
    }
    // Do not go behind last item of menu
    if (item->item_flags & 0x80)
      return;
    item++;
  }
}

