#import <libc.h>
#import <appkit/Application.h>
#import <appkit/TextField.h>
#import <soundkit/Sound.h>
#import <sound/soundstruct.h>
#import "Transport.h"
#import "DACPlayer.h"
#import "errors.h"
#import <math.h>
int done = 0;
int inskip = 0;
void UpdateStatus (DPSTimedEntry te, double timeNow, void *data)
{
  [(id)data updateStatus];
}


@implementation Transport:Object

+ new
{
  self = [super new];
  
  /* Create a timed entry to update the status window every second. */
  statusTE = DPSAddTimedEntry(1.0, &UpdateStatus, self, NX_BASETHRESHOLD);

  dacPlayer = [DACPlayer new];
  [dacPlayer setDelegate :self];

  return self;
}

- stop:sender;
{
  [dacPlayer stop];
  return self;
}

- pause:sender
{
  [dacPlayer pause];
  return self;
}

- play:(id)mySound
{
  aSound = mySound;
  done = inskip = 0;
  savesoundpointer = soundpointer = (short *)[aSound data];
  nsoundbytes = [aSound sampleCount] * BYTES_PER_16BIT;
  [dacPlayer setSamplingRate:(double)[aSound samplingRate]];
  [dacPlayer run];
  return self;
}

- wait
{
  [dacPlayer wait];
  [dacPlayer stop];
  return self;
}

/**
 ** Internal methods.
 **/
- updateStatus
{
  return self;
}

/**
 ** Delegate methods called from the DACPlayer object
 **/

- willPlay :player
/*
 * Called when the Player is about to start playing data.
 */
{
  id srateCell;
  int region_size, region_count;
  sampleValue = 0;
   /* set the current region size and count */
  region_size = 4 * vm_page_size;
  nbuffers = region_count = 10;
  [dacPlayer setupRegions:region_size:region_count];

   return self;
}

- didPlay :player;
/*
 * Called when the Player stops.
 */
{
   return self;
}

- playData :player :(char *)region :(int)nbytes
/*
 * Called whenever the Player wants more data. 
 */
{
   int i, nsamples = nbytes/BYTES_PER_16BIT;
   short *dstSamples = (short *)region;
   if([aSound channelCount] == 2) {
   	if((soundpointer - savesoundpointer) < nsoundbytes) {
   		//bcopy(soundpointer,region,nbytes);
		fragSounds(aSound,region,inskip,nsamples);
		inskip += nsamples;
   		soundpointer += nbytes/BYTES_PER_16BIT;
		}
    	else {
    		if(nbuffers-- == 2)
		done = 1;  /* count down DAC buffers */
		}
	}
    else {
	if((soundpointer - savesoundpointer) < nsoundbytes) {
   		//bcopy(soundpointer,region,nbytes);
		fragSounds(aSound,region,inskip,nsamples);
		inskip += nsamples/2;
   		soundpointer += (nbytes/BYTES_PER_16BIT);
		}
    	else {
    		if(nbuffers-- == 2)
		done = 1;  /* count down DAC buffers */
		}
	}
    return self;
}

@end

