package tcra.math;

import java.util.Vector;

/**
 * MathStringParser is used to parse a StringBuilder for one
 * single list.
 */
public class MathStringParser extends MathTypeParser
{
   private MathTypeParser elementParser;
   
   /**
    * Constructor specifying the parser to use to parse the elements
    * of the string.
    *
    * @param subParser MathTypeParser used to parse the elements of
    *                  the string.
    */
   public MathStringParser(MathTypeParser subParser)
   {
      elementParser = subParser;
   } // end ctor
   
   /**
    * Destructively parses the StringBuilder provided for a single
    * list of elements. The elements of the string are parsed by
    * their own specific type of MathTypeParser (ergo the Strategy
    * pattern).
    *
    * @param input       StringBuilder to be parsed.
    * @return MathString if parse completed successfully.
    *         <code>null</code> otherwise.
    * @throws MathFormatException If some error in the input is
    *                             encountered.
    */
   public MathString<MathType> parse(StringBuilder input)
      throws MathFormatException
   {
      // remove leading whitespace
      eatWhitespace(input);

      /* verify that we have a '<' at the beginning
       * if so, remove it and continue; if not, return null
       */
      if(input.length() == 0 || input.charAt(0) != '<')
         return null;
      
      input.deleteCharAt(0);

      /* Process the string and save the entries
       * save entry in vector
       * remove whitespace after retrieving an entry
       * check for ',', if there is one: parse another entry
       * if there is a '>', we are done
       * anything else is an error
       */
      Vector<MathType> entries = new Vector<MathType>();
      MathType temp = null;
      try   { temp = elementParser.parse(input); }
      catch (MathFormatException mfe) { throw mfe; }

      if(temp != null)
      {
    	  entries.add(temp);
    	  eatWhitespace(input);
    	  
    	  while(input.length() > 0 && input.charAt(0) == ',')
    	  {
    		  input.deleteCharAt(0);
    		  try   { temp = elementParser.parse(input); }
    	      catch (MathFormatException mfe) { throw mfe; }
    	      
    	      if(temp == null)
    	    	 throw new MathFormatException(
                           "Missing element or erronious ',' found.");
    	      entries.add(temp);
    	      eatWhitespace(input);
    	  } // end while
      } // end if
      // if the first element is null, then we have an empty string
      if(input.length() > 0 && input.charAt(0) == '>')
         return new MathString<MathType>(entries,this);
      throw new MathFormatException("String parse error.");
   } // end parse(StringBuilder)
} // end class
