#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>

#include "atari.h"

static char *rcsid = "$Id: configure.c,v 1.15 1997/01/01 01:55:59 david Exp $";

jmp_buf jmpbuf;

void
bus_err()
{
  longjmp(jmpbuf, 1);
}

int
unaligned_long_ok()
{
  long l[2];

  if (setjmp(jmpbuf) == 0)
    {
      signal(SIGBUS, bus_err);
      *((long *) ((char *) l + 1)) = 1;
      signal(SIGBUS, SIG_DFL);
      return 1;
    }
  else
    {
      signal(SIGBUS, SIG_DFL);
      return 0;
    }
}
 
void RemoveLF (char *string)
{
  int len;

  len = strlen (string);
  if (string[len-1] == '\n')
    string[len-1] = '\0';
}

void GetString (char *message, char *string)
{
  char gash[128];

  printf (message, string);
  gets (gash);
  if (strlen(gash) > 0)
    strcpy (string, gash);
}

void GetNumber (char *message, int *num)
{
  char gash[128];

  printf (message, *num);
  gets (gash);
  if (strlen(gash) > 0)
    sscanf (gash,"\n%d", num);
}

void YesNo (char *message, char *yn)
{
  char gash[128];
  char t_yn;

  do
    {
      printf (message, *yn);
      gets (gash);

      if (strlen(gash) > 0)
	t_yn = gash[0];
      else
	t_yn = ' ';

      if (islower(t_yn))
	t_yn = toupper(t_yn);
    } while ((t_yn != ' ') && (t_yn != 'Y') && (t_yn != 'N'));

  if (t_yn != ' ')
    *yn = t_yn;
}

int main (void)
{
  FILE *fp;
  char config_filename[256];
  char *home;

  char config_version[256];
  char gash[256];

  char atari_osa_filename[256];
  char atari_osb_filename[256];
  char atari_xlxe_filename[256];
  char atari_basic_filename[256];
  char atari_5200_filename[256];

  char disk_dir[256];
  char rom_dir[256];
  char h1_dir[256];
  char h2_dir[256];
  char h3_dir[256];
  char h4_dir[256];
  char print_command[256];
  int refresh_rate;
  char linux_joystick;
  char direct_video;
  int allow_unaligned_long = 0;

  home = getenv ("~");
  if (!home)
    home = getenv ("HOME");
  if (!home)
    home = ".";

  strcpy (atari_osa_filename, "atariosa.rom");
  strcpy (atari_osb_filename, "atariosb.rom");
  strcpy (atari_xlxe_filename, "atarixl.rom");
  strcpy (atari_basic_filename, "ataribas.rom");
  strcpy (atari_5200_filename, "atari5200.rom");

#ifndef DJGPP
  strcpy (disk_dir, "/usr/local/lib/atari/DISKS");
  strcpy (h1_dir, "/usr/local/lib/atari/H1");
  strcpy (h2_dir, "/usr/local/lib/atari/H2");
  strcpy (h3_dir, "/usr/local/lib/atari/H3");
  strcpy (h4_dir, "/usr/local/lib/atari/H4");
  strcpy (print_command, "lpr %s");
  strcpy (rom_dir, "/usr/local/lib/atari/ROMS");
  refresh_rate = 1;
  linux_joystick = 'N';
  direct_video = 'N';

  sprintf (config_filename, "%s/.atari800", home);
#else
  strcpy (disk_dir, "c:/atari800/DISKS");
  strcpy (h1_dir, "c:/atari800/H1");
  strcpy (h2_dir, "c:/atari800/H2");
  strcpy (h3_dir, "c:/atari800/H3");
  strcpy (h4_dir, "c:/atari800/H4");
  strcpy (print_command, "copy %s prn");
  strcpy (rom_dir, "c:/atari800/ROMS");
  refresh_rate = 1;
  linux_joystick = 'N';
  direct_video = 'N';

  sprintf (config_filename, "%s/atari800.cfg", home);
#endif

  fp = fopen (config_filename, "r");
  if (fp)
    {
      char *ptr;
      int len;

      printf ("\nReading: %s\n\n", config_filename);

      fgets (config_version, 256, fp);

      ptr = strrchr(config_version, ' ');
      if (ptr)
	*ptr = '\0';
      len = strlen (config_version);

      if (strncmp(ATARI_TITLE, config_version, len) == 0)
	{
	  fgets (atari_osa_filename, 256, fp);
	  RemoveLF (atari_osa_filename);

	  fgets (atari_osb_filename, 256, fp);
	  RemoveLF (atari_osb_filename);

	  fgets (atari_xlxe_filename, 256, fp);
	  RemoveLF (atari_xlxe_filename);

	  fgets (atari_basic_filename, 256, fp);
	  RemoveLF (atari_basic_filename);

	  fgets (atari_5200_filename, 256, fp);
	  RemoveLF (atari_5200_filename);

	  fgets (disk_dir, 256, fp);
	  RemoveLF (disk_dir);

	  fgets (h1_dir, 256, fp);
	  RemoveLF (h1_dir);

	  fgets (h2_dir, 256, fp);
	  RemoveLF (h2_dir);

	  fgets (h3_dir, 256, fp);
	  RemoveLF (h3_dir);

	  fgets (h4_dir, 256, fp);
	  RemoveLF (h4_dir);

	  fgets (print_command, 256, fp);
	  RemoveLF (print_command);

	  fgets (rom_dir, 256, fp);
	  RemoveLF (rom_dir);

	  if (fscanf(fp,"%d", &refresh_rate) == 0)
	    refresh_rate = 1;

	  if (fscanf (fp,"\n%c", &linux_joystick) == 0)
	    linux_joystick = 'N';

	  if (fscanf (fp,"\n%c\n", &direct_video) == 0)
	    direct_video = 'N';
	}
      else
	{
	  strcpy (disk_dir, config_version); /* This has already been read */
	  RemoveLF (disk_dir);

	  fgets (h1_dir, 256, fp);
	  RemoveLF (h1_dir);

	  fgets (h2_dir, 256, fp);
	  RemoveLF (h2_dir);

	  fgets (h3_dir, 256, fp);
	  RemoveLF (h3_dir);

	  fgets (h4_dir, 256, fp);
	  RemoveLF (h4_dir);

	  fgets (print_command, 256, fp);
	  RemoveLF (print_command);

	  fgets (rom_dir, 256, fp);
	  RemoveLF (rom_dir);

	  if (fscanf(fp,"%d", &refresh_rate) == 0)
	    refresh_rate = 1;

	  if (fscanf (fp,"\n%c", &linux_joystick) == 0)
	    linux_joystick = 'N';

          fscanf (fp, "\n%c", &gash[0]); /* FPS Monitor is Obsolete */

	  if (fscanf (fp,"\n%c\n", &direct_video) == 0)
	    direct_video = 'N';

	  fgets (gash, 256, fp); /* os_dir is Obsolete */
	}

      fclose (fp);
    }

  GetString ("Enter path to Atari OS/A ROM [%s] ", atari_osa_filename);
  GetString ("Enter path to Atari OS/B ROM [%s] ", atari_osb_filename);
  GetString ("Enter path to Atari XL/XE ROM [%s] ", atari_xlxe_filename);
  GetString ("Enter path to Atari BASIC ROM [%s] ", atari_basic_filename);
  GetString ("Enter path to Atari 5200 ROM [%s] ", atari_5200_filename);

  GetString ("Enter path for disk images [%s] ", disk_dir);
  GetString ("Enter path for ROM images [%s] ", rom_dir);
  GetString ("Enter path for H1: device [%s] ", h1_dir);
  GetString ("Enter path for H2: device [%s] ", h2_dir);
  GetString ("Enter path for H3: device [%s] ", h3_dir);
  GetString ("Enter path for H4: device [%s] ", h4_dir);
  GetString ("Enter command to print file [%s] ", print_command);
  GetNumber ("Generate screen every (1-50) frame(s) [%d] ", &refresh_rate);
  if (refresh_rate < 1)
    refresh_rate = 1;
  else if (refresh_rate > 50)
    refresh_rate = 50;
  YesNo ("Enable LINUX Joystick [%c] ", &linux_joystick);
  YesNo ("Enable Direct Video Access [%c] ", &direct_video);

  printf("Testing unaligned long accesses...");
  if ((allow_unaligned_long = unaligned_long_ok()))
  {
    printf("OK\n");
  }
  else
  {
    printf("not OK\n");
  }

  fp = fopen ("config.h", "w");
  if (fp)
    {
      fprintf (fp, "#ifndef __CONFIG__\n");
      fprintf (fp, "#define __CONFIG__\n");

      fprintf (fp, "#define ATARI_OSA_FILENAME \"%s\"\n",
	       atari_osa_filename);
      fprintf (fp, "#define ATARI_OSB_FILENAME \"%s\"\n",
	       atari_osb_filename);
      fprintf (fp, "#define ATARI_XLXE_FILENAME \"%s\"\n",
	       atari_xlxe_filename);
      fprintf (fp, "#define ATARI_BASIC_FILENAME \"%s\"\n",
	       atari_basic_filename);
      fprintf (fp, "#define ATARI_5200_FILENAME \"%s\"\n",
	       atari_5200_filename);

      fprintf (fp, "#define ATARI_DISK_DIR \"%s\"\n", disk_dir);
      fprintf (fp, "#define ATARI_ROM_DIR \"%s\"\n", rom_dir);
      fprintf (fp, "#define ATARI_H1_DIR \"%s\"\n", h1_dir);
      fprintf (fp, "#define ATARI_H2_DIR \"%s\"\n", h2_dir);
      fprintf (fp, "#define ATARI_H3_DIR \"%s\"\n", h3_dir);
      fprintf (fp, "#define ATARI_H4_DIR \"%s\"\n", h4_dir);
      fprintf (fp, "#define PRINT_COMMAND \"%s\"\n", print_command);
      fprintf (fp, "#define DEFAULT_REFRESH_RATE %d\n", refresh_rate);

      if (linux_joystick == 'Y')
        fprintf (fp, "#define LINUX_JOYSTICK\n");

      if (direct_video == 'Y')
        fprintf (fp, "#define DIRECT_VIDEO\n");

      if (allow_unaligned_long == 1)
	fprintf (fp, "#define UNALIGNED_LONG_OK\n");

      fprintf (fp, "#endif\n");

      fclose (fp);
    }

  fp = fopen (config_filename, "w");
  if (fp)
    {
      printf ("\nWriting: %s\n\n", config_filename);

      fprintf (fp, "%s\n", ATARI_TITLE);
      fprintf (fp, "%s\n", atari_osa_filename);
      fprintf (fp, "%s\n", atari_osb_filename);
      fprintf (fp, "%s\n", atari_xlxe_filename);
      fprintf (fp, "%s\n", atari_basic_filename);
      fprintf (fp, "%s\n", atari_5200_filename);
      fprintf (fp, "%s\n", disk_dir);
      fprintf (fp, "%s\n", h1_dir);
      fprintf (fp, "%s\n", h2_dir);
      fprintf (fp, "%s\n", h3_dir);
      fprintf (fp, "%s\n", h4_dir);
      fprintf (fp, "%s\n", print_command);
      fprintf (fp, "%s\n", rom_dir);
      fprintf (fp, "%d\n", refresh_rate);
      fprintf (fp, "%c\n", linux_joystick);
      fprintf (fp, "%c\n", direct_video);

      fclose (fp);
    }
  else
    {
      perror (config_filename);
      exit (1);
    }

  return 0;
}
