/**
 * 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
* 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
 *
 */
/* parser.c */
#include <stdio.h>
#include <string>
#include <cstring>
#include <iostream>
#include <stdlib.h>

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

#include "CustomWave.hpp"
#include "CustomShape.hpp"
#include "Expr.hpp"
#include "Eval.hpp"
#include "Func.hpp"
#include "InitCond.hpp"
#include "Param.hpp"
#include "Parser.hpp"
#include "PerFrameEqn.hpp"
#include "PerPixelEqn.hpp"
#include <map>
#include "ParamUtils.hpp"

#include "wipemalloc.h"
#include <iostream>
#include <sstream>
#include "BuiltinFuncs.hpp"


/* Grabs the next token from the file. The second argument points
   to the raw string */

line_mode_t   Parser::line_mode;
CustomWave    *Parser::current_wave;
CustomShape   *Parser::current_shape;
int           Parser::string_line_buffer_index;
char          Parser::string_line_buffer[STRING_LINE_SIZE];
unsigned int  Parser::line_count;
int           Parser::per_frame_eqn_count;
int           Parser::per_frame_init_eqn_count;
int           Parser::last_custom_wave_id;
int           Parser::last_custom_shape_id;
char          Parser::last_eqn_type[MAX_TOKEN_SIZE];
int           Parser::last_token_size;

std::string Parser::lastLinePrefix("");

bool Parser::tokenWrapAroundEnabled(false);


token_t
Parser::parseToken(std::istream &  fs, char * string)
{
  int c;
  int i;

  if (string != NULL)
    memset(string, 0, MAX_TOKEN_SIZE);


  /* Loop until a delimiter is found, or the maximum string size is found */
  for (i = 0; i < MAX_TOKEN_SIZE;i++)
  {
    //c = fgetc(fs);
    if (!fs || fs.eof())
      c = EOF;
    else
      c = fs.get();

    last_token_size++;
    /* If the string line buffer is full, quit */
    if (string_line_buffer_index == (STRING_LINE_SIZE - 1))
      return tStringBufferFilled;

    /* Otherwise add this character to the string line buffer */
    string_line_buffer[string_line_buffer_index++] = tolower(c);
    /* Now interpret the character */
    switch (c)
    {
    case '+':
      return tPlus;
    case '-':
      return tMinus;
    case '%':
      return tMod;
    case '/':

      /* check for line comment here */
      if (!fs || fs.eof())
        c = EOF;
      else
        c = fs.get();
      if (c == '/')
      {
        while (true)
        {
          if (!fs || fs.eof())
            c = EOF;
          else
            c = fs.get();
          if (c == EOF)
          {
            line_mode = UNSET_LINE_MODE;
            return tEOF;
          }
          if (c == '\n')
          {
            line_mode = UNSET_LINE_MODE;
            return tEOL;
          }
        }
      }

      /* Otherwise, just a regular division operator */
      fs.unget();
      return tDiv;
    case '*':
      return tMult;
    case '|':
      return tOr;
    case '&':
      return tAnd;
    case '(':
      return tLPr;
    case ')':
      return tRPr;
    case '[':
      return tLBr;
    case ']':
      return tRBr;
    case '=':
      return tEq;
    case '\n':
      line_count++;
      /// @note important hack implemented here to handle "wrap around tokens"
      // In particular: "per_frame_1=x=t+1.\nper_frame_2=37 + 5;" implies
      // "per_frame_1=x=t+1.37 + 5;". Thus, we have a global flag to determine
      // if "token wrap mode" is enabled. If so, we consider a token *continuing*
      // to the next line, but only attaching to the token buffer anything following
      // the first equals sign on that line.
      //
      // We can safely assume the next line must be part of the token if we allow the
      // semi colon to be a guaranteed delimiter in the grammar for all equation-based lines.
      // This IS NO LONGER assumed here. Instead, we check if the next line prefix
      // matches with the previous line prefix. If it passes a simple comparison, we wrap around.

      if (tokenWrapAroundEnabled)
      {
        std::ostringstream buffer;

        if (PARSE_DEBUG) std::cerr << "token wrap! line " << line_count << std::endl;
        while (c != '=')
        {
          if (!fs || fs.eof())
          {
            line_count = 1;
            line_mode = UNSET_LINE_MODE;
            if (PARSE_DEBUG)     std::cerr << "token wrap: end of file" << std::endl;
            return tEOF;
          }
          else {
            c = fs.get();
            if ( c != '=')
            buffer << (char)c;
          }
        }

        if (PARSE_DEBUG)
          std::cerr << "parseToken: parsed away equal sign, line prefix is \""
                    << buffer.str()
                    << "\""
                    << std::endl;
        --i;

        if (!wrapsToNextLine(buffer.str())) {
          tokenWrapAroundEnabled = false;
          int buf_size = (int)buffer.str().length();
          // <= to also remove equal sign parsing from stream
          for (int k = 0; k <= buf_size; k++) {
            if (fs)
              fs.unget();
            else
              abort();
          }
          return tEOL;
        }


        break;
      }


      line_mode = UNSET_LINE_MODE;
      return tEOL;
    case ',':
      return tComma;
    case ';':
      tokenWrapAroundEnabled = false;
      if (PARSE_DEBUG) std::cerr << "token wrap around = false (LINE " << line_count << ")" << std::endl;
      return tSemiColon;
    case ' ': /* space, skip the character */
      i--;
      break;
    case EOF:
      line_count = 1;
      line_mode = UNSET_LINE_MODE;
      return tEOF;

    case '\r':
      i--;
      break;
      default:
      if (c == EOF)
        std::cerr << "shouldn't happen: " << c << "(LINE " << line_count << ")" << std::endl;
      string[i] = tolower(c);
      //string[i+1] = 0;
      //std::cerr << "string is \n\"" << string << "\"" << std::endl;
    }


  }

  /* String reached maximum length, return special token error */
  return tStringTooLong;
}

/* Parse input in the form of "exp, exp, exp, ...)"
   Returns a general expression list */

GenExpr **
Parser::parse_prefix_args(std::istream &  fs, int num_args, MilkdropPreset * preset)
{
  int     i, j;
  GenExpr ** expr_list; /* List of arguments to function */
  GenExpr * gen_expr;

  /* Malloc the expression list */
  expr_list =  (GenExpr**)wipemalloc(sizeof(GenExpr*)*num_args);

  /* Malloc failed */
  if (expr_list == NULL)
    return NULL;


  i = 0;

  while (i < num_args)
  {
    //if (PARSE_DEBUG) printf("parse_prefix_args: parsing argument %d...\n", i+1);
    /* Parse the ith expression in the list */
    if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
    {
      //if (PARSE_DEBUG) printf("parse_prefix_args: failed to get parameter # %d for function (LINE %d)\n", i+1, line_count);
      for (j = 0; j < i; j++)
        delete expr_list[j];
      free(expr_list);
      expr_list = NULL;
      return NULL;
    }
    /* Assign entry in expression list */
    expr_list[i++] = gen_expr;
  }

  //if (PARSE_DEBUG) printf("parse_prefix_args: finished parsing %d arguments (LINE %d)\n", num_args, line_count);
  /* Finally, return the resulting expression list */
  return expr_list;
}

/* Parses a comment at the top of the file. Stops when left bracket is found */
int
Parser::parse_top_comment(std::istream &  fs)
{

  char string[MAX_TOKEN_SIZE];
  token_t token;

  /* Process tokens until left bracket is found */
  while ((token = parseToken(fs, string)) != tLBr)
  {
    if (token == tEOF)
      return PROJECTM_PARSE_ERROR;
  }

  /* Done, return success */
  return PROJECTM_SUCCESS;
}

/* Right Bracket is parsed by this function.
   puts a new string into name */
int
Parser::parse_preset_name(std::istream &  fs, char * name)
{
  token_t token;

  if (name == NULL)
    return PROJECTM_FAILURE;

  if ((token = parseToken(fs, name)) != tRBr)
    return PROJECTM_PARSE_ERROR;

  return PROJECTM_SUCCESS;
}


/* Parses per pixel equations */
int
Parser::parse_per_pixel_eqn(std::istream &  fs, MilkdropPreset * preset, char * init_string)
{
  char string[MAX_TOKEN_SIZE];
  GenExpr * gen_expr;

  if (init_string != 0)
  {
    strncpy(string, init_string, strlen(init_string));
  }
  else
  {
    if (parseToken(fs, string) != tEq)
    { /* parse per pixel operator name */
      return PROJECTM_PARSE_ERROR;
    }
  }

  /* Parse right side of equation as an expression */
  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
  {
    return PROJECTM_PARSE_ERROR;
  }

  /* Add the per pixel equation */
  if (preset->add_per_pixel_eqn(string, gen_expr) < 0)
  {
    if (PARSE_DEBUG)
    {

    }
    delete gen_expr;
    return PROJECTM_PARSE_ERROR;
  }

  return PROJECTM_SUCCESS;
}

/* Parses an equation line, this function is way too big, should add some helper functions */
int
Parser::parse_line(std::istream &  fs, MilkdropPreset * preset)
{

  char        eqn_string[MAX_TOKEN_SIZE];
  token_t     token;
  InitCond    * init_cond;
  PerFrameEqn * per_frame_eqn;

  /* Clear the string line buffer */
  memset(string_line_buffer, 0, STRING_LINE_SIZE);
  string_line_buffer_index = 0;

  tokenWrapAroundEnabled = false;

  token = parseToken( fs, eqn_string );
  switch (token)
  {

    /* Invalid Cases */
  case tRBr:
  case tLPr:
  case tRPr:
  case tComma:
  case tLBr:
  case tPlus:
  case tMinus:
  case tMod:
  case tMult:
  case tOr:
  case tAnd:
  case tDiv:

    if (PARSE_DEBUG) std::cerr << "parse_line: invalid token found at start of line (LINE "
    << line_count << ")" << std::endl;

    /* Invalid token found, return a parse error */
    return PROJECTM_PARSE_ERROR;


  case tEOL:  /* Empty line */
    line_mode = UNSET_LINE_MODE;
    return PROJECTM_SUCCESS;

  case tEOF: /* End of File */
    line_mode = UNSET_LINE_MODE;
    line_count = 1;
    tokenWrapAroundEnabled = false;
    return EOF;

  case tSemiColon: /* Indicates end of expression */
    tokenWrapAroundEnabled = false;
    return PROJECTM_SUCCESS;

    /* Valid Case, either an initial condition or equation should follow */
  case tEq:
    lastLinePrefix = std::string(eqn_string);
    if (PARSE_DEBUG) std::cout << "last line prefix = \"" << eqn_string << "\"" << std::endl;
    // std::cerr << "parse_line: tEQ case, fs.peek()=\'" << fs.peek() << "\'" << std::endl;
    if (!fs)
      return PROJECTM_PARSE_ERROR;

    //  char z = fs.get();
    char tmpChar;

    if ((tmpChar = fs.get()) == '\n') {
      tokenWrapAroundEnabled = false;
      return PROJECTM_PARSE_ERROR;
    } else if (tmpChar == '\r') {
      tokenWrapAroundEnabled = false;
      return PROJECTM_PARSE_ERROR;
    } else
      fs.unget();



    /* CASE: WARP CODE */
    if (!strncmp(eqn_string, WARP_STRING, WARP_STRING_LENGTH))
    {
      //std::cout << "parsing warp string block\n" << std::endl;
      parse_string_block(fs, &preset->presetOutputs().warpShader.programSource);
      return PROJECTM_SUCCESS;
    }


    /* CASE: COMPOSITE CODE */
    if (!strncmp(eqn_string, COMPOSITE_STRING, COMPOSITE_STRING_LENGTH))
    {
      //std::cout << "parsing composite string block\n" << std::endl;
      parse_string_block(fs, &preset->presetOutputs().compositeShader.programSource);
      return PROJECTM_SUCCESS;
    }

    /* CASE: PER FRAME INIT EQUATION */
    if (!strncmp(eqn_string, PER_FRAME_INIT_STRING, PER_FRAME_INIT_STRING_LENGTH))
    {
      tokenWrapAroundEnabled = true;
      //if (PARSE_DEBUG) printf("parse_line: per frame init equation found...(LINE %d)\n", line_count);

      /* Parse the per frame equation */
      if ((init_cond = parse_per_frame_init_eqn(fs, preset, NULL)) == NULL)
      {
        //if (PARSE_DEBUG) printf("parse_line: per frame init equation parsing failed (LINE %d)\n", line_count);
        tokenWrapAroundEnabled = false;
        return PROJECTM_PARSE_ERROR;
      }

      /* Insert the equation in the per frame equation tree */
      preset->per_frame_init_eqn_tree.insert(std::make_pair(init_cond->param->name, init_cond));

      line_mode = PER_FRAME_INIT_LINE_MODE;
      return PROJECTM_SUCCESS;
    }

    /* Per frame equation case */
    if (!strncmp(eqn_string, PER_FRAME_STRING, PER_FRAME_STRING_LENGTH))
    {
      tokenWrapAroundEnabled = true;
      /* Sometimes per frame equations are implicitly defined without the
      per_frame_ prefix. This informs the parser that one could follow */
      line_mode = PER_FRAME_LINE_MODE;

      //if (PARSE_DEBUG) printf("parse_line: per frame equation found...(LINE %d)\n", line_count);

      /* Parse the per frame equation */
      if ((per_frame_eqn = parse_per_frame_eqn(fs, ++per_frame_eqn_count, preset)) == NULL)
      {
        if (PARSE_DEBUG) printf("parse_line: per frame equation parsing failed (LINE %d)\n", line_count);
        tokenWrapAroundEnabled = false;
        return PROJECTM_PARSE_ERROR;
      }

      /* Insert the equation in the per frame equation tree */
      preset->per_frame_eqn_tree.push_back(per_frame_eqn);

      return PROJECTM_SUCCESS;

    }

    /* Wavecode initial condition case */
    if (!strncmp(eqn_string, WAVECODE_STRING, WAVECODE_STRING_LENGTH))
    {
      line_mode = CUSTOM_WAVE_WAVECODE_LINE_MODE;

      return parse_wavecode(eqn_string, fs, preset);
    }

    /* Custom Wave Prefix */
    if (    (!strncmp(eqn_string, WAVE_STRING, WAVE_STRING_LENGTH))
        &&  ((eqn_string[5] >= 48)  &&  (eqn_string[5] <= 57)))
    {
      tokenWrapAroundEnabled = true;
      //    if (PARSE_DEBUG) printf("parse_line wave prefix found: \"%s\"\n", eqn_string);

      return parse_wave(eqn_string, fs, preset);
    }


    /* Shapecode initial condition case */
    if (!strncmp(eqn_string, SHAPECODE_STRING, SHAPECODE_STRING_LENGTH))
    {
      line_mode = CUSTOM_SHAPE_SHAPECODE_LINE_MODE;

      if (PARSE_DEBUG) printf("parse_line: shapecode prefix found: \"%s\"\n", eqn_string);

      return parse_shapecode(eqn_string, fs, preset);
    }

    /* Custom Shape Prefix */
    if (    (!strncmp(eqn_string, SHAPE_STRING, SHAPE_STRING_LENGTH))
        &&  ((eqn_string[6] >= 48)  &&  (eqn_string[6] <= 57)))
    {
      tokenWrapAroundEnabled = true;
      if (PARSE_DEBUG) printf("parse_line shape prefix found: \"%s\"\n", eqn_string);
      return parse_shape(eqn_string, fs, preset);
    }

    /* Per pixel equation case */
    if (!strncmp(eqn_string, PER_PIXEL_STRING, PER_PIXEL_STRING_LENGTH))
    {
      tokenWrapAroundEnabled = true;

      line_mode = PER_PIXEL_LINE_MODE;

      if (parse_per_pixel_eqn(fs, preset, 0) < 0)
      {
        tokenWrapAroundEnabled = false;
        return PROJECTM_PARSE_ERROR;
      }


      if (PARSE_DEBUG) printf("parse_line: finished parsing per pixel equation (LINE %d)\n", line_count);
      return PROJECTM_SUCCESS;
    }

    /* Sometimes equations are written implicitly in milkdrop files, in the form

       per_frame_1 = p1 = eqn1; p2 = eqn2; p3 = eqn3;..;

       which is analagous to:

       per_frame_1 = p1 = eqn1; per_frame_2 = p2 = eqn2; per_frame_3 = p3 = eqn3; ...;

       The following line mode hack allows such implicit declaration of the
       prefix that specifies the equation type. An alternative method
       may be to associate each equation line as list of equations separated
       by semicolons (and a new line ends the list). Instead, however, a global
       variable called "line_mode" specifies the last type of equation found,
       and bases any implicitly typed input on this fact

       Note added by Carmelo Piccione (carmelo.piccione@gmail.com) 10/19/03
    */

    /* Per frame line mode previously, try to parse the equation implicitly */
    if (line_mode == PER_FRAME_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;
      if ((per_frame_eqn = parse_implicit_per_frame_eqn(fs, eqn_string, ++per_frame_eqn_count, preset)) == NULL)
      {
        tokenWrapAroundEnabled = false;
        return PROJECTM_PARSE_ERROR;
      }

      /* Insert the equation in the per frame equation tree */
      preset->per_frame_eqn_tree.push_back(per_frame_eqn);


      return PROJECTM_SUCCESS;
    }
    else if (line_mode == PER_FRAME_INIT_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;
      if (PARSE_DEBUG) printf("parse_line: parsing implicit per frame init eqn)\n");
      if ((init_cond = parse_per_frame_init_eqn(fs, preset, NULL)) == NULL)
      {
        tokenWrapAroundEnabled = false;
        return PROJECTM_PARSE_ERROR;
      }

      ++per_frame_init_eqn_count;

      /* Insert the equation in the per frame equation tree */
      preset->per_frame_init_eqn_tree.insert(std::make_pair(init_cond->param->name, init_cond));

      return PROJECTM_SUCCESS;
    }
    else if (line_mode == PER_PIXEL_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;
      if (PARSE_DEBUG) printf("parse_line: implicit per pixel eqn (LINE %d)\n", line_count);
      return parse_per_pixel_eqn(fs, preset, eqn_string);
    }
    else if (line_mode == CUSTOM_WAVE_PER_POINT_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;
      if (PARSE_DEBUG) printf("parse_line: implicit cwave ppoint eqn found (LINE %d)\n", line_count);
      //int len = strlen(eqn_string);

      if (parse_wave_helper(fs, preset, last_custom_wave_id, last_eqn_type, eqn_string) < 0)
      {
        if (PARSE_DEBUG) printf("parse_line: failed to parse an implicit custom wave per point eqn\n");
        return PROJECTM_FAILURE;
      }
      return PROJECTM_SUCCESS;
    }
    else if (line_mode == CUSTOM_WAVE_PER_FRAME_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;
      //Added by PJS. I hope I did it right
      CustomWave * custom_wave;

      /* Retrieve custom shape associated with this id */
      if ((custom_wave = MilkdropPreset::find_custom_object(last_custom_wave_id, preset->customWaves)) == NULL)
        return PROJECTM_FAILURE;
      return parse_wave_per_frame_eqn(fs, custom_wave, preset);
    }
    else if (line_mode == CUSTOM_WAVE_WAVECODE_LINE_MODE)
    {
      if (PARSE_DEBUG) printf("unsupported line mode: CUSTOM_WAVE_WAVECODE_LINE_MODE\n");
      return PROJECTM_FAILURE;
    }
    else if (line_mode == CUSTOM_SHAPE_SHAPECODE_LINE_MODE)
    {
      if (PARSE_DEBUG) printf("unsupported line mode: CUSTOM_SHAPE_SHAPECODE_LINE_MODE\n");
      return PROJECTM_FAILURE;
    }
    else if (line_mode == CUSTOM_SHAPE_PER_FRAME_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;

      CustomShape * custom_shape;

      /* Retrieve custom shape associated with this id */
      if ((custom_shape = MilkdropPreset::find_custom_object(last_custom_shape_id, preset->customShapes)) == NULL)
        return PROJECTM_FAILURE;

      return parse_shape_per_frame_eqn(fs, custom_shape, preset);
    }
    else if (line_mode == CUSTOM_SHAPE_PER_FRAME_INIT_LINE_MODE)
    {
      tokenWrapAroundEnabled = true;
      CustomShape * custom_shape;

      /* Retrieve custom shape associated with this id */
      if ((custom_shape = preset->find_custom_object(last_custom_shape_id, preset->customShapes)) == NULL)
        return PROJECTM_FAILURE;

      return parse_shape_per_frame_init_eqn(fs, custom_shape, preset);
    }

    if (PARSE_DEBUG) printf("parse_line: found initial condition: name = \"%s\" (LINE %d)\n", eqn_string, line_count);
    /* Evaluate the initial condition */
    if ((init_cond = parse_init_cond(fs, eqn_string, preset)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_line: failed to parse initial condition (LINE %d)\n", line_count);
      return PROJECTM_PARSE_ERROR;
    }

    /* Add equation to initial condition tree */
    preset->init_cond_tree.insert(std::make_pair(init_cond->param->name, init_cond));

    /* Finished with initial condition line */
    //    if (PARSE_DEBUG) printf("parse_line: initial condition parsed successfully\n");

    return PROJECTM_SUCCESS;

    /* END INITIAL CONDITIONING PARSING */

  default: /* an uncaught type or an error has occurred */
    if (PARSE_DEBUG) printf("parse_line: uncaught case, token val = %d\n", token);
    return PROJECTM_PARSE_ERROR;
  }

  /* Because of the default in the case statement,
     control flow should never actually reach here */
  return PROJECTM_PARSE_ERROR;
}



/* Parses a general expression, this function is the meat of the parser */
GenExpr *
Parser::parse_gen_expr ( std::istream &  fs, TreeExpr * tree_expr, MilkdropPreset * preset)
{
  int     i;
  char    string[MAX_TOKEN_SIZE];
  token_t token;
  GenExpr * gen_expr;
  float   val;
  Param   * param = NULL;
  Func    * func;
  GenExpr ** expr_list;

  switch (token = parseToken(fs,string))
  {
    /* Left Parentice Case */
  case tLPr:
    //std::cerr << "token before tLPr:" << string << std::endl;
    /* CASE 1 (Left Parentice): See if the previous string before this parentice is a function name */
    if ((func = BuiltinFuncs::find_func(string)) != NULL)
    {
      if (PARSE_DEBUG)
      {
        std::cerr << "parse_gen_expr: found prefix function (name = \""
                  << func->getName()
                  << "\") (LINE " << line_count << ")"
                  << std::endl;
      }

      /* Parse the functions arguments */
      if ((expr_list = parse_prefix_args(fs, func->getNumArgs(), preset)) == NULL)
      {
        if (PARSE_DEBUG)
        {
          std::cerr << "parse_prefix_args: failed to generate an expresion list! (LINE "
                    << line_count << ")"
                    << std::endl;
        }
        if ( tree_expr != NULL )
        {
          delete tree_expr;
        }
        return NULL;
      }

      /* Convert function to expression */
      if ((gen_expr = GenExpr::prefun_to_expr((float (*)(void *))func->func_ptr, expr_list, func->getNumArgs())) == NULL)
      {
        if (PARSE_DEBUG)
          printf("parse_prefix_args: failed to convert prefix function to general expression (LINE %d) \n", line_count);
        if (tree_expr)
          delete tree_expr;
        for (i = 0; i < func->getNumArgs();i++)
          delete expr_list[i];
        free(expr_list);
        expr_list = NULL;
        return NULL;
      }

      token = parseToken(fs, string);

      if (*string != 0)
      {
        if (PARSE_DEBUG) printf("parse_prefix_args: empty string expected, but not found...(LINE %d)\n", line_count);
        /* continue anyway for now, could be implicit multiplication */
      }

      return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
    }


    /* Case 2: (Left Parentice), a string coupled with a left parentice. Either an error or implicit
    multiplication operator. For now treat it as an error */
    if (*string != 0)
    {
      std::cerr << "token prefix is " << *string << std::endl;
      if (PARSE_DEBUG) printf("parse_gen_expr: implicit multiplication case unimplemented!\n");
      if (tree_expr)
        delete tree_expr;
      return NULL;
    }

    /* CASE 3 (Left Parentice): the following is enclosed parentices to change order
    of operations. So we create a new expression tree */

    if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_gen_expr:  found left parentice, but failed to create new expression tree \n");
      if (tree_expr)
        delete tree_expr;
      return NULL;
    }

    if (PARSE_DEBUG) printf("parse_gen_expr: finished enclosed expression tree...\n");
    token = parseToken(fs, string);
    return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);

    /* Plus is a prefix operator check */
  case tPlus:
    if (*string == 0)
    {
      if (PARSE_DEBUG) printf("parse_gen_expr: plus used as prefix (LINE %d)\n", line_count);

      /* Treat prefix plus as implict 0 preceding operator */
      gen_expr = GenExpr::const_to_expr(0);

      return parse_infix_op(fs, tPositive, insert_gen_expr(gen_expr, &tree_expr), preset);
    }

    /* Minus is a prefix operator check */
  case tMinus:
    if (*string == 0)
    {
      /* Use the negative infix operator, but first add an implicit zero to the operator tree */
      gen_expr = GenExpr::const_to_expr(0);
      //return parse_gen_expr(fs, insert_gen_expr(gen_expr, &tree_expr), preset);
      return parse_infix_op(fs, tNegative, insert_gen_expr(gen_expr, &tree_expr), preset);
    }

    /* All the following cases are strings followed by an infix operator or terminal */
  case tRPr:
  case tEOL:
  case tEOF:
  case tSemiColon:
  case tComma:

    /* CASE 1 (terminal): string is empty, but not null. Not sure if this will actually happen
    any more. */
    if (*string == 0)
    {
      if (PARSE_DEBUG) printf("parse_gen_expr: empty string coupled with terminal (LINE %d) \n", line_count);
      return parse_infix_op(fs, token, tree_expr, preset);

    }

  default:

    /* CASE 0: Empty string, parse error */
    if (*string == 0)
    {
      if (tree_expr)
        delete tree_expr;
      return NULL;
    }

    /* CASE 1: Check if string is a just a floating point number */
    if (string_to_float(string, &val) != PROJECTM_PARSE_ERROR)
    {
      if ((gen_expr = GenExpr::const_to_expr(val)) == NULL)
      {
      if (tree_expr)
        delete tree_expr;
      return NULL;
      }

      /* Parse the rest of the line */
      return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
    }


    /* CASE 4: custom shape variable */
    if (current_shape != NULL)
    {
      if ((param = ParamUtils::find<ParamUtils::NO_CREATE>(std::string(string), &current_shape->param_tree)) == NULL)
      {
        if ((param = preset->builtinParams.find_builtin_param(std::string(string))) == NULL)
          if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(std::string(string), &current_shape->param_tree)) == NULL)
          {
            if (tree_expr)
            delete tree_expr;
            return NULL;
          }
      }

      if (PARSE_DEBUG)
      {
        std::cerr << "parse_gen_expr: custom shape parameter (name = "
                  << param->name << ")"
                  << std::endl;
      }


      /* Convert parameter to an expression */
      if ((gen_expr = GenExpr::param_to_expr(param)) == NULL)
      {
        delete tree_expr;
        return NULL;
      }

      //if (PARSE_DEBUG) printf("converted to expression (LINE %d)\n", line_count);

      /* Parse the rest of the line */
      return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
    }

    /* CASE 5: custom wave variable */
    if (current_wave != NULL)
    {
      if ((param = ParamUtils::find<ParamUtils::NO_CREATE>(std::string(string), &current_wave->param_tree)) == NULL)
      {
        if ((param = preset->builtinParams.find_builtin_param(std::string(string))) == NULL)
          if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(std::string(string), &current_wave->param_tree)) == NULL)
          {
            if (tree_expr)
            delete tree_expr;
            return NULL;
          }
      }
      assert(param);

      if (PARSE_DEBUG)
      {
        std::cerr << "parse_gen_expr: custom wave parameter (name = " <<  param->name << ")" << std::endl;
      }

      /* Convert parameter to an expression */
      if ((gen_expr = GenExpr::param_to_expr(param)) == NULL)
      {
        delete tree_expr;
        return NULL;
      }

      //if (PARSE_DEBUG) printf("converted to expression (LINE %d)\n", line_count);

      /* Parse the rest of the line */
      return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
    }

    /* CASE 6: regular parameter. Will be created if necessary and the string has no invalid characters */
    if ((param = ParamUtils::find(string, &preset->builtinParams, &preset->user_param_tree)) != NULL)
    {
      if (PARSE_DEBUG)
      {
        std::cerr << "parse_gen_expr: parameter (name = \"" << param->name << "\")..." << std::endl;
      }

      /* Convert parameter to an expression */
      if ((gen_expr = GenExpr::param_to_expr(param)) == NULL)
      {
        delete tree_expr;
        return NULL;
      }

      //if (PARSE_DEBUG) printf("converted to expression (LINE %d)\n", line_count);

      /* Parse the rest of the line */
      return parse_infix_op(fs, token, insert_gen_expr(gen_expr, &tree_expr), preset);
    }

    /* CASE 7: Bad string, give up */
    if (PARSE_DEBUG)
    {
      printf( "parse_gen_expr: syntax error [string = \"%s\"] (LINE %d)\n", string, line_count);
    }
    if (tree_expr)
      delete tree_expr;
    return NULL;
  }
}



/* Inserts expressions into tree according to operator precedence.
   If root is null, a new tree is created, with infix_op as only element */

TreeExpr *
Parser::insert_infix_op(InfixOp * infix_op, TreeExpr **root)
{
  TreeExpr * new_root;

  /* Sanity check */
  if (infix_op == NULL)
    return NULL;

  /* The root is null, so make this operator
     the new root */

  if (*root == NULL)
  {
    new_root = new TreeExpr(infix_op, NULL, NULL, NULL);
    *root = new_root;
    return new_root;
  }

  /* The root node is not an infix function,
     so we make this infix operator the new root  */

  if ((*root)->infix_op == NULL)
  {
    new_root = new TreeExpr(infix_op, NULL, *root, NULL);
    (*root) = new_root;
    return new_root;
  }

  /* The root is an infix function. If the precedence
     of the item to be inserted is greater than the root's
     precedence, then make gen_expr the root */

  if (infix_op->precedence >= (*root)->infix_op->precedence)
  {
    new_root = new TreeExpr(infix_op, NULL, *root, NULL);
    (*root) = new_root;
    return new_root;
  }

  /* If control flow reaches here, use a recursive helper
     with the knowledge that the root is higher precedence
     than the item to be inserted */

  insert_infix_rec(infix_op, *root);
  return *root;
}


TreeExpr *
Parser::insert_gen_expr(GenExpr * gen_expr, TreeExpr ** root)
{
  TreeExpr * new_root;

  /* If someone foolishly passes a null
     pointer to insert, return the original tree */

  if (gen_expr == NULL)
  {
    return *root;
  }

  /* If the root is null, generate a new expression tree,
     using the passed expression as the root element */

  if (*root == NULL)
  {
    new_root = new TreeExpr(NULL, gen_expr, NULL, NULL);
    *root = new_root;
    return new_root;
  }


  /* Otherwise. the new element definitely will not replace the current root.
     Use a recursive helper function to do insertion */

  insert_gen_rec(gen_expr, *root);
  return *root;
}

/* A recursive helper function to insert general expression elements into the operator tree */
int
Parser::insert_gen_rec(GenExpr * gen_expr, TreeExpr * root)
{
  /* Trivial Case: root is null */

  if (root == NULL)
  {
    //if (PARSE_DEBUG) printf("insert_gen_rec: root is null, returning failure\n");
    return PROJECTM_FAILURE;
  }


  /* The current node's left pointer is null, and this
     current node is an infix operator, so insert the
     general expression at the left pointer */

  if ((root->left == NULL) && (root->infix_op != NULL))
  {
    root->left = new TreeExpr(NULL, gen_expr, NULL, NULL);
    return PROJECTM_SUCCESS;
  }

  /* The current node's right pointer is null, and this
     current node is an infix operator, so insert the
     general expression at the right pointer */

  if ((root->right == NULL) && (root->infix_op != NULL))
  {
    root->right = new TreeExpr(NULL, gen_expr, NULL, NULL);
    return PROJECTM_SUCCESS;
  }

  /* Otherwise recurse down to the left. If
     this succeeds then return. If it fails, try
     recursing down to the right */

  if (insert_gen_rec(gen_expr, root->left) == PROJECTM_FAILURE)
    return insert_gen_rec(gen_expr, root->right);

  /* Impossible for control flow to reach here, but in
     the world of C programming, who knows... */
  if (PARSE_DEBUG) printf("insert_gen_rec: should never reach here!\n");
  return PROJECTM_FAILURE;
}


/* A recursive helper function to insert infix arguments by operator precedence */
int
Parser::insert_infix_rec(InfixOp * infix_op, TreeExpr * root)
{
  /* Shouldn't happen, implies a parse error */

  if (root == NULL)
    return PROJECTM_FAILURE;

  /* Also shouldn't happen, also implies a (different) parse error */

  if (root->infix_op == NULL)
    return PROJECTM_FAILURE;

  /* Left tree is empty, attach this operator to it.
     I don't think this will ever happen */
  if (root->left == NULL)
  {
    root->left = new TreeExpr(infix_op, NULL, root->left, NULL);
    return PROJECTM_SUCCESS;
  }

  /* Right tree is empty, attach this operator to it */
  if (root->right == NULL)
  {
    root->right = new TreeExpr(infix_op, NULL, root->right, NULL);
    return PROJECTM_SUCCESS;
  }

  /* The left element can now be ignored, since there is no way for this
     operator to use those expressions */

  /* If the right element is not an infix operator,
     then insert the expression here, attaching the old right branch
     to the left of the new expression */

  if (root->right->infix_op == NULL)
  {
    root->right = new TreeExpr(infix_op, NULL, root->right, NULL);
    return PROJECTM_SUCCESS;
  }

  /* Traverse deeper if the inserting operator precedence is less than the
     the root's right operator precedence */
  if (infix_op->precedence < root->right->infix_op->precedence)
    return insert_infix_rec(infix_op, root->right);

  /* Otherwise, insert the operator here */

  root->right = new TreeExpr(infix_op, NULL, root->right, NULL);
  return PROJECTM_SUCCESS;
}

/* Parses an infix operator */
GenExpr *
Parser::parse_infix_op(std::istream &  fs, token_t token, TreeExpr * tree_expr, MilkdropPreset * preset)
{
  GenExpr * gen_expr;

  switch (token)
  {
    /* All the infix operators */
  case tPlus:
    if (PARSE_DEBUG) printf("parse_infix_op: found addition operator (LINE %d)\n", line_count);
    if (PARSE_DEBUG) std::cerr << "WRAP AROUND IS " <<  tokenWrapAroundEnabled << std::endl;

    return parse_gen_expr(fs, insert_infix_op(Eval::infix_add, &tree_expr), preset);
  case tMinus:
    if (PARSE_DEBUG) printf("parse_infix_op: found subtraction operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_minus, &tree_expr), preset);
  case tMult:
    if (PARSE_DEBUG) printf("parse_infix_op: found multiplication operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_mult, &tree_expr), preset);
  case tDiv:
    if (PARSE_DEBUG) printf("parse_infix_op: found division operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_div, &tree_expr), preset);
  case tMod:
    if (PARSE_DEBUG) printf("parse_infix_op: found modulo operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_mod, &tree_expr), preset);
  case tOr:
    if (PARSE_DEBUG) printf("parse_infix_op: found bitwise or operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_or, &tree_expr), preset);
  case tAnd:
    if (PARSE_DEBUG) printf("parse_infix_op: found bitwise and operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_and, &tree_expr), preset);
  case tPositive:
    if (PARSE_DEBUG) printf("parse_infix_op: found positive operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_positive, &tree_expr), preset);
  case tNegative:
    if (PARSE_DEBUG) printf("parse_infix_op: found negative operator (LINE %d)\n", line_count);
    return parse_gen_expr(fs, insert_infix_op(Eval::infix_negative, &tree_expr), preset);

  case tEOL:
  case tEOF:
  case tSemiColon:
  case tRPr:
  case tComma:
    if (PARSE_DEBUG) printf("parse_infix_op: terminal found (LINE %d)\n", line_count);
    gen_expr = new GenExpr(TREE_T, (void*)tree_expr);
    assert(gen_expr);
    return gen_expr;
  default:
    if (PARSE_DEBUG) printf("parse_infix_op: operator or terminal expected, but not found (LINE %d)\n", line_count);
    delete tree_expr;
    return NULL;
  }

  /* Will never happen */
  return NULL;
}

/* Parses an integer, checks for +/- prefix */
int
Parser::parse_int(std::istream &  fs, int * int_ptr)
{
  char    string[MAX_TOKEN_SIZE];
  token_t token;
  int     sign;
  char    * end_ptr = (char*)" ";

  token = parseToken(fs, string);


  switch (token)
  {
  case tMinus:
    sign = -1;
    token = parseToken(fs, string);
    break;
  case tPlus:
    sign = 1;
    token = parseToken(fs, string);
    break;
  default:
    sign = 1;
    break;
  }


  if (string[0] == 0)
    return PROJECTM_PARSE_ERROR;

  /* Convert the string to an integer. *end_ptr
     should end up pointing to null terminator of 'string'
     if the conversion was successful. */
  //  printf("STRING: \"%s\"\n", string);

  (*int_ptr) = sign*strtol(string, &end_ptr, 10);

  /* If end pointer is a return character or null terminator, all is well */
  if ((*end_ptr == '\r') || (*end_ptr == '\0'))
    return PROJECTM_SUCCESS;

  return PROJECTM_PARSE_ERROR;
}

/* Parses a floating point number */
int
Parser::string_to_float(char * string, float * float_ptr)
{
  char ** error_ptr;

  if (*string == 0)
    return PROJECTM_PARSE_ERROR;

  error_ptr = (char**)wipemalloc(sizeof(char**));

  (*float_ptr) = strtod(string, error_ptr);

  /* These imply a succesful parse of the string */
  if ((**error_ptr == '\0') || (**error_ptr == '\r'))
  {
    free(error_ptr);
    error_ptr = NULL;
    return PROJECTM_SUCCESS;
  }

  (*float_ptr) = 0;
  free(error_ptr);
  error_ptr = NULL;
  return PROJECTM_PARSE_ERROR;
}

/* Parses a floating point number */
int
Parser::parse_float(std::istream &  fs, float * float_ptr)
{
  char    string[MAX_TOKEN_SIZE];
  char    ** error_ptr;
  token_t token;
  int     sign;

  error_ptr =(char**) wipemalloc(sizeof(char**));

  token = parseToken(fs, string);

  switch (token)
  {
  case tMinus:
    sign = -1;
    token = parseToken(fs, string);
    break;
  case tPlus:
    sign = 1;
    token = parseToken(fs, string);
    break;
  default:
    sign = 1;
  }

  if (string[0] == 0)
  {
    free(error_ptr);
    error_ptr = NULL;
    return PROJECTM_PARSE_ERROR;
  }

  (*float_ptr) = sign*strtod(string, error_ptr);

  /* No conversion was performed */
  if ((**error_ptr == '\0') || (**error_ptr == '\r'))
  {
    free(error_ptr);
    error_ptr = NULL;
    return PROJECTM_SUCCESS;
  }

  if (PARSE_DEBUG) printf("parse_float: float conversion failed for string \"%s\"\n", string);

  (*float_ptr) = 0;
  free(error_ptr);
  error_ptr = NULL;
  return PROJECTM_PARSE_ERROR;
}

/* Parses a per frame equation. That is, interprets a stream of data as a per frame equation */
PerFrameEqn *
Parser::parse_per_frame_eqn(std::istream &  fs, int index, MilkdropPreset * preset)
{
  char        string[MAX_TOKEN_SIZE];
  Param       * param;
  PerFrameEqn * per_frame_eqn;
  GenExpr     * gen_expr;


  if (parseToken(fs, string) != tEq)
  {
    if (PARSE_DEBUG) printf("parse_per_frame_eqn: no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
    return NULL;
  }

  /* Find the parameter associated with the string, create one if necessary */
  if ((param = ParamUtils::find(string, &preset->builtinParams, &preset->user_param_tree)) == NULL)
  {
    return NULL;
  }
  if (PARSE_DEBUG) std::cerr << "parse_per_frame_eqn: parameter \"" << param->name << "\" retrieved (LINE" << line_count << ")" << std::endl;
  /* Make sure parameter is writable */
  if (param->flags & P_FLAG_READONLY)
  {
    if (PARSE_DEBUG) std::cerr << "parse_per_frame_eqn: parameter \"" << param->name << "\" %s is marked as read only (LINE " << line_count << ")" << std::endl;
    return NULL;
  }

  /* Parse right side of equation as an expression */
  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_per_frame_eqn: equation evaluated to null (LINE %d)\n", line_count);
    return NULL;
  }

  if (PARSE_DEBUG) printf("parse_per_frame_eqn: finished per frame equation evaluation (LINE %d)\n", line_count);

  /* Create a new per frame equation */
  if ((per_frame_eqn = new PerFrameEqn(index, param, gen_expr)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_per_frame_eqn: failed to create a new per frame eqn, out of memory?\n");
    delete gen_expr;
    return NULL;
  }

  if (PARSE_DEBUG) printf("parse_per_frame_eqn: per_frame eqn parsed succesfully\n");

  return per_frame_eqn;
}

/* Parses an 'implicit' per frame equation. That is, interprets a stream of data as a per frame equation without a prefix */
PerFrameEqn *
Parser::parse_implicit_per_frame_eqn(std::istream &  fs, char * param_string, int index, MilkdropPreset * preset)
{
  Param       * param;
  PerFrameEqn * per_frame_eqn;
  GenExpr     * gen_expr;

  if (fs == NULL)
    return NULL;
  if (param_string == NULL)
    return NULL;
  if (preset == NULL)
    return NULL;

  //rintf("param string: %s\n", param_string);
  /* Find the parameter associated with the string, create one if necessary */
  if ((param = ParamUtils::find(param_string, &preset->builtinParams, &preset->user_param_tree)) == NULL)
  {
    return NULL;
  }

  //printf("parse_implicit_per_frame_eqn: param is %s\n", param->name);

  /* Make sure parameter is writable */
  if (param->flags & P_FLAG_READONLY)
  {
    if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: parameter %s is marked as read only (LINE %d)\n", param->name.c_str(), line_count);
    return NULL;
  }

  /* Parse right side of equation as an expression */
  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: equation evaluated to null (LINE %d)\n", line_count);
    return NULL;
  }

  if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: finished per frame equation evaluation (LINE %d)\n", line_count);

  /* Create a new per frame equation */
  if ((per_frame_eqn = new PerFrameEqn(index, param, gen_expr)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: failed to create a new per frame eqn, out of memory?\n");
    delete gen_expr;
    return NULL;
  }

  if (PARSE_DEBUG) printf("parse_implicit_per_frame_eqn: per_frame eqn parsed succesfully\n");

  return per_frame_eqn;
}

/* Parses an initial condition */
InitCond *
Parser::parse_init_cond(std::istream &  fs, char * name, MilkdropPreset * preset)
{
  Param     * param;
  CValue    init_val;
  InitCond  * init_cond;

  if (name == NULL)
    return NULL;
  if (preset == NULL)
    return NULL;

  /* Search for the paramater in the database, creating it if necessary */
  if ((param = ParamUtils::find(name, &preset->builtinParams, &preset->user_param_tree)) == NULL)
  {
    return NULL;
  }

  if (PARSE_DEBUG) printf("parse_init_cond: parameter = \"%s\" (LINE %d)\n", param->name.c_str(), line_count);

  if (param->flags & P_FLAG_READONLY)
  {
    if (PARSE_DEBUG) printf("parse_init_cond: builtin parameter \"%s\" marked as read only!\n", param->name.c_str());
    return NULL;
  }

  /* At this point, a parameter has been created or was found
  in the database. */

  if (PARSE_DEBUG) printf("parsed_init_cond: parsing initial condition value... (LINE %d)\n", line_count);

  /* integer value (boolean is an integer in C) */
  if ( (param->type == P_TYPE_BOOL))
  {
    int bool_test;
    if ((parse_int(fs, &bool_test)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_init_cond: error parsing integer!\n");
      return NULL;
    }
    init_val.bool_val = bool_test;
  }
  else if ((param->type == P_TYPE_INT))
  {
    if ((parse_int(fs, (int*)&init_val.int_val)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_init_cond: error parsing integer!\n");
      return NULL;
    }
  }
  /* float value */
  else if (param->type == P_TYPE_DOUBLE)
  {
    if ((parse_float(fs, (float*)&init_val.float_val)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_init_cond: error parsing float!\n");
      return NULL;
    }
  }
  /* Unknown value */
  else
  {
    if (PARSE_DEBUG) printf("parse_init_cond: unknown parameter type!\n");
    return NULL;
  }

  /* Create new initial condition */
  if ((init_cond = new InitCond(param, init_val)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_init_cond: new_init_cond failed!\n");
    return NULL;
  }

  /* Finished */
  return init_cond;
}


void
Parser::parse_string_block(std::istream &  fs, std::string * out_string)
{
  char    name[MAX_TOKEN_SIZE];
  token_t token;

  std::set<char> skipList;
  skipList.insert('`');
  readStringUntil(fs, out_string, false, skipList);

  //std::cout << "out_string:\n " << *out_string << "\n" << std::endl;
}

InitCond *
Parser::parse_per_frame_init_eqn(std::istream &  fs, MilkdropPreset * preset, std::map<std::string,Param*> * database)
{
  char      name[MAX_TOKEN_SIZE];
  Param     * param = NULL;
  CValue    init_val;
  InitCond  * init_cond;
  GenExpr   * gen_expr;
  float     val;
  token_t   token;


  if (preset == NULL)
    return NULL;
  if (fs == NULL)
    return NULL;

  if ((token = parseToken(fs, name)) != tEq)
    return NULL;


  /* If a database was specified,then use ParamUtils::find_db instead */
  if ((database != NULL) && ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(name, database)) == NULL))
  {
    return NULL;
  }

  /* Otherwise use the builtin parameter and user databases. This is confusing. Sorry. */
  if ((param == NULL) && ((param = ParamUtils::find(name, &preset->builtinParams, &preset->user_param_tree)) == NULL))
  {
    return NULL;
  }

  if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: parameter = \"%s\" (LINE %d)\n", param->name.c_str(), line_count);

  if (param->flags & P_FLAG_READONLY)
  {
    if (PARSE_DEBUG) printf("pars_per_frame_init_eqn: builtin parameter \"%s\" marked as read only!\n", param->name.c_str());
    return NULL;
  }

  /* At this point, a parameter has been created or was found
  in the database. */

  if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: parsing right hand side of per frame init equation.. (LINE %d)\n", line_count);

  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: failed to parse general expresion!\n");
    return NULL;
  }

  /* Compute initial condition value */
  val = gen_expr->eval_gen_expr(-1,-1);

  /* Free the general expression now that we are done with it */
  delete gen_expr;

  /* integer value (boolean is an integer in C) */
  if (param->type == P_TYPE_BOOL)
  {
    init_val.bool_val = (bool)val;
  }
  else if ((param->type == P_TYPE_INT))
  {
    init_val.int_val = (int)val;
  }
  /* float value */
  else if (param->type == P_TYPE_DOUBLE)
  {
    init_val.float_val = val;
  }
  /* Unknown value */
  else
  {
    if (PARSE_DEBUG) printf("pase_per_frame_init_eqn: unknown parameter type!\n");
    return NULL;
  }


  /* Create new initial condition */
  if ((init_cond = new InitCond(param, init_val)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_per_frame_init_eqn: new_init_cond failed!\n");
    return NULL;
  }

  init_cond->evaluate(true);

  /* Finished */
  return init_cond;
}

bool
Parser::scanForComment(std::istream & fs)
{
  int c;

  c = fs.get();

  if (c == '/') {
    while (true)
    {
      if (!fs || fs.eof())
        return true;
      else
        c = fs.get();
      if (c == EOF)
        return true;

      if (c == '\n')
      {
        return true;
      }
    }
  } else {
    fs.unget();
    return false;
  }
}

void
Parser::readStringUntil(std::istream & fs, std::string * out_buffer, bool wrapAround, const std::set<char> & skipList)
{
  int string_line_buffer_index = 0;
  int c;

  /* Loop until a delimiter is found, or the maximum string size is found */
  while (true)
  {
    if (!fs || fs.eof())
      c = EOF;
    else
      c = fs.get();

    /* Now interpret the character */
    switch (c)
    {
    case '/':
      {
        bool commentExisted = scanForComment(fs);

        if (!commentExisted) {
          out_buffer->push_back(c);
          break;
        } else {
          line_count++;
          return;
        }
      }
    case '\n':
      if (!out_buffer->empty() && ((*out_buffer)[out_buffer->length() -1] == '\n'))
        return;

      line_count++;
      if (wrapAround)
      {
        std::ostringstream buffer;

        //      if (PARSE_DEBUG) std::cerr << "token wrap! line " << line_count << std::endl;
        while (c != '=')
        {
          if (!fs || fs.eof())
          {
            line_count = 1;
            line_mode = UNSET_LINE_MODE;
            //          if (PARSE_DEBUG)     std::cerr << "token wrap: end of file" << std::endl;
            return;
          }
          else {
            c = fs.get();
            if ( c != '=')
              buffer << c;
          }
        }


        if (!wrapsToNextLine(buffer.str())) {
          wrapAround = false;
          int buf_size = (int)buffer.str().length();
          // <= to also remove equal sign parsing from stream
          for (int k = 0; k <= buf_size; k++) {
            if (fs)
              fs.unget();
            else
              abort();
          }
          return;
        }

        break;
      } else
        out_buffer->push_back(c);
      return;
    case EOF:
      line_count = 1;
      return;
    default:

      if (out_buffer != NULL)
      {
        if (skipList.find(c) == skipList.end())
          out_buffer->push_back(c);
      }
    }
  }
}

int
Parser::parse_wavecode(char * token, std::istream &  fs, MilkdropPreset * preset)
{
  char        * var_string;
  InitCond    * init_cond;
  CustomWave  * custom_wave;
  int         id;
  CValue      init_val;
  Param       * param;

  assert(preset);
  assert(fs);
  assert(token);

  /* token should be in the form wavecode_N_var, such as wavecode_1_samples */

  /* Get id and variable name from token string */
  if (parse_wavecode_prefix(token, &id, &var_string) < 0)
    return PROJECTM_PARSE_ERROR;

  last_custom_wave_id = id;

  if (PARSE_DEBUG) printf("parse_wavecode: wavecode id = %d, parameter = \"%s\"\n", id, var_string);

  /* Retrieve custom wave information from preset, allocating new one if necessary */
  if ((custom_wave = MilkdropPreset::find_custom_object(id, preset->customWaves)) == NULL)
  {
    std::cerr << "parse_wavecode: failed to load (or create) custom wave (id = "
              << id << ")!\n"
              << std::endl;

    return PROJECTM_FAILURE;
  }

  if (PARSE_DEBUG) printf("parse_wavecode: custom wave found (id = %d)\n", custom_wave->id);

  /* Retrieve parameter from this custom waves parameter db */
  if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(var_string,&custom_wave->param_tree)) == NULL)
    return PROJECTM_FAILURE;

  if (PARSE_DEBUG) printf("parse_wavecode: custom wave parameter found (name = %s)\n", param->name.c_str());

  /* integer value (boolean is an integer in C) */

  if ((param->type == P_TYPE_BOOL))
  {
    int bool_test;

    if ((parse_int(fs, &bool_test)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_wavecode: error parsing integer!\n");
      return PROJECTM_PARSE_ERROR;
    }
    init_val.bool_val = bool_test;
  }
  else if ((param->type == P_TYPE_INT))
  {
    if ((parse_int(fs, (int*)&init_val.int_val)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_wavecode: error parsing integer!\n");
      return PROJECTM_PARSE_ERROR;
    }
  }
  /* float value */
  else if (param->type == P_TYPE_DOUBLE)
  {
    if ((parse_float(fs, (float*)&init_val.float_val)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_wavecode: error parsing float!\n");
      return PROJECTM_PARSE_ERROR;
    }
  }
  /* Unknown value */
  else
  {
    if (PARSE_DEBUG) printf("parse_wavecode: unknown parameter type!\n");
    return PROJECTM_PARSE_ERROR;
  }

  /* Create new initial condition */
  init_cond = new InitCond(param, init_val);

  if (init_cond == NULL)
  {
    if (PARSE_DEBUG) printf("parse_wavecode: new_init_cond failed!\n");
    return PROJECTM_FAILURE;
  }

  std::pair<std::map<std::string, InitCond*>::iterator, bool> inserteePair =
      custom_wave->init_cond_tree.insert(std::make_pair(init_cond->param->name, init_cond));

  // assert(inserteePair.second);

  line_mode = CUSTOM_WAVE_WAVECODE_LINE_MODE;

  if (PARSE_DEBUG) printf("parse_wavecode: [success]\n");
  return PROJECTM_SUCCESS;
}

int
Parser::parse_shapecode(char * token, std::istream &  fs, MilkdropPreset * preset)
{

  char        * var_string;
  InitCond    * init_cond;
  CustomShape * custom_shape;
  int         id;
  CValue      init_val;
  Param       * param;

  /* Null argument checks */
  if (preset == NULL)
    return PROJECTM_FAILURE;
  if (fs == NULL)
    return PROJECTM_FAILURE;
  if (token == NULL)
    return PROJECTM_FAILURE;

  /* token should be in the form shapecode_N_var, such as shapecode_1_samples */

  /* Get id and variable name from token string */
  if (parse_shapecode_prefix(token, &id, &var_string) < 0)
    return PROJECTM_PARSE_ERROR;

  last_custom_shape_id = id;

  if (PARSE_DEBUG) printf("parse_shapecode: shapecode id = %d, parameter = \"%s\"\n", id, var_string);


  /* Retrieve custom shape information from preset. The 3rd argument
  if true creates a custom shape if one does not exist */

  if ((custom_shape = MilkdropPreset::find_custom_object(id,  preset->customShapes)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shapecode: failed to load (or create) custom shape (id = %d)!\n", id);
    return PROJECTM_FAILURE;
  }
  if (PARSE_DEBUG) printf("parse_shapecode: custom shape found (id = %d)\n", custom_shape->id);

  if ((param = ParamUtils::find<ParamUtils::NO_CREATE>(var_string, &custom_shape->text_properties_tree)) != NULL)
  {
    std::string text;//[MAX_TOKEN_SIZE];
    //token_t token = parseToken(fs, text);

    fs >> text;

    *((std::string*)param->engine_val) = text;
    if (PARSE_DEBUG)
      std::cerr << "parse_shapecode: found image url, text is \""
                << text << "\""
                << std::endl;

    return PROJECTM_SUCCESS;
  }

  /* Retrieve parameter from this custom shapes parameter db */


  if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(var_string, &custom_shape->param_tree)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shapecode: failed to create parameter.\n");
    return PROJECTM_FAILURE;
  }
  if (PARSE_DEBUG) printf("parse_shapecode: custom shape parameter found (name = %s)\n", param->name.c_str());

  /* integer value (boolean is an integer in C) */


  if ((param->type == P_TYPE_BOOL))
  {
    int bool_test;

    if ((parse_int(fs, &bool_test)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_shapecode: error parsing integer!\n");
      return PROJECTM_PARSE_ERROR;
    }
    init_val.bool_val = bool_test;
  }
  else if ((param->type == P_TYPE_INT))
  {
    if ((parse_int(fs, (int*)&init_val.int_val)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_shapecode: error parsing integer!\n");
      return PROJECTM_PARSE_ERROR;
    }
  }
  /* float value */
  else if (param->type == P_TYPE_DOUBLE)
  {
    if ((parse_float(fs, (float*)&init_val.float_val)) == PROJECTM_PARSE_ERROR)
    {
      if (PARSE_DEBUG) printf("parse_shapecode: error parsing float!\n");
      return PROJECTM_PARSE_ERROR;
    }
  }
  /* Unknown value */
  else
  {
    if (PARSE_DEBUG) printf("parse_shapecode: unknown parameter type!\n");
    return PROJECTM_PARSE_ERROR;
  }

  /* Create new initial condition */
  if ((init_cond = new InitCond(param, init_val)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shapecode: new_init_cond failed!\n");
    return PROJECTM_FAILURE;
  }

  custom_shape->init_cond_tree.insert(std::make_pair(param->name,init_cond));
  line_mode = CUSTOM_SHAPE_SHAPECODE_LINE_MODE;

  if (PARSE_DEBUG) printf("parse_shapecode: [success]\n");
  return PROJECTM_SUCCESS;
}


int
Parser::parse_wavecode_prefix(char * token, int * id, char ** var_string)
{
  int len, i, j;

  if (token == NULL)
    return PROJECTM_FAILURE;
  /*
  if (*var_string == NULL)
    return PROJECTM_FAILURE;
  */
  if (id == NULL)
    return PROJECTM_FAILURE;

  len = strlen(token);

  /* Move pointer passed "wavecode_" prefix */
  if (len <= WAVECODE_STRING_LENGTH)
    return PROJECTM_FAILURE;
  i = WAVECODE_STRING_LENGTH;
  j = 0;
  (*id) = 0;

  /* This loop grabs the integer id for this custom wave */
  while ((i < len) && (token[i] >=  48) && (token[i] <= 57))
  {
    if (j >= MAX_TOKEN_SIZE)
      return PROJECTM_FAILURE;

    (*id) = 10*(*id) + (token[i]-48);
    j++;
    i++;
  }


  if (i > (len - 2))
    return PROJECTM_FAILURE;

  *var_string = token + i + 1;

  return PROJECTM_SUCCESS;
}


int
Parser::parse_shapecode_prefix(char * token, int * id, char ** var_string)
{
  int len, i, j;

  if (token == NULL)
    return PROJECTM_FAILURE;
  /*
  if (*var_string == NULL)
    return PROJECTM_FAILURE;
  */
  if (id == NULL)
    return PROJECTM_FAILURE;

  len = strlen(token);

  /* Move pointer passed "shapecode_" prefix */
  if (len <= SHAPECODE_STRING_LENGTH)
    return PROJECTM_FAILURE;
  i = SHAPECODE_STRING_LENGTH;
  j = 0;
  (*id) = 0;

  /* This loop grabs the integer id for this custom shape */
  while ((i < len) && (token[i] >=  48) && (token[i] <= 57))
  {
    if (j >= MAX_TOKEN_SIZE)
      return PROJECTM_FAILURE;

    (*id) = 10*(*id) + (token[i]-48);
    j++;
    i++;
  }


  if (i > (len - 2))
    return PROJECTM_FAILURE;

  *var_string = token + i + 1;

  return PROJECTM_SUCCESS;
}

int
Parser::parse_wave_prefix(char * token, int * id, char ** eqn_string)
{
  int len, i, j;

  if (token == NULL)
    return PROJECTM_FAILURE;
  if (eqn_string == NULL)
    return PROJECTM_FAILURE;
  if (id == NULL)
    return PROJECTM_FAILURE;

  len = strlen(token);

  if (len <= WAVE_STRING_LENGTH)
    return PROJECTM_FAILURE;


  i = WAVE_STRING_LENGTH;
  j = 0;
  (*id) = 0;

  /* This loop grabs the integer id for this custom wave */
  while ((i < len) && (token[i] >=  48) && (token[i] <= 57))
  {
    if (j >= MAX_TOKEN_SIZE)
      return PROJECTM_FAILURE;

    (*id) = 10*(*id) + (token[i]-48);
    j++;
    i++;
  }

  if (i > (len - 2))
    return PROJECTM_FAILURE;

  *eqn_string = token + i + 1;

  if (PARSE_DEBUG) printf("parse_wave_prefix: prefix = %s\n (LINE %d)", *eqn_string, line_count);
  return PROJECTM_SUCCESS;
}

int
Parser::parse_shape_prefix(char * token, int * id, char ** eqn_string)
{
  int len, i, j;

  if (token == NULL)
    return PROJECTM_FAILURE;
  if (eqn_string == NULL)
    return PROJECTM_FAILURE;
  if (id == NULL)
    return PROJECTM_FAILURE;

  len = strlen(token);

  if (len <= SHAPE_STRING_LENGTH)
    return PROJECTM_FAILURE;


  i = SHAPE_STRING_LENGTH;
  j = 0;
  (*id) = 0;

  /* This loop grabs the integer id for this custom wave */
  while ((i < len) && (token[i] >=  48) && (token[i] <= 57))
  {
    if (j >= MAX_TOKEN_SIZE)
      return PROJECTM_FAILURE;

    (*id) = 10*(*id) + (token[i]-48);
    j++;
    i++;
  }

  if (i > (len - 2))
    return PROJECTM_FAILURE;

  *eqn_string = token + i + 1;

  return PROJECTM_SUCCESS;
}

/* Parses custom wave equations */
int
Parser::parse_wave(char * token, std::istream &  fs, MilkdropPreset * preset)
{
  int   id;
  char  * eqn_type;

  if (PARSE_DEBUG) printf("parse_wave:begin\n");

  if (token == NULL)
    return PROJECTM_FAILURE;
  if (fs == NULL)
    return PROJECTM_FAILURE;
  if (preset == NULL)
    return PROJECTM_FAILURE;

  /* Grab custom wave id and equation type (per frame or per point) from string token */
  if (parse_wave_prefix(token, &id, &eqn_type) < 0)
  {
    if (PARSE_DEBUG) printf("parse_wave: syntax error in custom wave prefix!\n");
    return PROJECTM_FAILURE;
  }

  strncpy(last_eqn_type, eqn_type, MAX_TOKEN_SIZE);

  return parse_wave_helper(fs, preset, id, eqn_type, 0);
}

int
Parser::parse_wave_helper(std::istream &  fs, MilkdropPreset  * preset, int id, char * eqn_type, char * init_string)
{
  Param       * param;
  GenExpr     * gen_expr;
  char        string[MAX_TOKEN_SIZE];
  PerFrameEqn * per_frame_eqn;
  CustomWave  * custom_wave;
  InitCond    * init_cond;

  /* Retrieve custom wave associated with this id */
  if ((custom_wave = MilkdropPreset::find_custom_object(id,  preset->customWaves)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_wave_helper: custom wave id %d not found!\n", id);
    return PROJECTM_FAILURE;
  }

  /* per frame init equation case */
  if (!strncmp(eqn_type, WAVE_INIT_STRING, WAVE_INIT_STRING_LENGTH))
  {
    if (PARSE_DEBUG) printf("parse_wave_helper (per frame init): [begin] (LINE %d)\n", line_count);

    /* Parse the per frame init equation */
    if ((init_cond = parse_per_frame_init_eqn(fs, preset, &custom_wave->param_tree)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_wave_helper (per frame init): equation parsing failed (LINE %d)\n", line_count);
      return PROJECTM_PARSE_ERROR;
    }

    /* Insert the equation in the per frame equation tree */
    custom_wave->per_frame_init_eqn_tree.insert(std::make_pair(init_cond->param->name,init_cond));

    line_mode = CUSTOM_WAVE_PER_FRAME_INIT_LINE_MODE;
    init_cond->evaluate(true);
    return PROJECTM_SUCCESS;
  }

  /* per frame equation case */
  if (!strncmp(eqn_type, PER_FRAME_STRING_NO_UNDERSCORE, PER_FRAME_STRING_NO_UNDERSCORE_LENGTH))
  {
    if (PARSE_DEBUG) printf("parse_wave_helper (per_frame): [start] (custom wave id = %d)\n", custom_wave->id);

    if (parseToken(fs, string) != tEq)
    {
      if (PARSE_DEBUG) printf("parse_wave (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
      return PROJECTM_PARSE_ERROR;
    }

    /* Find the parameter associated with the string in the custom wave database */
    if ((param =  ParamUtils::find<ParamUtils::AUTO_CREATE>(string, &custom_wave->param_tree)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter \"%s\" not found or cannot be wipemalloc'ed!!\n", string);
      return PROJECTM_FAILURE;
    }


    /* Make sure parameter is writable */
    if (param->flags & P_FLAG_READONLY)
    {
      if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name.c_str(), line_count);
      return PROJECTM_FAILURE;
    }

    /* Parse right side of equation as an expression */

    current_wave = custom_wave;
    if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_wave (per_frame): equation evaluated to null (LINE %d)\n", line_count);
      current_wave = NULL;
      return PROJECTM_PARSE_ERROR;

    }

    current_wave = NULL;

    if (PARSE_DEBUG) printf("parse_wave (per_frame): [finished parsing equation] (LINE %d)\n", line_count);

    /* Create a new per frame equation */
    if ((per_frame_eqn = new PerFrameEqn(custom_wave->per_frame_count++, param, gen_expr)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_wave (per_frame): failed to create a new per frame eqn, out of memory?\n");
      delete gen_expr;
      return PROJECTM_FAILURE;
    }

    custom_wave->per_frame_eqn_tree.push_back(per_frame_eqn);
    if (PARSE_DEBUG) printf("parse_wave (per_frame): equation %d associated with custom wave %d [success]\n",
                            per_frame_eqn->index, custom_wave->id);


    /* Need to add stuff to string buffer so the editor can read the equations.
    Why not make a nice little helper function for this? - here it is: */

    line_mode = CUSTOM_WAVE_PER_FRAME_LINE_MODE;
    return PROJECTM_SUCCESS;
  }


  /* per point equation case */
  if (!strncmp(eqn_type, PER_POINT_STRING, PER_POINT_STRING_LENGTH))
  {
    if (PARSE_DEBUG) printf("parse_wave_helper (per_point): per_pixel equation parsing start...(LINE %d)\n", line_count);

    /// HACK the parse_line code already parsed the per_pixel variable name. This handles that case
    /// Parser needs reworked. Don't have time for it. So this is the result.
    if (init_string)
      strncpy(string, init_string, strlen(init_string)+1);
    else
    {
      if (parseToken(fs, string) != tEq)
      { /* parse per pixel operator  name */
        if (PARSE_DEBUG) printf("parse_wave_helper (per_point): equal operator missing after per pixel operator. Last token = \"%s\"  (LINE %d)\n", string, line_count);

        return PROJECTM_PARSE_ERROR;
      }
    }

    /* Parse right side of equation as an expression, First tell parser we are parsing a custom wave */
    current_wave = custom_wave;
    if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
    {
      if (PARSE_DEBUG) printf("parse_wave_helper (per_point): equation evaluated to null? (LINE %d)\n", line_count);

      return PROJECTM_PARSE_ERROR;
    }


    /* Add the per point equation */
    if (custom_wave->add_per_point_eqn(string, gen_expr) < 0)
    {
      delete gen_expr;

      return PROJECTM_PARSE_ERROR;
    }
    // This tells the parser we are no longer parsing a custom wave
    current_wave = NULL;



    line_mode = CUSTOM_WAVE_PER_POINT_LINE_MODE;
    if (PARSE_DEBUG) printf("parse_wave_helper (per_point): [finished] (custom wave id = %d)\n", custom_wave->id);
    return PROJECTM_SUCCESS;
  }

  return PROJECTM_FAILURE;
}

/* Parses custom shape equations */
int
Parser::parse_shape(char * token, std::istream &  fs, MilkdropPreset * preset)
{
  int         id;
  char        * eqn_type;
  CustomShape * custom_shape;


  if (token == NULL)
    return PROJECTM_FAILURE;
  if (fs == NULL)
    return PROJECTM_FAILURE;
  if (preset == NULL)
    return PROJECTM_FAILURE;

  /* Grab custom shape id and equation type (per frame or per point) from string token */
  if (parse_shape_prefix(token, &id, &eqn_type) < 0)
  {
    if (PARSE_DEBUG) printf("parse_shape: syntax error in custom shape prefix!\n");
    return PROJECTM_PARSE_ERROR;
  }

  /* Retrieve custom shape associated with this id */
  if ((custom_shape = MilkdropPreset::find_custom_object(id,preset->customShapes)) == NULL)
    return PROJECTM_FAILURE;


  /* per frame init equation case */
  if (!strncmp(eqn_type, SHAPE_INIT_STRING, SHAPE_INIT_STRING_LENGTH))
  {
    return parse_shape_per_frame_init_eqn(fs, custom_shape, preset);
  }

  /* per frame equation case */
  if (!strncmp(eqn_type, PER_FRAME_STRING_NO_UNDERSCORE, PER_FRAME_STRING_NO_UNDERSCORE_LENGTH))
  {
    return parse_shape_per_frame_eqn(fs, custom_shape, preset);
  }


  /* Syntax error, return parse error */
  return PROJECTM_PARSE_ERROR;
}

/* Helper function to update the string buffers used by the editor */



/* Helper function: returns the length of the prefix portion in the line
   buffer (the passed string here). In other words, given
   the string 'per_frame_1 = x = ....', return the length of 'per_frame_1 = '
   Returns -1 if syntax error
*/

int
Parser::get_string_prefix_len(char * string)
{
  int i = 0;

  /* Null argument check */
  if (string == NULL)
    return PROJECTM_FAILURE;

  /* First find the equal sign */
  while (string[i] != '=')
  {
    if (string[i] == 0)
      return PROJECTM_FAILURE;
    i++;
  }

  /* If the string already ends at the next char then give up */
  if (string[i+1] == 0)
    return PROJECTM_FAILURE;

  /* Move past the equal sign */
  i++;

  /* Now found the start of the LHS variable, ie skip the spaces */
  while(string[i] == ' ')
  {
    i++;
  }

  /* If this is the end of the string then its a syntax error */
  if (string[i] == 0)
    return PROJECTM_FAILURE;

  /* Finished successfully, return the length */
  return i;
}

int
Parser::parse_shape_per_frame_init_eqn(std::istream &  fs, CustomShape * custom_shape, MilkdropPreset * preset)
{
  InitCond * init_cond;

  if (PARSE_DEBUG) printf("parse_shape (per frame init): [begin] (LINE %d)\n", line_count);

  /* Parse the per frame equation */
  if ((init_cond = parse_per_frame_init_eqn(fs, preset, &custom_shape->param_tree)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shape (per frame init): equation parsing failed (LINE %d)\n", line_count);
    return PROJECTM_PARSE_ERROR;
  }

  /// \idea possibly a good place to update a string buffer;

  line_mode = CUSTOM_SHAPE_PER_FRAME_INIT_LINE_MODE;
  init_cond->evaluate(true);
  return PROJECTM_SUCCESS;
}

int
Parser::parse_shape_per_frame_eqn(std::istream & fs, CustomShape * custom_shape, MilkdropPreset * preset)
{
  Param       * param;
  GenExpr     * gen_expr;
  PerFrameEqn * per_frame_eqn;

  char string[MAX_TOKEN_SIZE];

  if (PARSE_DEBUG) printf("parse_shape (per_frame): [start] (custom shape id = %d)\n", custom_shape->id);

  if (parseToken(fs, string) != tEq)
  {
    if (PARSE_DEBUG) printf("parse_shape (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
    return PROJECTM_PARSE_ERROR;
  }

  /* Find the parameter associated with the string in the custom shape database */
  if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(string, &custom_shape->param_tree)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shape (per_frame): parameter \"%s\" not found or cannot be wipemalloc'ed!!\n", string);
    return PROJECTM_FAILURE;
  }


  /* Make sure parameter is writable */
  if (param->flags & P_FLAG_READONLY)
  {
    if (PARSE_DEBUG) printf("parse_shape (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name.c_str(), line_count);
    return PROJECTM_PARSE_ERROR;
  }

  /* Parse right side of equation as an expression */

  current_shape = custom_shape;
  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shape (per_frame): equation evaluated to null (LINE %d)\n", line_count);
    current_shape = NULL;
    return PROJECTM_PARSE_ERROR;
  }

  current_shape = NULL;

  if (PARSE_DEBUG) printf("parse_shape (per_frame): [finished parsing equation] (LINE %d)\n", line_count);

  /* Create a new per frame equation */
  if ((per_frame_eqn = new PerFrameEqn(custom_shape->per_frame_count++, param, gen_expr)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_shape (per_frame): failed to create a new per frame eqn, out of memory?\n");
    delete gen_expr;
    return PROJECTM_FAILURE;
  }

  custom_shape->per_frame_eqn_tree.push_back(per_frame_eqn);

  /// \idea add string buffer update for easy >> and <<

  line_mode = CUSTOM_SHAPE_PER_FRAME_LINE_MODE;
  return PROJECTM_SUCCESS;
}

int
Parser::parse_wave_per_frame_eqn(std::istream &  fs, CustomWave * custom_wave, MilkdropPreset * preset)
{
  Param       * param;
  GenExpr     * gen_expr;
  PerFrameEqn * per_frame_eqn;

  char string[MAX_TOKEN_SIZE];

  if (PARSE_DEBUG) printf("parse_wave (per_frame): [start] (custom shape id = %d)\n", custom_wave->id);

  if (parseToken(fs, string) != tEq)
  {
    if (PARSE_DEBUG) printf("parse_wave (per_frame): no equal sign after string \"%s\" (LINE %d)\n", string, line_count);
    return PROJECTM_PARSE_ERROR;
  }

  /* Find the parameter associated with the string in the custom shape database */
  if ((param = ParamUtils::find<ParamUtils::AUTO_CREATE>(string, &custom_wave->param_tree)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter \"%s\" not found or cannot be wipemalloc'ed!!\n", string);
    return PROJECTM_FAILURE;
  }


  /* Make sure parameter is writable */
  if (param->flags & P_FLAG_READONLY)
  {
    if (PARSE_DEBUG) printf("parse_wave (per_frame): parameter %s is marked as read only (LINE %d)\n", param->name.c_str(), line_count);
    return PROJECTM_FAILURE;
  }

  /* Parse right side of equation as an expression */

  current_wave = custom_wave;
  if ((gen_expr = parse_gen_expr(fs, NULL, preset)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_wave (per_frame): equation evaluated to null (LINE %d)\n", line_count);
    current_wave = NULL;
    return PROJECTM_PARSE_ERROR;
  }

  current_wave = NULL;

  if (PARSE_DEBUG) printf("parse_wave (per_frame): [finished parsing equation] (LINE %d)\n", line_count);

  /* Create a new per frame equation */
  if ((per_frame_eqn = new PerFrameEqn(custom_wave->per_frame_count++, param, gen_expr)) == NULL)
  {
    if (PARSE_DEBUG) printf("parse_wave (per_frame): failed to create a new per frame eqn, out of memory?\n");
    delete gen_expr;
    return PROJECTM_FAILURE;
  }

  custom_wave->per_frame_eqn_tree.push_back(per_frame_eqn);
  if (PARSE_DEBUG) printf("parse_wave (per_frame): equation %d associated with custom wave %d [success]\n",
                          per_frame_eqn->index, custom_wave->id);


  /* Need to add stuff to string buffer so the editor can read the equations.
  Why not make a nice little helper function for this? - here it is: */

  line_mode = CUSTOM_WAVE_PER_FRAME_LINE_MODE;
  return PROJECTM_SUCCESS;
}


bool
Parser::wrapsToNextLine(const std::string & str)
{
  std::size_t lastLineEndIndex = lastLinePrefix.find_last_not_of("0123456789");
  std::size_t thisLineEndIndex = str.find_last_not_of("0123456789");
  std::size_t startIndex = 0;

  if ((str.compare(startIndex, lastLineEndIndex, lastLinePrefix.c_str(), thisLineEndIndex)) == 0)
    return true;
  else
    return false;
}
