#include <exec/types.h>
#include <exec/libraries.h>
#include <exec/execbase.h>
#include <inline/exec.h>
#include <libraries/dosextens.h>

#include <sys/syscall.h>

/* get the current revision number. Version control is automatically done by
 * OpenLibrary(), I just have to check the revision number 
 */
#include "/library/version.h"

struct Library *ixemulbase;

static int start_stdio();

/*
 * Have to take care.. I may not use any library functions in this file,
 * since they are exactly then used, when the library itself couldn't be
 * opened...
 */
static char *build_warn (char *t1, int num1, char *t2, int num2);

extern int main();
extern int expand_cmd_line;
extern char *default_wb_window;
extern int errno;
extern char *_ctype_;
extern int sys_nerr;

int
ENTRY()
{
  register unsigned char *rega0  asm("a0");
  register unsigned long  regd0  asm("d0");

  UBYTE *aline = rega0;
  ULONG alen = regd0;

  int res = 20;
  
  ixemulbase = OpenLibrary ("ixemul.library", 37);
  if (ixemulbase)
    {
      /* just warn, in case the user tries to run program with might require
       * more functions than are currently available under this revision. */
      if (ixemulbase->lib_Revision < IX_REVISION)
	{
	  /* I wish I had stdio in the library... */
	  __panic_msg ("ixemul.library warning: current revision ",
	  	       ixemulbase->lib_Revision,
	  	       ", needed revision ",
	  	       IX_REVISION);
	}

      res = ix_startup (aline, alen, 
		        expand_cmd_line, default_wb_window, start_stdio, &errno);

      CloseLibrary (ixemulbase);
    }
  else
    {
      struct Process *me = (struct Process *)((*(struct ExecBase **)4)->ThisTask);

      __panic_msg ("Need at least version ", IX_VERSION, " of ixemul.library.", 0);
      
      /* quickly deal with the WB startup message, as the library couldn't do
       * this for us. Nothing at all is done that isn't necessary to just shutup
       * workbench..*/
      if (! me->pr_CLI)
        {
	  Forbid (); 
	  ReplyMsg ((WaitPort (& me->pr_MsgPort), GetMsg (& me->pr_MsgPort)));
	}
      
      res = 20;
    }

  return res;
}

int
start_stdio(int a1, int a2)
{
  int res;

  /* more to follow ;-) */
  ix_get_vars (&_ctype_, &sys_nerr);

  _init_stdio();

  res = main (a1, a2);
  return res;
}

/* this thing is best done with sprintf else, but I don't want to include
 * the stdio package per default... 
 */
static char *
itoa (int num)
{
  short snum = num;

  /* how large can a long get...?? */
  static char buf[16];
  char *cp;
  
  buf[15] = 0;
  for (cp = &buf[15]; snum; snum /= 10) 
    *--cp = (snum % 10) + '0';

  return cp;
}

static char *
pstrcpy (char *start, char *arg)
{
  while (*start++=*arg++) ;
  return start-1;
}

static char *
build_warn (char *t1, int num1, char *t2, int num2)
{
  char buf[255], *cp;
  
  cp = pstrcpy (buf, t1);
  cp = pstrcpy (cp, itoa (num1));
  cp = pstrcpy (cp, t2);
  if (num2)
    pstrcpy (cp, itoa (num2));

  return buf;
}
