/* swi.c */

#include <stdlib.h>
#include <string.h>

#include "kernel.h"

#include "dBoxTools.h"
#include "find.h"
#include "main.h"
#include "swi.h"

static char buffer[20]; /* used to build text from numeric values */

static _kernel_oserror *swi_SetClient( _kernel_swi_regs *r )
{ int c;

  c = client;
  if( r->r[4] != 0 ) client = r->r[4];
  r->r[4] = c;
  return NULL;
}

static _kernel_oserror *swi_SetClientHandle( _kernel_swi_regs *r )
{ int c;

  c = handle;
  if( r->r[4] != 0 ) handle = r->r[4];
  r->r[4] = c;
  return NULL;
}

static _kernel_oserror *swi_SetOutPutFocus( _kernel_swi_regs *r )
{ int flags = r->r[0];


  return NULL;
}

static _kernel_oserror *swi_SetDestination( _kernel_swi_regs *r )
{
  return NULL;
}

static _kernel_oserror *swi_SetValue( _kernel_swi_regs *r )
{
  return NULL;
}

static _kernel_oserror *swi_GetValue( _kernel_swi_regs *r )
{
  return NULL;
}

static _kernel_oserror *swi_Quit( _kernel_swi_regs *r )
{
  return NULL;
}

static int findTask( char *task )
{ _kernel_swi_regs r;
  int buffer[4];
  
  r.r[0] = 0;
  r.r[1] = (int) buffer;
  r.r[2] = 16;

  while( r.r[0] >= 0 )
  { _kernel_swi( 0x42681, &r, &r );
    if( strcmp( (char*) buffer[1], task ) == 0 ) return buffer[0];
  }
  return 0;
}    

static _kernel_oserror erBuff =
{ ERROR_BUFFER_OVERFLOW, "dBoxTools buffer too small"};

_kernel_oserror *swi_despatch( int swi, _kernel_swi_regs *r )
{ int i;
  int flags = r->r[0] >> 1;
  _kernel_oserror *er = NULL;
  
  if( flags & 2 ) r->r[1] = findTask( (char *) r->r[1] );
  if( flags & 4 ) r->r[2] = (int) find_object( (char *) r->r[2] );
  if( flags & 8 )
  { if( *(char *) (r->r[3]) == ':' ) r->r[3]++; 
    r->r[3] = (int) strtol( (char*) r->r[3], NULL, 16 );
  }
   
  switch( swi )
  { case dBoxTools_SetClient      : er = swi_SetClient( r ); break;
    case dBoxTools_SetClientHandle: er = swi_SetClientHandle( r ); break;
    case dBoxTools_SetOutPutFocus : er = swi_SetOutPutFocus( r ); break;
    case dBoxTools_SetDestination : er = swi_SetDestination( r ); break;
    case dBoxTools_SetValue       : er = swi_SetValue( r ); break;
    case dBoxTools_GetValue       : er = swi_GetValue( r ); break;
    case dBoxTools_Quit           : er = swi_Quit( r ); break;
    return NULL;}

  if( er ) return er;
  if( flags & RETURN_AS_TEXT )
  { sprintf( buffer, "%i%n", r->r[4], &i );
    if( i + 1 > r->r[5] ) return &erBuff;
    return NULL;}
  return er;  
}

/* end of swi.c */

