#include "SM_CommonFXPCH.h"
#include "SM_DemoEffect.h"
#include "SM_Engine3DPch.h"
#include "SM_Sound.h"
#include "FXMusic.h"


static  SM_DemoEffect::Helper  LoadHelp[] =
{
  {"", "Load the sound syncer"},
};

static SM_DemoEffect::Helper CommandsHelp[] =
{
  {"SETINPUT namemusicfx", "Pone como stream actual el efecto de musica que pases como parametro"},    
  {"BEATTHRESHOLD Peak Amplitude", "Peak (0 - 1) frecuencia maxima que se mira para el beat\nAmplitude (0 - 1) amplitud minima para beat"},
  {"DRAW ON", "DRAW GRAPH"},
  {"DRAW OFF", "DONT DRAW GRAPH"},
};




class SoundSyncerFX : public SM_DemoEffect
{
public:              
  SoundSyncerFX(char const* pcName) : SM_DemoEffect(pcName)
  {
    m_bDraw = false;
  }

  virtual          ~SoundSyncerFX()
  {
  }

  int LoadArgumentsHelp     (Helper*& pHelpers)
  {
    pHelpers = LoadHelp;
    return (sizeof(LoadHelp)/sizeof(Helper));
  }

  int CommandArgumentsHelp  (Helper*& pHelpers)
  {
    pHelpers = CommandsHelp;
    return (sizeof(CommandsHelp)/sizeof(Helper));
  }


  int Reset()
  {
    m_bDraw = false;
    return 0;
  }

  int      Init(const char* pcCommand)
  {
    char* pcCopy =0;
    char* pcToken;
    int   iReturn=-1;
    
    pcCopy=new char[strlen(pcCommand)+1];
    strcpy(pcCopy, pcCommand);

    pcToken=strtok(pcCopy, " \t");

    if (pcToken)
    if (strcmp(pcToken, "FILL THIS UP")==0)
    {
    }

    iReturn  = 0;
    
//FAILED:
    if (pcCopy) { delete[] pcCopy; pcCopy=0; }

    return iReturn;        
  }

  int      Shutdown()
  {
    return (0);
  }

  int      Start(float fTime)
  {
    return (0);
  }

  int      Stop()
  {
    return (0);
  }

  
  int      Run(float fTime)
  {
    if (!m_bDraw)
    {
      return 1;
    }

    FVF_PosRhwDiffuseTex1 pVertices[SM_SOUND_DATASAMPLES];

    ShaderManager::GetShader("NULL")->SetShaderState(0);
    SM_D3d::Device()->SetVertexShader(FVF_POSRHWDIFFUSETEX1);

    float* pfData = 0;
    unsigned i;

    float fWidth =Coordinates::PhysicalWidth();
    float fHeight=Coordinates::PhysicalHeight();
  
    if (SM_Sound::GetFFT(fTime, pfData))
    {
      for (i = 0 ; i < SM_SOUND_DATASAMPLES ; i++)
      {
        pVertices[i].x=fWidth*2*i*(1.0f/SM_SOUND_DATASAMPLES); pVertices[i].y=fHeight-float(pfData[i])*fHeight*0.5f; pVertices[i].z=0.0f; pVertices[i].u=0.0f; pVertices[i].v=0.0f; pVertices[i].oow=1.0f; pVertices[i].diffuse=0xFFFFFFFF;
      }

      SM_D3d::Device()->DrawPrimitiveUP(
          D3DPT_LINESTRIP, 
          SM_SOUND_DATASAMPLES-1,
          pVertices,
          sizeof(FVF_PosRhwDiffuseTex1));
    }

    float fPeakFrequency;
    float fMinAmplitude;
    SM_Sound::GetBeatThreshold (&fPeakFrequency, &fMinAmplitude);

    unsigned uColor;
    if (SM_Sound::IsBeat(fTime))
    {
      uColor = 0xFF00FF00;
    }
    else
    {
      uColor = 0xFFFF0000;
    }
    

    pVertices[0].x=fWidth*fPeakFrequency; pVertices[0].y=fHeight; pVertices[0].z=0.0f; pVertices[0].u=0.0f; pVertices[0].v=0.0f; pVertices[0].oow=1.0f; pVertices[0].diffuse=uColor;
    pVertices[1].x=fWidth*fPeakFrequency; pVertices[1].y=fHeight-fMinAmplitude*fHeight*0.5f; pVertices[1].z=0.0f; pVertices[1].u=0.0f; pVertices[1].v=0.0f; pVertices[1].oow=1.0f; pVertices[1].diffuse=uColor;

    SM_D3d::Device()->DrawPrimitiveUP(
          D3DPT_LINESTRIP, 
          1,
          pVertices,
          sizeof(FVF_PosRhwDiffuseTex1));

    pVertices[0].x=0.0f                 ; pVertices[0].y=fHeight-fMinAmplitude*fHeight*0.5f; pVertices[0].z=0.0f; pVertices[0].u=0.0f; pVertices[0].v=0.0f; pVertices[0].oow=1.0f; pVertices[0].diffuse=uColor;
    pVertices[1].x=fWidth*fPeakFrequency; pVertices[1].y=fHeight-fMinAmplitude*fHeight*0.5f; pVertices[1].z=0.0f; pVertices[1].u=0.0f; pVertices[1].v=0.0f; pVertices[1].oow=1.0f; pVertices[1].diffuse=uColor;

    SM_D3d::Device()->DrawPrimitiveUP(
          D3DPT_LINESTRIP, 
          1,
          pVertices,
          sizeof(FVF_PosRhwDiffuseTex1));
    
    return 1;
  }

  int      Command           (float fTime, const char* pcCommand)
  {
    SM_DemoEffect::Command(fTime, pcCommand);
    char* pcCopy =0;
    char* pcToken;
    int   iReturn=-1;
    
    pcCopy=new char[strlen(pcCommand)+1];
    strcpy(pcCopy, pcCommand);

    pcToken=strtok(pcCopy, " \t");
    
    if (pcToken)
    if (strcmp(pcToken, "SETINPUT")==0)
    {
      pcToken=strtok(0, " \t");
      if (pcToken)
      {
        strupr(pcToken);
        SM_DemoEffect* pEffect = GetEffect(pcToken);
        if (pEffect)
        {
          MusicFX* pFX = (MusicFX*) pEffect;

          SM_Sound::SetStream(pFX->GetStream());
        }
      }
    }
    else if (strcmp(pcToken, "BEATTHRESHOLD")==0)
    {
      pcToken=strtok(0, " \t");
      if (pcToken)
      {
        float fPeak = atof(pcToken);
        pcToken=strtok(0, " \t");
        if (pcToken)
        {
          float fMinAmplitude = atof(pcToken);

          SM_Sound::SetBeatThreshold (fPeak, fMinAmplitude);
        }
      }      
    }
    else if (strcmp(pcToken, "DRAW")==0)
    {
      if (strtok(0, " \t"))
      {
        m_bDraw = true;
      }
      else
      {
        m_bDraw = false;
      }
    }

    iReturn  = 0;
    
    if (pcCopy) { delete[] pcCopy; pcCopy=0; }
    return iReturn;
  }  

  bool m_bDraw;
};

DEFINE_EFFECT(SoundSyncerFX)

SoundSyncerFX Syncer("SOUNDSYNCER");



