/*-------------------------------------------------------*/
/* ProjectOmega                 									*/
/* Written by T.Miles												*/
/* ID: 289175															*/
/* Module:	Plugin Class   									   */
/* Derived from App class											*/
/* Provides storage & retrieval mechanisms for incoming  */
/* data.  Handles config file I/O								*/
/*-------------------------------------------------------*/


#include <clib/exec_protos.h>
#include <dos/dosextens.h>
#include <string.h>
#include "misc/filereq.h"
#include "plugin.h"
#include <iostream.h>
#include <fstream.h>

/************************************************/
/* Plugin Class Methods                         */
/************************************************/

OmegaPlugin::OmegaPlugin(){
	oa_SetName("ProjectOmega Plugin");
	op_Configured=FALSE;
	op_TrackNames=NULL;
	op_Type=0;
	op_ID=0;
	coordScreen=NULL;
}

OmegaPlugin::~OmegaPlugin(){
//	cout << "Deleting plugin" << endl;
	UINT size=op_Tracks.GetSize();
	if (op_TrackNames)
		delete []op_TrackNames;
		
	// Our tracks are stored as pointers now so we need to free
	// the memory
	for (UINT n=0;n<size;n++){
		if (op_Tracks[n]!=NULL)
			delete op_Tracks[n];
	}
}

void OmegaPlugin::BuildTrackNames(){
	OmegaTrack *pTrack;
	UINT size=op_Tracks.GetSize();

	if (op_TrackNames)
		delete[] op_TrackNames;
	
	if (size!=0)
		op_TrackNames=new char *[size];
	else
		op_TrackNames=NULL;
			
	for (UINT n=0;n<size;n++){
		pTrack=op_Tracks.GetItem(n);
		op_TrackNames[n]=pTrack->GetName();  // Point to first letter
	}	
}

BOOL OmegaPlugin::StartUp(){
	// Create the track name array and initialise it
	BuildTrackNames();
	
	coordPort=FindPort("ProjectOmega");		// Find the port we need to signal
	if (!coordPort){
		Error("Unable To Find ProjectOmega","I Need the Coordinator!");
		return FALSE;
	}
	else
		return OmegaApp::Initialise(NULL);
}

//
// The only message the plugin knows how to deal with is 'configure'
// Otherwise we pass it on the the app class
void OmegaPlugin::DealWithMessage(OmegaMessage *msg){
	UINT Class=msg->om_Class;
	if (Class==OM_CONFIG){
		ReplyMsg((Message *)msg);
		OnConfig();
	}
	else
		OmegaApp::DealWithMessage(msg);
}
	
void OmegaPlugin::op_SaveTracks(){
	UINT size=op_Tracks.GetSize();
	FILE *file;
	UINT n;

	file=OpenConfigFile(TRUE,TRUE);
	if (file){
		for (n=0;n<size;n++){
			fwrite("%\n",2,1,file);		// Denote a new track
			op_Tracks[n]->Save(file);
		}
		fwrite("$\n",2,1,file);
		OnSaveConfig(file);				// Denote custom data
		fclose(file);
	}
}

// Get a handle to a config file
// If save mode is requested then it saves out Plugin Identifier first
// If load mode, checks config file for correct identifier
//
// Input:  req=TRUE -> Will ask for a filename
//			  req=FALSE -> Uses the default file name
//			  save=TRUE -> opens up a writable file, saves ID
//			  save=FALSE -> opens a readable file, checks ID
// Output: Handle to the config file if successful, NULL if failed 
// 		  or if requester was cancelled 
//
FILE *OmegaPlugin::OpenConfigFile(BOOL req, BOOL save){
	FileReq myReq;
	FILE *file=NULL;
	char *filename=new char[30];
	ULONG id;

	sprintf(filename,"%d.cfg",op_Type);
	// Open the file - prompt if necessary
	if (!req)
		file=fopen(filename,"r");
	else{	
		file=myReq.CreateRequester("Select Config File",filename,NULL,"#?.cfg",save);
		if (myReq.Cancelled())
			file=NULL;
	}
	// Write ID or check it
	if (file){
		if (save)
			fprintf(file,"%x\n",op_Type);
		else{
			if(!(fscanf(file,"%x\n",&id) && id==op_Type)){
				fclose(file);
				file=NULL;
			}
		}
	}
	// If we haven't asked for a requester then it's the initial config
	// so don't pop up an error if we can't find the thing!
	if (!file && !myReq.Cancelled() && req){
		if (save)	
			Error("File Saving Error","Unable to Open File");
		else
			Error("File Loading Error","Unable to Open File");		
	}
	// Return result
	delete[]filename;
	return file;
}
		
void OmegaPlugin::op_LoadTracks(BOOL defConfig){
	char tag;

	char *buffer=new char[256];
	UINT min,max,type;
	UINT or,n,results=0;
	OmegaTrack *newTrack;
	
	FILE *file=OpenConfigFile(!defConfig);

	if (file){
		// Clear our tracklist - but only if we've opened the file
		while (op_Tracks.GetSize()!=0){
			newTrack=op_Tracks.GetItem(0);	// Get a reference to the old track
			delete newTrack;						// Delete the space used
			op_Tracks.DeleteItem(0);			// Remove the pointer in our array
		}					
	
		// Should check file to see if it is a valid config file
		while (!(feof(file))){
			tag=fgetc(file);
			switch(tag){
			case '%':
				// Read in the track name & number of conditions
				results=fscanf(file,"%s %d %d\n",buffer,&or, &n);
				newTrack=new OmegaTrack(buffer,or,n);
				// This stuff should really be done in the track class but I've
				// had so many problems getting it to work that way!
				// This way works - so what the hell!
				for (n=0;n<MAXCONDITIONS;n++){
					results=fscanf(file,"%d%d%d%d\n",&type,&min,&max,&or);
					newTrack->SetCondition(n,(UBYTE)type,(UBYTE)min,(UBYTE)max,or);
				}
				op_Tracks.AddItem(newTrack);
				break;
			case '$':
				OnLoadConfig(file);
				break;
			}
		}
		fclose(file)
	}
	delete[] buffer;
} 

void OmegaPlugin::OnConfig(){
	Error("No Configuration Required",NULL);
}
