/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You  have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sstream>

#include "Common.hpp"
#include "fatal.h"

#include "CustomWave.hpp"
#include "Eval.hpp"
#include "Expr.hpp"
#include "InitCond.hpp"
#include "Param.hpp"
#include "PerFrameEqn.hpp"
#include "PerPointEqn.hpp"
#include "Preset.hpp"
#include <map>
#include "ParamUtils.hpp"
#include "InitCondUtils.hpp"
#include "wipemalloc.h"

#define MAX_SAMPLE_SIZE 4096


CustomWave::CustomWave(int _id)
  : Waveform(512),
    id(_id),
    per_frame_count(0),
    r(0),
    g(0),
    b(0),
    a(0)
{
  Param * param;

  /// @bug deprecate the use of wipemalloc
  this->r_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->g_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->b_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->a_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->x_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->y_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->value1 = (float*) wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->value2 = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));
  this->sample_mesh = (float*)wipemalloc(MAX_SAMPLE_SIZE*sizeof(float));

  /* Start: Load custom wave parameters */

  if ((param = Param::new_param_float("r", P_FLAG_NONE | P_FLAG_PER_POINT, &this->r, this->r_mesh, 1.0, 0.0, .5)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &param_tree) < 0)
  {
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_float("g", P_FLAG_NONE | P_FLAG_PER_POINT, &this->g,  this->g_mesh, 1.0, 0.0, .5)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_float("b", P_FLAG_NONE | P_FLAG_PER_POINT, &this->b,  this->b_mesh, 1.0, 0.0, .5)) == NULL)
  {
    ;
    /// @bug make exception
    abort();

  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_float("a", P_FLAG_NONE | P_FLAG_PER_POINT, &this->a,  this->a_mesh, 1.0, 0.0, .5)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_float("x", P_FLAG_NONE | P_FLAG_PER_POINT, &this->x,  this->x_mesh, 1.0, 0.0, .5)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_float("y", P_FLAG_NONE | P_FLAG_PER_POINT, &this->y,  this->y_mesh, 1.0, 0.0, .5)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_bool("enabled", P_FLAG_NONE, &this->enabled, 1, 0, 0)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_int("sep", P_FLAG_NONE, &this->sep, 100, -100, 0)) == NULL)
  {
    ;
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_bool("bspectrum", P_FLAG_NONE, &this->spectrum, 1, 0, 0)) == NULL)
  {
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_bool("bdrawthick", P_FLAG_NONE, &this->thick, 1, 0, 0)) == NULL)
  {
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    /// @bug make exception
    abort();
  }

  if ((param = Param::new_param_bool("busedots", P_FLAG_NONE, &this->dots, 1, 0, 0)) == NULL)
  {
    /// @bug make exception
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_bool("badditive", P_FLAG_NONE, &this->additive, 1, 0, 0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_int("samples", P_FLAG_NONE, &this->samples, 2048, 1, 512)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_float("sample", P_FLAG_READONLY | P_FLAG_NONE | P_FLAG_ALWAYS_MATRIX | P_FLAG_PER_POINT,
                      &this->sample, this->sample_mesh, 1.0, 0.0, 0.0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("value1", P_FLAG_READONLY | P_FLAG_NONE | P_FLAG_ALWAYS_MATRIX | P_FLAG_PER_POINT, &this->v1, this->value1, 1.0, -1.0, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("value2", P_FLAG_READONLY | P_FLAG_NONE | P_FLAG_ALWAYS_MATRIX | P_FLAG_PER_POINT, &this->v2, this->value2, 1.0, -1.0, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_float("smoothing", P_FLAG_NONE, &this->smoothing, NULL, 1.0, 0.0, 0.0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_float("scaling", P_FLAG_NONE, &this->scaling, NULL, MAX_DOUBLE_SIZE, 0.0, 1.0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_float("t1", P_FLAG_PER_POINT | P_FLAG_TVAR, &this->t1, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_float("t2",  P_FLAG_PER_POINT |P_FLAG_TVAR, &this->t2, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("t3",  P_FLAG_PER_POINT |P_FLAG_TVAR, &this->t3, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("t4",  P_FLAG_PER_POINT |P_FLAG_TVAR, &this->t4, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("t5", P_FLAG_TVAR, &this->t5, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("t6", P_FLAG_TVAR | P_FLAG_PER_POINT, &this->t6, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    abort();
  }

  if ((param = Param::new_param_float("t7", P_FLAG_TVAR | P_FLAG_PER_POINT, &this->t7, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  if ((param = Param::new_param_float("t8", P_FLAG_TVAR | P_FLAG_PER_POINT, &this->t8, NULL, MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0)) == NULL)
  {
    ;
    abort();
  }

  if (ParamUtils::insert(param, &this->param_tree) < 0)
  {
    ;
    abort();
  }

  for (unsigned int i = 1;  i <= NUM_Q_VARIABLES;  i++) {
    std::ostringstream os;

    os << "q" << i;
    param = Param::new_param_float ( os.str().c_str(), P_FLAG_QVAR, &this->q[i], NULL,
                                     MAX_DOUBLE_SIZE, -MAX_DOUBLE_SIZE, 0.0 );
    if ( ParamUtils::insert ( param, &this->param_tree ) < 0 )
    {
      abort();
    }
  }

  /* End of parameter loading. Note that the read only parameters associated
     with custom waves (ie, sample) are variables stored in PresetFrameIO.hpp,
     and not specific to the custom wave datastructure. */
}

CustomWave::~CustomWave()
{
  for (std::vector<PerPointEqn*>::iterator pos = per_point_eqn_tree.begin(); pos != per_point_eqn_tree.end(); ++pos)
    delete(*pos);

  for (std::vector<PerFrameEqn*>::iterator pos = per_frame_eqn_tree.begin(); pos != per_frame_eqn_tree.end(); ++pos)
    delete(*pos);

  for (std::map<std::string, InitCond*>::iterator pos = init_cond_tree.begin(); pos != init_cond_tree.end(); ++pos)
    delete(pos->second);

  for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree.begin(); pos != per_frame_init_eqn_tree.end(); ++pos)
    delete(pos->second);

  for (std::map<std::string, Param*>::iterator pos = param_tree.begin(); pos != param_tree.end(); ++pos)
    delete(pos->second);

  free (r_mesh);
  free (g_mesh);
  free (b_mesh);
  free (a_mesh);
  free (x_mesh);
  free (y_mesh);
  free (value1);
  free (value2);
  free (sample_mesh);
}




// Comments: index is not passed, so we assume monotonic increment by 1 is ok here
int
CustomWave::add_per_point_eqn(char * name, GenExpr * gen_expr)
{

  PerPointEqn * per_point_eqn;
  int index;
  Param * param = NULL;

  /* Argument checks */
  if (gen_expr == NULL)
    return PROJECTM_FAILURE;
  if (name == NULL)
    return PROJECTM_FAILURE;

  if (CUSTOM_WAVE_DEBUG) printf("add_per_point_eqn: per pixel equation (name = \"%s\")\n", name);

  /* Search for the parameter so we know what matrix the per pixel equation is referencing */

  if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(name,&param_tree)) == NULL)
  {
    if (CUSTOM_WAVE_DEBUG)
      printf("add_per_point_eqn: failed to allocate a new parameter!\n");
    return PROJECTM_FAILURE;
  }

  /* Get largest index in the tree */
  index = per_point_eqn_tree.size();

  /* Create the per point equation given the index, parameter, and general expression */
  if ((per_point_eqn = new PerPointEqn(index, param, gen_expr, samples)) == NULL)
    return PROJECTM_FAILURE;

  if (CUSTOM_WAVE_DEBUG)
    printf("add_per_point_eqn: created new equation (index = %d) (name = \"%s\")\n", per_point_eqn->index, per_point_eqn->param->name.c_str());

  /* Insert the per pixel equation into the preset per pixel database */

  per_point_eqn_tree.push_back(per_point_eqn);

  /* Done */
  return PROJECTM_SUCCESS;
}


void
CustomWave::evalInitConds()
{
  for (std::map<std::string, InitCond*>::iterator pos = per_frame_init_eqn_tree.begin();
       pos != per_frame_init_eqn_tree.end();
       ++pos)
  {
    assert(pos->second);
    pos->second->evaluate();
  }
}

ColoredPoint
CustomWave::PerPoint (ColoredPoint p, const WaveformContext context)
{
  r_mesh[context.sample_int] = r;
  g_mesh[context.sample_int] = g;
  b_mesh[context.sample_int] = b;
  a_mesh[context.sample_int] = a;
  x_mesh[context.sample_int] = x;
  y_mesh[context.sample_int] = y;
  sample = context.sample;
  sample_mesh[context.sample_int] = context.sample;
  v1 = context.left;
  v2 = context.right;

  for (std::vector<PerPointEqn*>::iterator pos = per_point_eqn_tree.begin();
       pos != per_point_eqn_tree.end();
       ++pos)
    (*pos)->evaluate(context.sample_int);

  p.a = a_mesh[context.sample_int];
  p.r = r_mesh[context.sample_int];
  p.g = g_mesh[context.sample_int];
  p.b = b_mesh[context.sample_int];
  p.x = x_mesh[context.sample_int];
  p.y = y_mesh[context.sample_int];

  return p;
}


void
CustomWave::loadUnspecInitConds()
{
  InitCondUtils::LoadUnspecInitCond fun(this->init_cond_tree, this->per_frame_init_eqn_tree);
  traverse(param_tree, fun);
}
