/****************************************************************************\
*
* Magnetic Scrolls Interpreter by Niclas Karlsson 1997
*
* (Simple) ANSI interface main.c
*
\****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "defs.h"
#include "unix.h"
#include "x11lib.h"
#include "main.h"

extern type32 i_count;

type8 buffer[80],xpos=0,bufpos=0,log_on=0,ms_gfx_enabled,filename[128];
FILE *log=0,*log2=0;

type8 ms_load_file(type8 *name, type8 *ptr, type16 size) {
  FILE *fh;
  type8 *realname;

  if ( name ) {
    realname=name;
  } else {
    printf ( "Error; filename oddity.\n" );
    exit ( 0 );
  }

  if (!(fh=fopen(realname,"rb"))) return 1;
  if (fread(ptr,1,size,fh)!=size) return 1;
  fclose(fh);
  return 0;
}

type8 ms_save_file(type8 *name, type8 *ptr, type16 size) {
  FILE *fh;
  type8 *realname;

  if ( name ) {
    realname=name;
  } else {
    printf ( "Error; filename oddity.\n" );
    exit ( 0 );
  }

  if (!(fh=fopen(realname,"wb"))) return 1;
  if (fwrite(ptr,1,size,fh)!=size) return 1;
  fclose(fh);
  return 0;
}

void script_write(type8 c) {
  if (log_on==2 && fputc(c,log)==EOF) {
    printf("[Problem with script file - closing]\n");
    fclose(log);
    log_on=0;
  }
}

void transcript_write(type8 c) {
  if (log2 && c==0x08 && ftell(log2)>0) fseek(log2,-1,SEEK_CUR);
  else if (log2 && fputc(c,log2)==EOF) {
    printf("[Problem with transcript file - closing]\n");
    fclose(log2);
    log2=0;
  }
}

void ms_statuschar ( type8 c ) {
  static char statusbuffer [ MAXLINE ];
  static type8 x=0;

  /* tab to top right region */
  if ( c == 0x09 ) {
    x = 65; /* skip to the last 15 chars */

  /* done with thie rendition of the status bar */
  } else if ( c == 0x0a ) {
    x = 0;
    unix_put_status ( statusbuffer );
    memset ( statusbuffer, ' ', 79 );

  } else {
    statusbuffer [ x ] = c;
    x++;
  }

  return;
}

/* ms_flush() is primarily used to flush lines to the terminal that
 * don't end with a newline.. ie: prompts.
 */
void ms_flush ( void ) {

  if ( unix_option ( "rawtext" ) ) {
    fflush ( stdout );
    return;
  }

  if ( ! bufpos ) {
    return; /* if no characters in buffer... */
  }

  buffer [ bufpos ] = '\0'; /* terminate buffer */

  unix_put_text ( buffer, 0 ); /* display buffer to terminal */

  bufpos = 0;               /* mark pending buffer as empty */
  bzero ( buffer, 80 );     /* empty buffer */

  return;
}

void ms_putchar ( type8 c ) {

  /* transcript_write ( c ); */ /* write transcript entry */

  if ( unix_option ( "rawtext" ) ) {
    printf ( "%c", c );
    return;
  }

  if ( c == 0 ) {               /* flush? */
    ms_flush();

  } else if ( c == 8 ) {               /* backspace?! */
    /* buffer [ bufpos-- ] = '\0'; */ /* hmmm */
    ms_flush();

  } else if ( ( c == 10 ) ||    /* newline */
	      ( c == 13 ) )     /* carriage return */
  {
    unix_put_text ( buffer, 1 ); /* enter current chars into queue */
    unix_put_text ( "", 1 );    /* enter into queue a blank line */
    bzero ( buffer, 80 );       /* clear buffer */
    bufpos = 0;                 /* reset cursor */

  } else if ( bufpos >= 78 ) {  /* line must be forcibly wrapped */
    char newbuffer [ 80 ];
    char *space = strrchr ( buffer, ' ' );

    if ( isprint ( c ) ) {
      buffer [ bufpos++ ] = c;  /* copy new char to buffer */
    }

    *space = '\0';              /* terminate old buffer */

    unix_put_text ( buffer, 1 );   /* pass it to normal mechanism */

    strncpy ( newbuffer, space + 1, 80 );  /* copy remainder */
    bzero ( buffer, 80 );                  /* wipe old buffer */
    strncpy ( buffer, newbuffer, 80 );     /* reinstant remainder */
    bufpos = strlen ( buffer );            /* reset cursor */

  } else if ( isprint ( c ) ) {
    buffer [ bufpos++ ] = c;      /* copy char to buffer */

  }

  return;
}

type8 ms_getchar ( void ) {
  int key = 0;

  if ( unix_option ( "rawtext" ) ) {

    poll_events();
    key = getchar();
    poll_events();

    return ( key );
  }

  while ( unix_query_keybuffer_depth() < 1 ) {
    poll_events();      /* process window system events */
    usleep ( 50000 );   /* waste time until input is available */
  }

  key = unix_pop_keybuffer();

  if ( key == 13 ) {
    key = 10;
  }

  ms_putchar ( (char) key );

  return ( (char) key );
}

void ms_showpic(type8 c,type8 mode) {
  /*	printf("Display picture [%d]\n",c); */
  /* Insert your favourite picture viewing code here */
  /* mode: 0 gfx off, 1 gfx on (thumbnails), 2 gfx on (normal) */

  /* unpack the image into the cache */
  unix_unpack_picture ( c, mode );

  /* queue up the image for display */
  unix_show_picture ( c, mode );

}

int main ( int argc, char *argv[] ) {
  type8  running, *gamename=0, *gfxname=0;
  type32 dlimit, slimit;

  printf ( "MAGNETIC\n" );
  printf ( "Original version by Niclas Karlsson\n" );
  printf ( "Unix port by Jeff Mitchell (skeezix@acm.org)\n" );
  printf ( "\n" );

  if (sizeof(type8)!=1 || sizeof(type16)!=2 || sizeof(type32)!=4) {
    fprintf(stderr,"You have incorrect typesizes, please edit "
	    "the typedefs and recompile\nor proceed on your"
	    "own risk...\n");
    exit(1);
  }

  /* NIL the game-to-load */
  unix_request_value ( 0 ) [ 0 ] = '\0';

  if ( ! unix_identify_options ( argc, argv ) ) {
    unix_usage();
    exit ( 0 );
  }

  /* did the user select a game to run? */
  if ( unix_request_value ( 0 ) [ 0 ] == '\0' ) {
    unix_usage();
    printf ( "Please provide a game name as well as options.\n" );
    exit ( 0 );
  }

  dlimit=slimit=0xffffffff;

  /* check for generic options */
  if ( unix_option ( "dump" ) ) {
    dlimit = atoi ( unix_option_value ( "dump" ) );
  }

  if ( unix_option ( "safety" ) ) {
    slimit = atoi ( unix_option_value ( "safety" ) );
  }

#ifdef 0
  case 't':	if (!(log2=fopen(&argv[i][2],"w"))) {
    printf("Failed to open \"%s\" for writing.\n",&argv[i][2]);
  }
#endif
#ifdef 0
  case 'r':
    if ( ( log = fopen( &argv[i][2],"r" ) ) ) {
      log_on=1;
    } else {
      printf("Failed to open \"%s\" for reading.\n",&argv[i][2]);
    }
#endif
#ifdef 0
  case 'w':
    if ( (log=fopen(&argv[i][2],"w")) ) {
      log_on=2;
    } else {
      printf("Failed to open \"%s\" for writing.\n",&argv[i][2]);
    }
#endif

  gamename = unix_request_value ( 0 );
  gfxname = unix_request_value ( 1 );

  printf ( "Selected game file: %s\n", gamename );
  printf ( "Selected graphics file: %s\n", gfxname );

  unix_init_graphics_engine();

  if (!(ms_gfx_enabled=ms_init(gamename,gfxname))) {
    printf("Couldn't start up game \"%s\".\n",gamename);
    exit(1);
  }

  /* check if this is a known game; if so, and we have a handler
   * for it, call the special handler.
   */
  if ( ( ! unix_option ( "nointro" ) ) &&
       ( ! unix_option ( "nopics" ) ) )
  {
    unix_special_intro();
  }

  ms_gfx_enabled--;
  running=1;

  while ((i_count<slimit) && running) {

    if (i_count>=dlimit) status();

    running=ms_rungame();

  }

  if (i_count==slimit) {
    printf("\n\nSafety limit (%ld) reached.\n",slimit);
    status();
  }
  ms_freemem();
  if (log_on) fclose(log);
  if (log2) fclose(log2);
  log2=0;
  printf("\nExiting.\n");

  unix_shutdown_graphics_engine();

  exit(0);
}
