/**
 * 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);
}

