/***********************************************************
 * UAE - The U*nix Amiga Emulator                          *
 *                                                         *
 * UAE-Control -- Emulator Control from Inside Emulation   *
 *  (c) 1996 Tauno Taipaleenmaki <tataipal@raita.oulu.fi>  *
 *                                                         *
 * Version 0.1                                             *
 *                                                         *
 * Requires V36 or higher. Compiled with SAS/C 6.5         *
 *                                                         *
 * People with KS1.3 or lower should use the command line  *
 * version "uaectrl"                                       *
 ***********************************************************/
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/gadtools.h>
#include <proto/graphics.h>
#include <proto/reqtools.h>
#include <intuition/intuition.h>
#include <libraries/reqtools.h>
#include <stdio.h>
#include <string.h>
#include "uae-control.h"
#include "uae_pragmas.h"

#define MAX_DRV_NAME          20

     struct Library              *ReqBase; 
     struct Library              *UaeBase;
     struct Window               *window;
     struct Screen               *scr;
     struct Gadget               *glist;
     APTR                        VisInfo;

struct UAE_CONFIG      config;

struct TextAttr topaz8 = {
       ( STRPTR )"topaz.font", 8, 0x00, 0x01 };

struct NewWindow newwindow = {
       20,20, 400,160, 0,1,
	 IDCMP_CLOSEWINDOW | BUTTONIDCMP | CYCLEIDCMP | INTEGERIDCMP,
	 WFLG_DRAGBAR | WFLG_CLOSEGADGET | WFLG_ACTIVATE | WFLG_DEPTHGADGET,
	 NULL,NULL,(UBYTE *)"UAE-Control v0.1",NULL,NULL,
	 0,0,0,0, CUSTOMSCREEN
};

int setup_window(void);
void quit_program(int error, char *text);
void print_drive_status(void);

/************************************
 * Main program                     *
 ************************************/
int main()
{
       int                  quit = 0,i;
       struct IntuiMessage  *msg;
       struct Gadget        *button;
       struct StringInfo    *strinfo;
       char                 buf[257];
       UWORD                koodi, msgID;
       ULONG                classi, number;
       APTR                 address;
       ULONG                CycleTags[3];

       CycleTags[0] = GTCY_Active;
       CycleTags[1] = (ULONG)&number;
       CycleTags[2] = TAG_DONE;
       
       ReqBase = OpenLibrary("reqtools.library",0);
       if (!ReqBase) {
	      quit_program(1, "Reqtools.library needed!");
	      return(1);
       }
       UaeBase = OpenLibrary("uae.library",0);
       if (!UaeBase) {
	      UaeBase = OpenLibrary("uae.library",0);
	      if (!UaeBase) {
		     quit_program(1, "Emulator not running or uae.library not installed.\n");
		     return(1);
	      }
       }
/* Read UAE configuration */
       i = GetUaeConfig( &config );
       
       i = setup_window();
       if (i == 0) {
	      quit_program(1, "Cannot setup a window!");
	      return(1);
       }
       while( quit == 0 ) {
	      WaitPort(window->UserPort);
	      while( msg = (struct IntuiMessage *)GT_GetIMsg(window->UserPort))
		{
		       classi = msg->Class;
		       koodi = msg->Code;
		       address = msg->IAddress;
		       if (classi == IDCMP_GADGETUP) {
			      msgID = ((struct Gadget *)msg->IAddress)->GadgetID;
			      button = (struct Gadget *)msg->IAddress;
			      if (button->SpecialInfo) {
				     strinfo = (struct StringInfo *)button->SpecialInfo;
			      }
		       } else
			 msgID = msg->Code;

		       GT_ReplyIMsg((struct IntuiMessage *)msg);
		       
		       switch( classi ) {
			case IDCMP_CLOSEWINDOW:
			      quit = 1;
			      break;
			case IDCMP_GADGETUP:
			      switch( msgID ) {
			       case GAD_EXITEMU:
				     ExitEmu();
				     break;
			       case GAD_EJECT_DF0:
				     EjectDisk(0);
				     GetUaeConfig( &config );
				     print_drive_status();
				     break;
			       case GAD_EJECT_DF1:
				     EjectDisk(1);
				     GetUaeConfig( &config );
				     print_drive_status();
				     break;
			       case GAD_EJECT_DF2:
				     EjectDisk(2);
				     GetUaeConfig( &config );
				     print_drive_status();
				     break;
			       case GAD_EJECT_DF3:
				     EjectDisk(3);
				     GetUaeConfig( &config );
				     print_drive_status();
				     break;
			       case GAD_SOUND:
				     if (config.do_output_sound) {
					    DisableSound();
				     } else {
					    EnableSound();
				     }
				     GetUaeConfig( &config );
				     break;
			       case GAD_JOYSTICK:
				     if (config.do_fake_joystick) { 
					    DisableJoystick();
				     } else {
					    EnableJoystick();
				     }
				     GetUaeConfig( &config );
				     break;
			       case GAD_FRAMERATE:
				     SetFrameRate( strinfo->LongInt );
				     GetUaeConfig( &config );
				     break;
			       case GAD_INSERT_DF0:
				     i = rtGetStringA( (UBYTE *)&buf, 255, 
						  (UBYTE *)"Disk-file name:",
						  NULL, TAG_DONE);
				     if (i) {
					    InsertDisk((UBYTE *)&buf, 0);
					    GetUaeConfig( &config );
					    print_drive_status();
				     }
				     break;
			       case GAD_INSERT_DF1:
				     i = rtGetStringA( (UBYTE *)&buf, 255,
						      (UBYTE *)"Disk-file name:",
						      NULL, TAG_DONE);
				     if (i) {
					    InsertDisk((UBYTE *)&buf, 1);
					    GetUaeConfig( &config );
					    print_drive_status();
				     }
				     break;
			       case GAD_INSERT_DF2:
				     i = rtGetStringA( (UBYTE *)&buf, 255,
						      (UBYTE *)"Disk-file name:",
						      NULL, TAG_DONE);
				     if (i) {
					    InsertDisk((UBYTE *)&buf, 2);
					    GetUaeConfig( &config );
					    print_drive_status();
				     }
				     break;
			       case GAD_INSERT_DF3:
				     i = rtGetStringA( (UBYTE *)&buf, 255,
						      (UBYTE *)"Disk-file name:",
						      NULL, TAG_DONE);
				     if (i) {
					    InsertDisk((UBYTE *)&buf, 3);
					    GetUaeConfig( &config );
					    print_drive_status();
				     }
				     break;
			       case GAD_LANGUAGE:
				     number = config.keyboard;
				     number++;
				     if (number == 5) 
				       number = 0;
				     ChangeLanguage( number );
				     GetUaeConfig( &config );
				     break;
			       case GAD_RESET:
				     ColdReboot();
				     break;
			       case GAD_DEBUG:
				     DebugFunc();
				     break;
			       default:
				     break;
			      }
			      break;
			default:
			      break;
		       }
		}
       }
       quit_program(0, "");
       return(0);
}

/******************************************
 * Quits the program                      *
 ******************************************/
void quit_program(int error, char *text)
{
       if (error > 0) {
	      printf(" UAE-Control v0.1\n");
	      printf("  (c)1996 Tauno Taipaleenmaki\n\n");
	      printf(" ERROR: %s\n", text);
       }
       if (scr) 
	 UnlockPubScreen(NULL, scr);
       if (window)
	 CloseWindow( window );
       if (VisInfo)
	 FreeVisualInfo( VisInfo );
       if (glist)
	 FreeGadgets( glist );
       if (ReqBase)
	 CloseLibrary( ReqBase );
       if (UaeBase)
	 CloseLibrary( UaeBase );
}


/******************************************
 * Opens up the window & sets the gadgets *
 ******************************************/
int setup_window(void)
{
       struct Gadget           *g;
       struct NewGadget        ng;
       UWORD                   offy;
       ULONG                   drawtags[20];

       static const char *keyb_langs[] =
	 {
		"US",
		"DE",
		"SE",
		"FR",
		"IT",
		NULL
	 };

       scr = LockPubScreen(NULL);
       if (!scr)
	 return(0);
       
       VisInfo = GetVisualInfo( scr, TAG_DONE );
       if (!VisInfo)
	 return(0);
       
       offy = scr->WBorTop + scr->RastPort.TxHeight + 1;

/* Create buttons */
       g = CreateContext( &glist );
       if (!g)
	 return(0);
       
       ng.ng_TextAttr = &topaz8;
       ng.ng_VisualInfo = VisInfo;
       ng.ng_Flags = PLACETEXT_IN;
       ng.ng_LeftEdge = 10; ng.ng_TopEdge = offy + 10;
       ng.ng_Width = 90; ng.ng_Height = 15;
       ng.ng_GadgetText = (UBYTE *)"Hard reset";
       ng.ng_GadgetID = GAD_RESET;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       
       ng.ng_LeftEdge = 102; ng.ng_Width = 50;
       ng.ng_GadgetText = (UBYTE *)"Debug";
       ng.ng_GadgetID = GAD_DEBUG;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       
       ng.ng_LeftEdge = 153; ng.ng_Width = 50;
       ng.ng_GadgetText = (UBYTE *)"Exit";
       ng.ng_GadgetID = GAD_EXITEMU;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);

/* Eject buttons */
       ng.ng_LeftEdge = 250; ng.ng_Width = 70;
       ng.ng_TopEdge = offy + 35;
       ng.ng_GadgetID = GAD_EJECT_DF0;
       ng.ng_GadgetText = (UBYTE *)"Eject";
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       ng.ng_TopEdge = offy + 53;
       ng.ng_GadgetID = GAD_EJECT_DF1;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       ng.ng_TopEdge = offy + 70;
       ng.ng_GadgetID = GAD_EJECT_DF2;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       ng.ng_TopEdge = offy + 87;
       ng.ng_GadgetID = GAD_EJECT_DF3;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);

/* Insert buttons */
       ng.ng_LeftEdge = 321; ng.ng_TopEdge = offy + 35;
       ng.ng_GadgetID = GAD_INSERT_DF0;
       ng.ng_GadgetText = (UBYTE *)"Insert";
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       ng.ng_TopEdge = offy + 53;
       ng.ng_GadgetID = GAD_INSERT_DF1;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       ng.ng_TopEdge = offy + 70;
       ng.ng_GadgetID = GAD_INSERT_DF2;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);
       ng.ng_TopEdge = offy + 87;
       ng.ng_GadgetID = GAD_INSERT_DF3;
       g = CreateGadgetA(BUTTON_KIND, g, &ng, TAG_DONE);

/* Sound & Joystick buttons */       

       ng.ng_LeftEdge = 120;
       ng.ng_TopEdge = 120;
       ng.ng_GadgetID = GAD_SOUND;
       ng.ng_GadgetText = (UBYTE *)"Sound";
       ng.ng_Flags = PLACETEXT_LEFT;
       if (config.do_output_sound) {
	      drawtags[0] = GTCB_Checked;
	      drawtags[1] = 1;
	      drawtags[2] = TAG_DONE;
       } else {
	      drawtags[0] = TAG_DONE;
       }
       g = CreateGadgetA(CHECKBOX_KIND, g, &ng,(struct TagItem *)&drawtags);
       
       ng.ng_TopEdge = 135;
       ng.ng_GadgetID = GAD_JOYSTICK;
       ng.ng_GadgetText = (UBYTE *)"Fake Joystick";
       if (config.do_fake_joystick) {
	      drawtags[0] = GTCB_Checked;
	      drawtags[1] = 1;
	      drawtags[2] = TAG_DONE;
       } else {
	      drawtags[0] = TAG_DONE;
       }
       g = CreateGadgetA(CHECKBOX_KIND, g, &ng, (struct TagItem *)&drawtags);

       ng.ng_TopEdge = 130;
       ng.ng_LeftEdge = 160;
       ng.ng_GadgetID = GAD_LANGUAGE;
       ng.ng_GadgetText = (UBYTE *)"Language";
       ng.ng_Flags = PLACETEXT_ABOVE;
       drawtags[0] = GTCY_Labels;
       drawtags[1] = (ULONG)keyb_langs;
       drawtags[2] = GTCY_Active;
       drawtags[3] = config.keyboard;
       drawtags[4] = TAG_DONE;
       g = CreateGadgetA(CYCLE_KIND, g, &ng, (struct TagItem *)&drawtags);

       ng.ng_TopEdge = 130;
       ng.ng_LeftEdge = 250;
       ng.ng_GadgetID = GAD_FRAMERATE;
       ng.ng_GadgetText = (UBYTE *)"Framerate";
       ng.ng_Flags = PLACETEXT_ABOVE;
       drawtags[0] = GTIN_Number;
       drawtags[1] = config.framerate;
       drawtags[2] = TAG_DONE;
       g = CreateGadgetA(INTEGER_KIND, g, &ng, (struct TagItem *)&drawtags);
       
       newwindow.FirstGadget = glist;
       newwindow.Screen = scr;             /* Store screen ptr */
       window = OpenWindow( &newwindow );
       if (!window)
	 return(0);

/* Draw texts etc... */
       Move(window->RPort, 10, offy + 35 + 10);
       Text(window->RPort, (UBYTE *)"DF0:", 4);
       Move(window->RPort, 10, offy + 53 + 10);
       Text(window->RPort, (UBYTE *)"DF1:", 4);
       Move(window->RPort, 10, offy + 70 + 10);
       Text(window->RPort, (UBYTE *)"DF2:", 4);
       Move(window->RPort, 10, offy + 87 + 10);
       Text(window->RPort, (UBYTE *)"DF3:", 4);

       drawtags[0] = (GT_VisualInfo);
       drawtags[1] = (ULONG)VisInfo;
       drawtags[2] = GTBB_Recessed;
       drawtags[3] = 1;
       drawtags[4] = TAG_DONE;
       
       DrawBevelBoxA(window->RPort, 5, offy + 34, 
		     390, 17, (struct TagItem *)&drawtags);
       DrawBevelBoxA(window->RPort, 5, offy + 52,
		     390, 17, (struct TagItem *)&drawtags);
       DrawBevelBoxA(window->RPort, 5, offy + 69,
		     390, 17, (struct TagItem *)&drawtags);
       DrawBevelBoxA(window->RPort, 5, offy + 86,
		     390, 17, (struct TagItem *)&drawtags);

       print_drive_status();

       UnlockPubScreen(NULL, scr);
       return(1);
}

void print_drive_status(void)
{
       char     empty[80];
       int      len;
       UWORD    offy = scr->WBorTop + scr->RastPort.TxHeight + 1;
       
       for(len=0;len<80;len++) 
	 empty[len] = ' ';
       empty[79] = '\0';
       
       Move(window->RPort, 42, offy + 45);
       if (config.disk_in_df0) {
	      len = strlen( config.df0_name );
	      if (len > MAX_DRV_NAME)
		len = MAX_DRV_NAME;
	      Text(window->RPort, (UBYTE *)config.df0_name, len);
       } else {
	      Text(window->RPort, (UBYTE *)empty, MAX_DRV_NAME);
       }
       
       Move(window->RPort, 42, offy + 63);
       if (config.disk_in_df1) {
	      len = strlen( config.df1_name );
	      if (len > MAX_DRV_NAME)
		len = MAX_DRV_NAME;
	      Text(window->RPort, (UBYTE *)config.df1_name, len);
       } else {
	      Text(window->RPort, (UBYTE *)empty, MAX_DRV_NAME);
       }
       
       Move(window->RPort, 42, offy + 80);
       if (config.disk_in_df2) {
	      len = strlen( config.df2_name );
	      if (len > MAX_DRV_NAME)
		len = MAX_DRV_NAME;
	      Text(window->RPort, (UBYTE *)config.df2_name, len);
       } else {
	      Text(window->RPort, (UBYTE *)empty, MAX_DRV_NAME);
       }
       
       Move(window->RPort, 42, offy + 97);
       if (config.disk_in_df3) {
	      len = strlen( config.df3_name );
	      if (len > MAX_DRV_NAME)
		len = MAX_DRV_NAME;
	      Text(window->RPort, (UBYTE *)config.df3_name, len);
       } else {
	      Text(window->RPort, (UBYTE *)empty, MAX_DRV_NAME);
       }
}



