/* RTFParser.java --
   Copyright (C) 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing.text.rtf;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

/**
 * Parses an RTF file into a {@link Document}. The parser utilizes
 * {@link RTFScanner}.
 *
 * @author Roman Kennke (roman@ontographics.com)
 */
class RTFParser
{

  /**
   * Our scanner.
   */
  private RTFScanner scanner;

  /**
   * The document into which we parse.
   */
  private Document doc;

  /**
   * The current position.
   */
  private int pos;

  /**
   * Constructs a new RTFParser for the specified document and position,
   * without initializing the scanner. This is only used internally.
   *
   * @param doc the {@link Document} into which we should parse
   * @param pos the position to start
   */
  private RTFParser(Document doc, int pos)
  {
    this.doc = doc;
    this.pos = pos;
  }

  /**
   * Constructs a new RTFParser for the specified <code>stream</code>.
   *
   * @param stream the stream from which we parse
   * @param doc the {@link Document} into which we should parse
   * @param pos the position to start
   */
  public RTFParser(InputStream stream, Document doc, int pos)
  {
    this(doc, pos);
    scanner = new RTFScanner(stream);
  }

  /**
   * Constructs a new RTFParser for the specified <code>reader</code>.
   *
   * @param reader the reader from which we parse
   * @param doc the {@link Document} into which we should parse
   * @param pos the position to start
   */
  public RTFParser(Reader reader, Document doc, int pos)
  {
    this(doc, pos);
    scanner = new RTFScanner(reader);
  }

  /**
   * Returns the {@link Document} in which we parsed the RTF data.
   *
   * @return the {@link Document} in which we parsed the RTF data
   */
  public Document getDocument()
  {
    return doc;
  }

  /**
   * Starts the parsing process.
   */
  public void parse()
    throws IOException, BadLocationException
  {
    parseFile();
  }

  /**
   * The parse rules for &lt;file&gt;.
   */
  private void parseFile()
    throws IOException, BadLocationException
  {
    Token t1 = scanner.readToken();
    if (t1.type != Token.LCURLY)
      throw new RTFParseException("expected left curly braces");

    parseHeader();
    parseDocument();
  
    Token t2 = scanner.peekToken();
    if (t2.type == Token.RCURLY)
      {
        // Eat the token.
        scanner.readToken();
      }
    else
      {
        // Ignore this for maximum robustness when file is broken.
        System.err.println("RTF warning: expected right curly braces");
      }

  }

  /**
   * The parse rules for &lt;header&gt;.
   *
   * TODO: implement this properly
   */
  private void parseHeader()
  //throws IOException, BadLocationException
  {
    // TODO add parse rules here
  }


  /**
   * The parse rules for &lt;document&gt;.
   *
   * TODO: implement this properly
   */
  private void parseDocument()
    throws IOException, BadLocationException
  {
    //  !!! TODO !!!
    // This simply emits every TEXT Token as text to the document
    // which is plain stupid

    boolean eof = false;

    do {
      Token token = scanner.readToken();
      switch (token.type)
        {
        case Token.TEXT:
          TextToken textToken = (TextToken) token;
          doc.insertString(pos, textToken.text, null);
          pos += textToken.text.length();
          break;
        case Token.EOF:
          eof = true;
          break;
        default:
          // FIXME
          break;
        }
    } while (!eof);

  }

}
