#include "swis.h"
#include "kernel.h"
#include "stdarg.h"
#include "wimplib.h"
#include "string.h"
#include "toolbox.h"
#include "gadgets.h"

#include "ctype.h"
#include "files.h"

extern MessagesFD messages;

void raise_error(_kernel_oserror *);

char lookup_token_buffer[1024];

extern char *strcasestr(const char *a, const char *b)
{
  int i;
  for (;;)
  {
    for (i=0; ; i++)
    {
      char ch = b[i];
      if (ch == 0) return (char *)a;
      if (tolower(a[i]) != tolower(ch)) break;
    }
    if (*a++ == 0) return 0;
  }
}

extern void read_var_val(char *var, char *buffer, int buf_size)
{
    _kernel_swi_regs r;

    r.r[0] = (int)var;
    r.r[1] = (int) buffer;
    r.r[2] = buf_size;

    _kernel_swi(OS_ReadVarVal, &r,&r);

    *(buffer + r.r[2]) = '\0';

    return;
}

extern void messages_lookup (MessagesFD messages_fd, char *token, char *buffer,
                             int buffer_size, char *par1, char *par2, char *par3,
                             char *par4, char **new_buffer, int *new_buffer_size)
{

   /* Looks up token and passes back appropriate message */

   _kernel_oserror  *e;
   _kernel_swi_regs  regs;

   regs.r[0] = (int)  &messages_fd;
   regs.r[1] = (int)  token;
   regs.r[2] = (int)  buffer;
   regs.r[3] =        buffer_size;
   regs.r[4] = (int)  par1;
   regs.r[5] = (int)  par2;
   regs.r[6] = (int)  par3;
   regs.r[7] = (int)  par4;

   if ((e = _kernel_swi (MessageTrans_Lookup, &regs, &regs)) != NULL)
      raise_error (e);

   if (new_buffer) {
      *new_buffer      = (char *) regs.r[2];
   }
   if (new_buffer_size) {
      *new_buffer_size = regs.r[3];
   }
}


extern void raise_error(_kernel_oserror *e)
{

      /* Given an error block, raise the error */

      _kernel_swi_regs regs;
      char *strng;

      if(e == NULL)
       return;

      messages_lookup (messages, "_TaskName", NULL, 0, NULL, NULL, NULL, NULL, &strng, NULL);

      regs.r[0] = (int) e;
      regs.r[1] =       16;
      regs.r[2] = (int) strng;

      _kernel_swi (Wimp_ReportError, &regs, &regs);
}

_kernel_oserror *my_stringset_set_selected( unsigned int flags,
                                            ObjectId window,
                                            ComponentId string_set,
                                            int index
                                           )
{
  _kernel_swi_regs r;

  r.r[0] = flags;
  r.r[1] = (int) window;
  r.r[2] = StringSet_SetSelected;
  r.r[3] = (int) string_set;
  r.r[4] = index;
  return(_kernel_swi(Toolbox_ObjectMiscOp,&r,&r));
}

/*
char * lookup_token(char *tag)
{
    _kernel_swi_regs regs;
    regs.r[0] = (int) &messages;
    regs.r[1] = (int) tag;
    regs.r[2] = 0;

    if (_kernel_swi(MessageTrans_Lookup,&regs,&regs)) return 0;
    else return (char *) regs.r[2];

}
*/

char * lookup_token(char *tag)
{
    messages_lookup (messages, tag, lookup_token_buffer, 1024, NULL, NULL, NULL, NULL,
                     NULL, NULL);
    return lookup_token_buffer;
}


void werr(int fatal, char* format, ...)
{
   va_list va;
   _kernel_oserror e = {0, 0};
   e.errnum = 0;
   va_start(va, format);
   vsprintf(&e.errmess, format, va);
   va_end(va);
   /*wimp_report_error(&e, 0, lookup_token("_TaskName"));*/
   wimp_report_error(&e, 0, 0);
   if (fatal) exit(0);
}

char *get_leaf_name(char *buffer)
{
  int len;

  len = strlen(buffer);
  while(*(buffer+len--) != '.' && len != 0);

  /* If seperator found, return pointer to leaf name, otherwise return buffer */
  if(*(buffer+len+1) == '.')
   return(buffer+len+2);

  return(buffer);
}

BOOL file_exists(char *file_name, char *ACCESS)
{
  _kernel_oserror *e;
  int file_handle;

  e = file_open(file_name, &file_handle, ACCESS);
  if(e!=NULL)
  {
    return(FALSE);
  }
  file_close(file_handle);
  return(TRUE);
}

BOOL directory_exists(char *dir_name)
{
  int type;

  _swix(OS_File,_IN(0) | _IN(1) | _OUT(0), 5, dir_name, &type);

  if(type != 2)
  {
    return(FALSE);
  }
  return(TRUE);
}

extern BOOL task_running(char *name)
{
  _kernel_swi_regs r;
  int buffer[1024];
  char *p;
  int x, unused = 0, entries = 0, last = 0;

  while(TRUE)
  {
    r.r[0] = last;
    r.r[1] = (int)buffer;
    r.r[2] = 1024;
    _kernel_swi(TaskManager_EnumerateTasks, &r, &r);

    last   = r.r[0];
    unused = r.r[2];

    entries = (1024 - unused)/16;

    for(x = 0 ; x < entries; x++ )
    {
      p = (char *)buffer[1 + (x*4)];

      if(!strcasecmp(p, name))
       return(TRUE);
    }

    if(last < 0)
     return(FALSE);
  }
  return(FALSE);
}

extern int strcasecmp(char *s1, char *s2)
{
  while (tolower(*s1) == tolower(*s2++))
    if (*s1++ == '\0') return(0);
  return(tolower(*s1) - tolower(*--s2));
}
