/*
  splay player plugin
  Copyright (C) 1999  Martin Vogt

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU Library General Public License as published by
  the Free Software Foundation.

  For more information look at the file COPYRIGHT in this package

 */


#include "splayPlugin.h"
#include "mpegsound.h"



SplayPlugin::SplayPlugin() {
  pow(6.0,3.0);            // fixes bug in __math.h
  doFloat = false;
  downSampleFlag=false;
  monoFlag=false;
  lnoLength=false;
  mpegAudioStream=NULL;
  currentHeader=NULL;
}


SplayPlugin::~SplayPlugin() {
}


// here we can config our decoder with special flags
void SplayPlugin::config(const char* key,const char* value,void* user_data) {
  if (strcmp(key,"dofloat")==0) {
    doFloat=true;
  }
  if (strcmp(key,"-m")==0) {
    monoFlag=true;
  }
  if (strcmp(key,"-2")==0) {
    downSampleFlag=true;
  }
  if (strcmp(key,"-c")==0) {
    lnoLength=true;
  }

  if (strcmp(key,"decode")==0) {
    if (strcmp(value,"true")==0) {
      lDecode=true;
    } else {
      lDecode=false;
    }
  }    
  DecoderPlugin::config(key,value,user_data);
}



void SplayPlugin::decoder_loop() {

  if (input == NULL) {
    cout << "SplayPlugin::decoder_loop input is NULL"<<endl;
    exit(0);
  }
  if (output == NULL) {
    cout << "SplayPlugin::decoder_loop output is NULL"<<endl;
    exit(0);
  }
  // init decoder
  output->audioInit();

  currentHeader=new MpegAudioHeader();
  mpegAudioStream=new MpegAudioStream(input);
  Mpegtoraw* server=NULL;
  int len=0;
  int resyncCounter=0;
  // start decoding
  

  while(runCheck()) {
    
    switch(streamState) {
    case _STREAM_STATE_FIRST_INIT :
      if (mpegAudioStream->firstInitialize(currentHeader)==false) {
      } else {
	server = new Mpegtoraw(mpegAudioStream,currentHeader,output,doFloat);
	server->setdownfrequency(downSampleFlag);
	server->setforcetomono(monoFlag);
	output->audioSetup(currentHeader->getFrequencyHz()>>downSampleFlag,
			   currentHeader->getInputstereo()>>monoFlag,
			   0,0,doFloat?(sizeof(float)*8):16);
	output->audioOpen();
	setStreamState(_STREAM_STATE_PLAY);
	if (lnoLength==false) {
	  len=mpegAudioStream->getLength();
	  pluginInfo->setLength(len);
	  output->writeInfo(pluginInfo);
	}
	server->decode(currentHeader);
	lhasLength=true;
      }
      break;
    case _STREAM_STATE_INIT :
      if (mpegAudioStream->nextHeader(currentHeader)==false) {
	continue;
      }
      resyncCounter++;
      // decode but no output
      server->decode(currentHeader);
      // here we are not writing to output
      if (resyncCounter > 5) {
	setStreamState(_STREAM_STATE_PLAY);
	resyncCounter=0;
      }
      break;
    case _STREAM_STATE_PLAY :
      // decode 
      if (mpegAudioStream->nextHeader(currentHeader)==false) {
	setStreamState(_STREAM_STATE_INIT);
	continue;
      }
      server->decode(currentHeader);

      // after decoder we write to output
      server->flushrawdata();
     
      break;
    case _STREAM_STATE_WAIT_FOR_END:
      // exit while loop
      lDecoderLoop=false;
      break;
    default:
      cout << "unknown stream state:"<<streamState<<endl;
    }
  }

  // remove decoder
  if (server != NULL) {
    server->clearbuffer();
    delete server;
  }

  output->audioFlush();
  delete mpegAudioStream;
  delete currentHeader;
  mpegAudioStream=NULL;
  currentHeader=NULL;
}

// splay can seek in streams
int SplayPlugin::seek_impl(int second) {


  if (mpegAudioStream != NULL) {
    int pos=mpegAudioStream->getSeekPosition(second);
    input->seek(pos);
    setStreamState(_STREAM_STATE_INIT);
  } else {
    cout << "cannot seek, plugin not initialized"<<endl;
  }
  return true;
}


int SplayPlugin::getTotalLength() {
  shutdownLock();
  int back=0;
  if (mpegAudioStream != NULL) {
    back=mpegAudioStream->getLength();
  } else {
    cout << "cannot report total length, plugin not initialized"<<endl;
  }
  shutdownUnlock();
  return back;
}





