/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2007 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 should 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
 *
 */
/**
 * $Id$
 *
 * MilkdropPreset
 *
 * $Log$
 */
#ifndef _MilkdropPreset_HPP
#define _MilkdropPreset_HPP

#include "Common.hpp"
#include <string>
#include <cassert>
#include <map>

#define MILKDROP_PRESET_DEBUG 0 /* 0 for no debugging, 1 for normal, 2 for insane */

#include "CustomShape.hpp"
#include "CustomWave.hpp"
#include "Expr.hpp"
#include "PerPixelEqn.hpp"
#include "PerFrameEqn.hpp"
#include "BuiltinParams.hpp"
#include "PresetFrameIO.hpp"
#include "InitCond.hpp"
#include "Preset.hpp"


class CustomWave;
class CustomShape;
class InitCond;


class MilkdropPreset : public Preset
{

public:


  ///  Load a MilkdropPreset by filename with input and output buffers specified.
  /// \param absoluteFilePath the absolute file path of a MilkdropPreset to load from the file system
  /// \param MilkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
  /// \param MilkdropPresetInputs a reference to read only projectM engine variables
  /// \param MilkdropPresetOutputs initialized and filled with data parsed from a MilkdropPreset
  MilkdropPreset(const std::string & absoluteFilePath, const std::string & milkdropPresetName, PresetOutputs & presetOutputs);

  ///  Load a MilkdropPreset from an input stream with input and output buffers specified.
  /// \param in an already initialized input stream to read the MilkdropPreset file from
  /// \param MilkdropPresetName a descriptive name for the MilkdropPreset. Usually just the file name
  /// \param MilkdropPresetInputs a reference to read only projectM engine variables
  /// \param MilkdropPresetOutputs initialized and filled with data parsed from a MilkdropPreset
  MilkdropPreset(std::istream & in, const std::string & milkdropPresetName, PresetOutputs & presetOutputs);

  ~MilkdropPreset();

  /// All "builtin" parameters for this MilkdropPreset. Anything *but* user defined parameters and
  /// custom waves / shapes objects go here.
  /// @bug encapsulate
  BuiltinParams builtinParams;


  /// Used by parser to find/create custom waves and shapes. May be refactored
  template <class CustomObject>
  static CustomObject * find_custom_object(int id, std::vector<CustomObject*> & customObjects);


  int per_pixel_eqn_string_index;
  int per_frame_eqn_string_index;
  int per_frame_init_eqn_string_index;

  int per_frame_eqn_count,
  per_frame_init_eqn_count;


  /// Used by parser
  /// @bug refactor
  int add_per_pixel_eqn( char *name, GenExpr *gen_expr );

  /// Accessor method to retrieve the absolute file path of the loaded MilkdropPreset
  /// \returns a file path string
  std::string absoluteFilePath() const
  {
    return _absoluteFilePath;
  }


  /// Accessor method for the MilkdropPreset outputs instance associated with this MilkdropPreset
  /// \returns A MilkdropPreset output instance with values computed from most recent evaluateFrame()
  PresetOutputs & presetOutputs() const
  {
    return _presetOutputs;
  }

  const PresetInputs & presetInputs() const
  {
    return _presetInputs;
  }


  // @bug encapsulate

  PresetOutputs::cwave_container customWaves;
  PresetOutputs::cshape_container customShapes;

  /// @bug encapsulate
  /* Data structures that contain equation and initial condition information */
  std::vector<PerFrameEqn*>  per_frame_eqn_tree;   /* per frame equations */
  std::map<int, PerPixelEqn*>  per_pixel_eqn_tree; /* per pixel equation tree */
  std::map<std::string,InitCond*>  per_frame_init_eqn_tree; /* per frame initial equations */
  std::map<std::string,InitCond*>  init_cond_tree; /* initial conditions */
  std::map<std::string,Param*> user_param_tree; /* user parameter splay tree */


  PresetOutputs & pipeline() { return _presetOutputs; }

  void Render(const BeatDetect &music, const PipelineContext &context);
  const std::string & name() const;
  const std::string & filename() const { return _filename; }
  private:
  std::string _filename;
  PresetInputs _presetInputs;
  /// Evaluates the MilkdropPreset for a frame given the current values of MilkdropPreset inputs / outputs
  /// All calculated values are stored in the associated MilkdropPreset outputs instance
  void evaluateFrame();

  // The absolute file path of the MilkdropPreset
  std::string _absoluteFilePath;

  // The absolute path of the MilkdropPreset
  std::string _absolutePath;

  void initialize(const std::string & pathname);
  void initialize(std::istream & in);

  int loadPresetFile(const std::string & pathname);

  void loadBuiltinParamsUnspecInitConds();
  void loadCustomWaveUnspecInitConds();
  void loadCustomShapeUnspecInitConds();

  void evalCustomWavePerFrameEquations();
  void evalCustomShapePerFrameEquations();
  void evalPerFrameInitEquations();
  void evalCustomWaveInitConditions();
  void evalCustomShapeInitConditions();
  void evalPerPixelEqns();
  void evalPerFrameEquations();
  void initialize_PerPixelMeshes();
  int readIn(std::istream & fs);

  void preloadInitialize();
  void postloadInitialize();

  PresetOutputs & _presetOutputs;

  template <class CustomObject>
  void transfer_q_variables(std::vector<CustomObject*> & customObjects);
};


template <class CustomObject> void
MilkdropPreset::transfer_q_variables(std::vector<CustomObject*> & customObjects)
{
  CustomObject * custom_object;

  for (typename std::vector<CustomObject*>::iterator pos = customObjects.begin();
       pos != customObjects.end();
       ++pos)
  {
    custom_object = *pos;
    for (unsigned int i = 0; i < NUM_Q_VARIABLES; i++)
      custom_object->q[i] = _presetOutputs.q[i];
  }
}

template <class CustomObject> CustomObject *
MilkdropPreset::find_custom_object(int id, std::vector<CustomObject*> & customObjects)
{
  CustomObject * custom_object = NULL;

  for (typename std::vector<CustomObject*>::iterator pos = customObjects.begin();
       pos != customObjects.end();
       ++pos)
  {
    if ((*pos)->id == id) {
      custom_object = *pos;
      break;
    }
  }

  if (custom_object == NULL)
  {
    if ((custom_object = new CustomObject(id)) == NULL)
    {
      return NULL;
    }

    customObjects.push_back(custom_object);
  }

  assert(custom_object);
  return custom_object;
}


#endif /** !_MilkdropPreset_HPP */
