#import "HyperupicControl.h"


@implementation HyperupicControl

static any_t runFunc(any_t obj)
{
  [((id)obj) runGen];
  return 0;
}

static DPSTimedEntryProc updateStatus( DPSTimedEntry te, double now,
    void *userData )
{
  HyperupicControl *self;

  self = userData;
  if (self->hypeGen) {
    if ([self->hypeGen getStatus] == IDLE) {
      [self->statusText setStringValue:"done"];

      if ( [self->hypeGen getSavedSoundFile] == NO ) {
	char msg[1024];
	sprintf(msg,"%7f", (float) ([self->hypeGen getBigee] ));
	[self->amplitudeText setStringValue:msg];
	sprintf(msg,"%7f", (float) ([self->hypeGen getDuration] ));
	[self->durationText setStringValue:msg];
      }
    }
    else {
      if ([self->hypeGen getStatus] == PAUSED)
	[self->statusText setStringValue:"paused"];
      else {
	char msg[1024];
	sprintf(msg,"%d%% computed", (int) ([self->hypeGen howFar] * 100.));
	[self->statusText setStringValue:msg];
	sprintf(msg,"%7f", (float) ([self->hypeGen getBigee] ));
	[self->amplitudeText setStringValue:msg];
	sprintf(msg,"%7f", (float) ([self->hypeGen getDuration] ));
	[self->durationText setStringValue:msg];
      }
    }
  }
  return 0;
}

+ create {

  id	newInstance;

  newInstance = [self new];
  return newInstance;
}

- init {

  [super init];
  hypeGen = [[HyperupicGen alloc] init];
  myTimedEntry = DPSAddTimedEntry( 3.0, (DPSTimedEntryProc) updateStatus,
		self, NX_BASETHRESHOLD );

  return self;
}

- sendAmplitudeText: (char *) stringValue {

  [amplitudeText setStringValue:stringValue];
  return self;
}

- sendStatusText: (char *) stringValue {

  [statusText setStringValue:stringValue];
  return self;
}

- sendMapPathText: (char *) stringValue{

  [mapPathText setStringValue:stringValue];
  return self;
}

- sendImagePathText: (char *) stringValue{

  [imagePathText setStringValue:stringValue];
  return self;
}

- displayFreqs: sender {

  [freqConWindow orderBack:sender];
  [hypeGen displayFreqs:sender];
  return self;
}

- setHarmsText: sender {

  [hypeGen setHarmsText:sender];
  return self;
}

- setxVal: sender {

  char	bonk[1024];

  [hypeGen setxVal:sender];
  sprintf(bonk,"%d", [hypeGen xendVal]);
  [xfText setStringValue:bonk];
  sprintf(bonk,"%d", 0);
  [xsText setStringValue:bonk];

  return self;
}

- setyVal: sender {

  char	bonk[1024];

  [hypeGen setyVal:sender];
  sprintf(bonk,"%d", [hypeGen yendVal]);
  [yfText setStringValue:bonk];
  sprintf(bonk,"%d", 0);
  [ysText setStringValue:bonk];

  return self;
}

- setxstartVal: sender {

  [hypeGen setxstartVal:sender];
  return self;
}

- setystartVal: sender {

  [hypeGen setystartVal:sender];
  return self;
}

- setxendVal: sender {

  [hypeGen setxendVal:sender];
  return self;
}

- setyendVal: sender {

  [hypeGen setyendVal:sender];
  return self;
}

- snuff: sender {

  if ([hypeGen getStatus] != IDLE) {
	[hypeGen snuff];
	[statusText setStringValue:"snuffed"];
  }
  else 
    NXRunAlertPanel("Shake your Booty","Holy Toledo! Nothing left to kill!",
		    "okie",NULL,NULL,NULL);

  return self;
}

- pause: sender {

  if ([hypeGen getStatus] == PAUSED) {
    [(HyperupicGen *)hypeGen resume];
    [statusText setStringValue:"running"];
  }
  else {
    if ([hypeGen getStatus] != IDLE) {
  	[(HyperupicGen *)hypeGen pause];
	[statusText setStringValue:"paused"];
    }
    else {
  	NXRunAlertPanel("Head Cheese","Look around you! We're idling.",
			"dokie",NULL,NULL,NULL);
//	[sender setState:0];
    }
  }

  return self;
}

- ampref: sender {
  [hypeGen ampref:sender];
  return self;
}

- time: sender {
  [hypeGen time:sender];
  return self;
}

- freqcon: sender {
  [hypeGen freqcon:sender];
  return self;
}

- freqdiff: sender {
  [hypeGen freqdiff:sender];
  return self;
}

- samplingRate: sender {
  [hypeGen samplingRate:sender];
  return self;
}

- seed: sender {
  [hypeGen seed:sender];
  return self;
}

- setSynt: sender {
  [hypeGen setSynt:sender];
  return self;
}

- setImagePath: sender {

  char	bonk[1024];

  if ( [hypeGen getStatus] == IDLE ) {
    [hypeGen setImagePath:sender];
    if ( [hypeGen getGotImage] == YES) {
      sprintf(bonk,"%d", [hypeGen xval]);
      [xText setStringValue:bonk];
      sprintf(bonk,"%d", [hypeGen yval]);
      [yText setStringValue:bonk];
      sprintf(bonk,"%d", [hypeGen xendVal]);
      [xfText setStringValue:bonk];
      sprintf(bonk,"%d", [hypeGen yendVal]);
      [yfText setStringValue:bonk];
      sprintf(bonk,"%d", 0);
      [xsText setStringValue:bonk];
      sprintf(bonk,"%d", 0);
      [ysText setStringValue:bonk];
    }
  }
  else {
    sprintf(bonk,"%s", [hypeGen getImagePath]);
    [imagePathText setStringValue:bonk];
  }

  return self;
}

- setMapPath: sender {

  char	bonk[1024];

  if ( [hypeGen getStatus] != IDLE ) {
    sprintf(bonk,"%s", [hypeGen getMapPath]);
    [mapPathText setStringValue:bonk];
  }
  else 
    [hypeGen setMapPath:sender];

  return self;
}

- setTablePath: sender {

  char	bonk[1024];

  if ( [hypeGen getStatus] != IDLE ) {
    sprintf(bonk,"%s", [hypeGen getTablePath]);
    [tablePathText setStringValue:bonk];
  }
  else
    [hypeGen setTablePath:sender];

  return self;
}

- openRequest:sender
{

  char	bonk[1024];

  if ( [hypeGen getStatus] != IDLE ) {
    NXRunAlertPanel("Iron Maiden","Well blow me down! Hyperupic is transducing!",
                        "okie",NULL,NULL,NULL);
    return nil;
  }

  if ([hypeGen openRequest:sender] && [hypeGen getGotImage] == YES) {
    sprintf(bonk,"%s", [hypeGen getImagePath]);
    [imagePathText setStringValue:bonk];
    sprintf(bonk,"%d", [hypeGen xval]);
    [xText setStringValue:bonk];
    sprintf(bonk,"%d", [hypeGen yval]);
    [yText setStringValue:bonk];
    sprintf(bonk,"%d", [hypeGen xendVal]);
    [xfText setStringValue:bonk];
    sprintf(bonk,"%d", [hypeGen yendVal]);
    [yfText setStringValue:bonk];
    sprintf(bonk,"%d", 0);
    [xsText setStringValue:bonk];
    sprintf(bonk,"%d", 0);
    [ysText setStringValue:bonk];
  }

  return self;
}

- openMapRequest:sender
{

  char	bonk[1024];

  if ( [hypeGen getStatus] != IDLE ) {
    NXRunAlertPanel("Don Ho","NO NO NO! Hyperupic is transducing!",
                        "dokie",NULL,NULL,NULL);
    return nil;
  }

  if ([hypeGen openMapRequest:sender] && [hypeGen getGotMapFile] == YES) {
    sprintf(bonk,"%s", [hypeGen getMapPath]);
    [mapPathText setStringValue:bonk];
  }

  return self;
}

- openTableRequest:sender
{

  char	bonk[1024];

  if ( [hypeGen getStatus] != IDLE ) {
    NXRunAlertPanel("Psychedelic Circus","Uh Oh! Hyperupic is transducing!",
                        "dokie",NULL,NULL,NULL);
    return nil;
  }

  if ([hypeGen openTableRequest:sender] && [hypeGen getGotTableFile] == YES) {
    sprintf(bonk,"%s", [hypeGen getTablePath]);
    [tablePathText setStringValue:bonk];
  }

  return self;
}


- saveRequest:sender
{
  [hypeGen saveRequest:sender];
  return self;
}

- saveInRequest:sender
{
  if ([hypeGen saveInRequest:sender])
    [mainWindow setTitle:[hypeGen getSoundPath]];

  return self;
}

- playSound: sender {

  [hypeGen playSound:sender];
  return self;
}

- stopPlaying: sender {

  SNDStop(1);
  return self;
}

- reverseMapping: sender {

  [hypeGen reverseMapping:sender];
  return self;
}

- adjustFrequency: sender {

  char	bonk[1024];

  sprintf(bonk,"%f", [hypeGen adjustFrequency]);
  [freqOffText setStringValue:bonk];
  return self;
}

- runGen: sender {

  int	grabber;

  if ([hypeGen getGotImage] == NO) {
    NXRunAlertPanel("Bruno Walter","Criminy! No image to transduce!",
                        "dokie",NULL,NULL,NULL);
    return nil;
  }

  if ([hypeGen getGotMapFile] == NO) {
    NXRunAlertPanel("Liberal, Kansas","Loser! Specify an amplitude map file!",
                        "okie",NULL,NULL,NULL);
    return nil;
  }

  if ([hypeGen getOscilTable] == YES) {
    if ([hypeGen getGotTableFile] == NO) {
      NXRunAlertPanel("Lead Pipe",
		    "Oh Ford! You need to specify an oscillator table!",
		    "dokie",NULL,NULL,NULL);
      return nil;
    }
  }

  // thread control

  if ([hypeGen getStatus] != IDLE) {
    grabber = NXRunAlertPanel("Snail Death",
		"Drunkard! You already have a process running!",
		"Snuff","Reprieve",NULL,NULL);
    if (grabber == NX_ALERTDEFAULT) {
      [self snuff:self];
      cthread_yield(); 			// a good time for a thread!
    } 
    else {
      if (grabber == NX_ALERTALTERNATE)
        return nil;
    }
  }


  if ( [hypeGen getSavedSoundFile] == NO ) {
    grabber = NXRunAlertPanel("Marlboro","Clumsy! Unsaved sound file!",
		    "Save","Forget","Cancel",NULL);

    if ( grabber == NX_ALERTDEFAULT )
      [self saveInRequest:self];
    else {
      if ( grabber == NX_ALERTOTHER )
	return nil;
    }
  }

  cthread_detach(cthread_fork( runFunc, (any_t) hypeGen));

  return self;
}

- selectGenHarmSeries: sender {

  [hypeGen selectGenHarmSeries:sender];
  return self;
}

- selectGenScale: sender {

  [hypeGen selectGenScale:sender];
  return self;
}

- selectXcoor: sender {

  [hypeGen selectXcoor:sender];
  return self;
}


- selectYcoor: sender {

  [hypeGen selectYcoor:sender];
  return self;
}

- selectDisplayAll: sender {

  [hypeGen selectDisplayAll:sender];
  return self;
}

- selectDisplayMinMax: sender {

  [hypeGen selectDisplayMinMax:sender];
  return self;
}


- selectGenNorm: sender {

  [hypeGen selectGenNorm:sender];
  return self;
}

- selectGenRetro: sender {

  [hypeGen selectGenRetro:sender];
  return self;
}

- selectGenRotNorm: sender {

  [hypeGen selectGenRotNorm:sender];
  return self;
}

- selectGenRotRetro: sender {

  [hypeGen selectGenRotRetro:sender];
  return self;
}

- selectGenNormInv: sender {

  [hypeGen selectGenNormInv:sender];
  return self;
}

- selectGenRetroInv: sender {

  [hypeGen selectGenRetroInv:sender];
  return self;
}

- selectGenRotNormInv: sender {

  [hypeGen selectGenRotNormInv:sender];
  return self;
}

- selectGenRotRetroInv: sender {

  [hypeGen selectGenRotRetroInv:sender];
  return self;
}

- selectMapR: sender {

  [hypeGen selectMapR:sender];
  return self;
}

- selectMapG: sender {

  [hypeGen selectMapG:sender];
  return self;
}

- selectMapB: sender {

  [hypeGen selectMapB:sender];
  return self;
}

- selectMapRG: sender {

  [hypeGen selectMapRG:sender];
  return self;
}

- selectMapRB: sender {

  [hypeGen selectMapRB:sender];
  return self;
}

- selectMapGB: sender {

  [hypeGen selectMapGB:sender];
  return self;
}

- selectMapRGB: sender {

  [hypeGen selectMapRGB:sender];
  return self;
}

- selectOscCos: sender {

  [hypeGen selectOscCos:sender];
  return self;
}

- selectOscComplex: sender {

  [harmWindow orderBack:sender];
  [hypeGen selectOscComplex:sender];
  return self;
}

- selectOscTable: sender {

  if ( [hypeGen getGotTableFile] == NO ) {
    if (![self openTableRequest:sender]) {
      return nil;
    }
  }

  if (![hypeGen selectOscTable:sender])
    return nil;


//  [oscilRadio selectCellAt:0 :0];

  return self;
}

@end
