#include "PresetFrameIO.hpp"
#include "wipemalloc.h"
#include <math.h>
#include <cassert>
#include <iostream>
#include <cmath>
#include "Renderer/BeatDetect.hpp"


PresetInputs::PresetInputs() : PipelineContext()
{
}

void
PresetInputs::update(const BeatDetect & music, const PipelineContext & context)
{

  // Reflect new values form the beat detection unit
  this->bass      = music.bass;
  this->mid       = music.mid;
  this->treb      = music.treb;
  this->bass_att  = music.bass_att;
  this->mid_att   = music.mid_att;
  this->treb_att  = music.treb_att;

  // Reflect new values from the pipeline context
  this->fps       = context.fps;
  this->time      = context.time;

  this->frame     = context.frame;
  this->progress  = context.progress;
}

void
PresetInputs::Initialize ( int gx, int gy )
{
  int x, y;

  this->gx =gx;
  this->gy= gy;


  /// @bug no clue if this block belongs here
  // ***
  progress = 0;
  frame = 1;

  x_per_pixel = 0;
  y_per_pixel = 0;
  rad_per_pixel = 0;
  ang_per_pixel = 0;
  // ***

  this->x_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->x_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->y_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x <gx; x++ )
  {
    this->y_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->rad_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->rad_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->theta_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x <gx; x++ )
  {
    this->theta_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }

  this->origtheta= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->origtheta[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->origrad= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->origrad[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->origx= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->origx[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->origy= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->origy[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }

  for ( x=0;x<gx;x++ )
  {
    for ( y=0;y<gy;y++ )
    {
      this->origx[x][y]=x/ ( float ) ( gx-1 );
      this->origy[x][y]=- ( ( y/ ( float ) ( gy-1 ) )-1 );
      this->origrad[x][y]=hypot ( ( this->origx[x][y]-.5 ) *2, ( this->origy[x][y]-.5 ) *2 ) * .7071067;
      this->origtheta[x][y]=atan2 ( ( ( this->origy[x][y]-.5 ) *2 ), ( ( this->origx[x][y]-.5 ) *2 ) );
    }
  }
}

PresetOutputs::PresetOutputs() : Pipeline()
{}

PresetOutputs::~PresetOutputs()
{
  assert(this->gx > 0);

  for ( int x = 0; x < this->gx; x++ )
  {
    free (this->sx_mesh[x]);
    free (this->sy_mesh[x]);
    free (this->dy_mesh[x]);
    free (this->dx_mesh[x]);
    free (this->cy_mesh[x]);
    free (this->cx_mesh[x]);

    free (this->warp_mesh[x]);
    free (this->zoom_mesh[x]);
    free (this->zoomexp_mesh[x]);
    free (this->rot_mesh[x]);
    free (this->orig_x[x]);
    free (this->orig_y[x]);
    free (this->rad_mesh[x]);
  }

  free (this->rad_mesh);
  free (this->sx_mesh);
  free (this->sy_mesh);
  free (this->dy_mesh);
  free (this->dx_mesh);
  free (this->cy_mesh);
  free (this->cx_mesh);
  free (this->warp_mesh);
  free (this->zoom_mesh);
  free (this->zoomexp_mesh);
  free (this->rot_mesh);
  free (this->orig_x);
  free (this->orig_y);

}

void
PresetOutputs::Render(const BeatDetect &music, const PipelineContext &context)
{
  PerPixelMath(context);

  drawables.clear();

  drawables.push_back(&mv);

  for (PresetOutputs::cshape_container::iterator pos = customShapes.begin();
       pos != customShapes.end();
       ++pos)
  {
    if( (*pos)->enabled==1) drawables.push_back((*pos));
  }

  for (PresetOutputs::cwave_container::iterator pos = customWaves.begin();
       pos != customWaves.end();
       ++pos)
  {
    if( (*pos)->enabled==1) drawables.push_back((*pos));
  }

  drawables.push_back(&wave);
  if(bDarkenCenter==1) drawables.push_back(&darkenCenter);
  drawables.push_back(&border);

  compositeDrawables.clear();
  compositeDrawables.push_back(&videoEcho);

  if (bBrighten==1)
    compositeDrawables.push_back(&brighten);

  if (bDarken==1)
    compositeDrawables.push_back(&darken);

  if (bSolarize==1)
    compositeDrawables.push_back(&solarize);

  if (bInvert==1)
    compositeDrawables.push_back(&invert);
}


void
PresetOutputs::PerPixelMath(const PipelineContext &context)
{
  int   x, y;
  float fZoom2, fZoom2Inv;

  for (x = 0; x < gx; x++)
  {
    for (y = 0; y < gy; y++)
    {
      fZoom2 = std::pow(this->zoom_mesh[x][y], std::pow(this->zoomexp_mesh[x][y],
                                                        rad_mesh[x][y] * 2.0f - 1.0f));
      fZoom2Inv = 1.0f / fZoom2;
      this->x_mesh[x][y] = this->orig_x[x][y] * 0.5f * fZoom2Inv + 0.5f;
      this->y_mesh[x][y] = this->orig_y[x][y] * 0.5f * fZoom2Inv + 0.5f;
    }
  }

  for (x = 0; x < gx; x++)
  {
    for (y = 0; y < gy; y++)
    {
      this->x_mesh[x][y] = (this->x_mesh[x][y] - this->cx_mesh[x][y])
                         / this->sx_mesh[x][y] + this->cx_mesh[x][y];
    }
  }

  for (x = 0; x < gx; x++)
  {
    for (y = 0; y < gy; y++)
    {
      this->y_mesh[x][y] = (this->y_mesh[x][y] - this->cy_mesh[x][y])
                         / this->sy_mesh[x][y] + this->cy_mesh[x][y];
    }
  }

  float fWarpTime = context.time * this->fWarpAnimSpeed;
  float fWarpScaleInv = 1.0f / this->fWarpScale;
  float f[4];
  f[0] = 11.68f + 4.0f * cosf(fWarpTime * 1.413f + 10);
  f[1] = 8.77f + 3.0f * cosf(fWarpTime * 1.113f + 7);
  f[2] = 10.54f + 3.0f * cosf(fWarpTime * 1.233f + 3);
  f[3] = 11.49f + 4.0f * cosf(fWarpTime * 0.933f + 5);

  for (x = 0; x < gx; x++)
  {
    for (y = 0; y < gy; y++)
    {
      this->x_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * sinf(fWarpTime * 0.333f
                          + fWarpScaleInv * (this->orig_x[x][y] * f[0] - this->orig_y[x][y] * f[3]));
      this->y_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * cosf(fWarpTime * 0.375f
                          - fWarpScaleInv * (this->orig_x[x][y] * f[2] + this->orig_y[x][y] * f[1]));
      this->x_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * cosf(fWarpTime * 0.753f
                          - fWarpScaleInv * (this->orig_x[x][y] * f[1] - this->orig_y[x][y] * f[2]));
      this->y_mesh[x][y] += this->warp_mesh[x][y] * 0.0035f * sinf(fWarpTime * 0.825f
                          + fWarpScaleInv * (this->orig_x[x][y] * f[0] + this->orig_y[x][y] * f[3]));
    }
  }
  for (x = 0; x < gx; x++)
  {
    for (y = 0; y < gy; y++)
    {
      float u2 = this->x_mesh[x][y] - this->cx_mesh[x][y];
      float v2 = this->y_mesh[x][y] - this->cy_mesh[x][y];

      float cos_rot = cosf(this->rot_mesh[x][y]);
      float sin_rot = sinf(this->rot_mesh[x][y]);

      this->x_mesh[x][y] = u2 * cos_rot - v2 * sin_rot + this->cx_mesh[x][y];
      this->y_mesh[x][y] = u2 * sin_rot + v2 * cos_rot + this->cy_mesh[x][y];
    }
  }

  for (x = 0; x < gx; x++)
    for (y = 0; y < gy; y++)
      this->x_mesh[x][y] -= this->dx_mesh[x][y];

  for (x = 0; x < gx; x++)
    for (y = 0; y < gy; y++)
      this->y_mesh[x][y] -= this->dy_mesh[x][y];
}


void
PresetOutputs::Initialize ( int gx, int gy )
{
  assert(gx > 0);
  this->gx = gx;
  this->gy= gy;

  staticPerPixel = true;
  setStaticPerPixel(gx,gy);

  assert(this->gx > 0);
  int x;
  this->x_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->x_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->y_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->y_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->sx_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->sx_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->sy_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->sy_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->dx_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->dx_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->dy_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->dy_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->cx_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->cx_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->cy_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->cy_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->zoom_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->zoom_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->zoomexp_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->zoomexp_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->rot_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->rot_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }

  this->warp_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->warp_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->rad_mesh= ( float ** ) wipemalloc ( gx * sizeof ( float * ) );
  for ( x = 0; x < gx; x++ )
  {
    this->rad_mesh[x] = ( float * ) wipemalloc ( gy * sizeof ( float ) );
  }
  this->orig_x = (float **) wipemalloc(gx * sizeof(float *));
  for (x = 0; x < gx; x++)
  {
    this->orig_x[x] = (float *) wipemalloc(gy * sizeof(float));
  }
  this->orig_y = (float **) wipemalloc(gx * sizeof(float *));
  for (x = 0; x < gx; x++)
  {
    this->orig_y[x] = (float *) wipemalloc(gy * sizeof(float));
  }

  //initialize reference grid values
  for (x = 0; x < gx; x++)
  {
    for (int y = 0; y < gy; y++)
    {
      float origx = x / (float) (gx - 1);
      float origy = -((y / (float) (gy - 1)) - 1);

      rad_mesh[x][y]=hypot ( ( origx-.5 ) *2, ( origy-.5 ) *2 ) * .7071067;
      orig_x[x][y] = (origx - .5) * 2;
      orig_y[x][y] = (origy - .5) * 2;
    }
  }
}

PresetInputs::~PresetInputs()
{
  for ( int x = 0; x < this->gx; x++ )
  {
    free ( this->origtheta[x] );
    free ( this->origrad[x] );
    free ( this->origx[x] );
    free ( this->origy[x] );

    free ( this->x_mesh[x] );
    free ( this->y_mesh[x] );
    free ( this->rad_mesh[x] );
    free ( this->theta_mesh[x] );
  }


  free ( this->origx );
  free ( this->origy );
  free ( this->origrad );
  free ( this->origtheta );

  free ( this->x_mesh );
  free ( this->y_mesh );
  free ( this->rad_mesh );
  free ( this->theta_mesh );

  this->origx = NULL;
  this->origy = NULL;
  this->origtheta = NULL;
  this->origrad = NULL;

  this->x_mesh = NULL;
  this->y_mesh = NULL;
  this->rad_mesh = NULL;
  this->theta_mesh = NULL;
}


void PresetInputs::resetMesh()
{
  int x,y;

  assert ( x_mesh );
  assert ( y_mesh );
  assert ( rad_mesh );
  assert ( theta_mesh );

  for ( x=0;x<this->gx;x++ )
  {
    for ( y=0;y<this->gy;y++ )
    {
      x_mesh[x][y]=this->origx[x][y];
      y_mesh[x][y]=this->origy[x][y];
      rad_mesh[x][y]=this->origrad[x][y];
      theta_mesh[x][y]=this->origtheta[x][y];
    }
  }
}


#ifdef USE_MERGE_PRESET_CODE
void
PresetMerger::MergePresets(PresetOutputs & A, PresetOutputs & B, double ratio, int gx, int gy)
{

  double invratio = 1.0 - ratio;
  //Merge Simple Waveforms
  //
  // All the mess is because of Waveform 7, which is two lines.
  //


  //Merge Custom Shapes and Custom Waves

  for (PresetOutputs::cshape_container::iterator pos = A.customShapes.begin();
       pos != A.customShapes.end();
       ++pos)
  {
    (*pos)->a *= invratio;
    (*pos)->a2 *= invratio;
    (*pos)->border_a *= invratio;
  }

  for (PresetOutputs::cshape_container::iterator pos = B.customShapes.begin();
       pos != B.customShapes.end();
       ++pos)
  {
    (*pos)->a *= ratio;
    (*pos)->a2 *= ratio;
    (*pos)->border_a *= ratio;

    A.customShapes.push_back(*pos);
  }

  for (PresetOutputs::cwave_container::iterator pos = A.customWaves.begin();
       pos != A.customWaves.end();
       ++pos)
  {
    (*pos)->a *= invratio;
    for (int x=0; x <   (*pos)->samples; x++)
    {
      (*pos)->a_mesh[x]= (*pos)->a_mesh[x]*invratio;
    }
  }

  for (PresetOutputs::cwave_container::iterator pos = B.customWaves.begin();
       pos != B.customWaves.end();
       ++pos)
  {
    (*pos)->a *= ratio;
    for (int x=0; x < (*pos)->samples; x++)
    {
      (*pos)->a_mesh[x]= (*pos)->a_mesh[x]*ratio;
    }
    A.customWaves.push_back(*pos);
  }


  //Interpolate Per-Pixel mesh

  for (int x=0;x<gx;x++)
  {
    for(int y=0;y<gy;y++)
    {
      A.x_mesh[x][y]  = A.x_mesh[x][y]* invratio + B.x_mesh[x][y]*ratio;
    }
  }
  for (int x=0;x<gx;x++)
  {
    for(int y=0;y<gy;y++)
    {
      A.y_mesh[x][y]  = A.y_mesh[x][y]* invratio + B.y_mesh[x][y]*ratio;
    }
  }



  //Interpolate PerFrame floats

  A.screenDecay = A.screenDecay * invratio + B.screenDecay * ratio;

  A.wave.r = A.wave.r* invratio + B.wave.r*ratio;
  A.wave.g = A.wave.g* invratio + B.wave.g*ratio;
  A.wave.b = A.wave.b* invratio + B.wave.b*ratio;
  A.wave.a = A.wave.a* invratio + B.wave.a*ratio;
  A.wave.x = A.wave.x* invratio + B.wave.x*ratio;
  A.wave.y = A.wave.y* invratio + B.wave.y*ratio;
  A.wave.mystery = A.wave.mystery* invratio + B.wave.mystery*ratio;

  A.border.outer_size = A.border.outer_size* invratio + B.border.outer_size*ratio;
  A.border.outer_r = A.border.outer_r* invratio + B.border.outer_r*ratio;
  A.border.outer_g = A.border.outer_g* invratio + B.border.outer_g*ratio;
  A.border.outer_b = A.border.outer_b* invratio + B.border.outer_b*ratio;
  A.border.outer_a = A.border.outer_a* invratio + B.border.outer_a*ratio;

  A.border.inner_size = A.border.inner_size* invratio + B.border.inner_size*ratio;
  A.border.inner_r = A.border.inner_r* invratio + B.border.inner_r*ratio;
  A.border.inner_g = A.border.inner_g* invratio + B.border.inner_g*ratio;
  A.border.inner_b = A.border.inner_b* invratio + B.border.inner_b*ratio;
  A.border.inner_a = A.border.inner_a* invratio + B.border.inner_a*ratio;

  A.mv.a  = A.mv.a* invratio + B.mv.a*ratio;
  A.mv.r  = A.mv.r* invratio + B.mv.r*ratio;
  A.mv.g  = A.mv.g* invratio + B.mv.g*ratio;
  A.mv.b  = A.mv.b* invratio + B.mv.b*ratio;
  A.mv.length = A.mv.length* invratio + B.mv.length*ratio;
  A.mv.x_num = A.mv.x_num* invratio + B.mv.x_num*ratio;
  A.mv.y_num = A.mv.y_num* invratio + B.mv.y_num*ratio;
  A.mv.y_offset = A.mv.y_offset* invratio + B.mv.y_offset*ratio;
  A.mv.x_offset = A.mv.x_offset* invratio + B.mv.x_offset*ratio;


  A.fRating = A.fRating* invratio + B.fRating*ratio;
  A.fGammaAdj = A.fGammaAdj* invratio + B.fGammaAdj*ratio;
  A.videoEcho.zoom = A.videoEcho.zoom* invratio + B.videoEcho.zoom*ratio;
  A.videoEcho.a = A.videoEcho.a* invratio + B.videoEcho.a*ratio;


  A.fWarpAnimSpeed = A.fWarpAnimSpeed* invratio + B.fWarpAnimSpeed*ratio;
  A.fWarpScale = A.fWarpScale* invratio + B.fWarpScale*ratio;
  A.fShader = A.fShader* invratio + B.fShader*ratio;

  //Switch bools and discrete values halfway.  Maybe we should do some interesting stuff here.

  if (ratio > 0.5)
  {
    A.videoEcho.orientation = B.videoEcho.orientation;
    A.textureWrap = B.textureWrap;
    A.bDarkenCenter = B.bDarkenCenter;
    A.bRedBlueStereo = B.bRedBlueStereo;
    A.bBrighten = B.bBrighten;
    A.bDarken = B.bDarken;
    A.bSolarize = B.bSolarize;
    A.bInvert = B.bInvert;
    A.bMotionVectorsOn = B.bMotionVectorsOn;
  }

  return;
}
#endif
