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

}
