/* RTFScanner.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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;

/**
 * Provides a scanner that scans an {@link InputStream} for tokens of the
 * RTF syntax.
 *
 * This scanner is based upon the RTF specification 1.6
 * available at:
 *
 * <a
 * href="http://msdn.microsoft.com/library/en-us/dnrtfspec/html/rtfspec.asp">
 * RTF specification at MSDN</a>
 *
 * @author Roman Kennke (roman@ontographics.com)
 */
class RTFScanner
{

  /**
   * The reader from which we read the RTF data.
   */
  private Reader in;

  /**
   * This is used to constuct strings from the read in chars.
   */
  private StringBuffer buffer;

  /**
   * Lookahead token.
   */
  private Token lastToken;

  /**
   * Constructs a new RTFScanner without initializing the {@link Reader}.
   */
  private RTFScanner()
  {
    buffer = new StringBuffer();
  }

  /**
   * Constructs a new RTFScanner for the given {@link InputStream}.
   * The stream is wrapped into an {@link InputStreamReader} and if it's
   * not yet buffered then the Reader is wrapped in a {@link BufferedReader}
   *
   * @param stream the {@link InputStream} to read RTF data from
   */
  public RTFScanner(InputStream stream)
  {
    this();
    InputStreamReader reader = new InputStreamReader(stream);
    in = new BufferedReader(reader);
  }

  /**
   * Constructs a new RTFScanner for the given {@link Reader}.
   *
   * If the reader is not an instance of {@link BufferedReader} then it
   * is wrapped into a BufferedReader.
   *
   * @param reader the {@link BufferedReader} to read RTF data from
   */
  public RTFScanner(Reader reader)
  {
    this();
    if (reader instanceof BufferedReader)
      {
        in = reader;
      }
    else
      {
        in = new BufferedReader(reader);
      }
  }

  /**
   * Reads in the next {@link Token} from the stream.
   *
   * @return the read {@link Token}
   *
   * @throws IOException if the underlying stream has problems
   */
  private Token readTokenImpl()
    throws IOException
  {
    Token token = null;

    int c = in.read();
    switch(c)
      {
      case -1:
        token = new Token(Token.EOF);
        break;

      case '{':
        token = new Token(Token.LCURLY);
        break;

      case '}':
        token = new Token(Token.RCURLY);
        break;

      case '\\':
        buffer.delete(0, buffer.length());
        buffer.append((char) c);
        token = readControlWord();
        break;

      default:
        buffer.delete(0, buffer.length());
        buffer.append((char) c);
        token = readText();
        break;
      }

    return token;
  }

  Token peekToken()
    throws IOException
  {
    lastToken = readTokenImpl();
    return lastToken;
  }

  Token readToken()
    throws IOException
  {
    Token token;
    if (lastToken != null)
      {
        token = lastToken;
        lastToken = null;
      }
    else
      token = readTokenImpl();
    return token;
  }

  /**
   * Reads in a control word and optional parameter.
   *
   * @return the read in control word as {@link ControlWordToken}
   *
   * @throws IOException if the underlying stream has problems
   */
  private Token readControlWord()
    throws IOException
  {
    // this flag indicates if we are still reading the name or are already
    // in the parameter
    boolean readingName = true;
    String name = null;
    String param = null;

    while (true)
      {
        in.mark(1);
        int c = in.read();

        // check for 'a'..'z'
        if (readingName && (c >= 'a') && (c <= 'z'))
          {
            buffer.append((char) c);
          }
        else if ((c >= '0') && (c <= '9'))
          {
            // if the last char was in the name, then finish reading the name
            if (readingName)
              {
                name = buffer.toString();
                buffer.delete(0, buffer.length());
                readingName = false;
              }
            buffer.append((char) c);
          }
        else
          {
            // if we were in the name, then finish this
            if (readingName)
              {
                name = buffer.toString();
              }
            // otherwise finish the parameter
            else
              {
                param = buffer.toString();
              }

            // clear up
            buffer.delete(0, buffer.length());
            // reset input buffer to last char
            in.reset();
            // break while loop
            break;
          }
      }

    ControlWordToken token = null;

    if (param == null)
      token = new ControlWordToken(name);
    else
      token =new ControlWordToken(name, Integer.parseInt(param));

    return token;

  }

  /**
   * Reads in a block of text.
   *
   * @return the token for the text
   */
  private Token readText()
    throws IOException
  {

    boolean readingText = true;
    while (readingText)
      {
        in.mark(1);
        int c = in.read();
        switch(c)
          {
          case '\\':
          case '{':
          case '}':
          case -1:
            readingText = false;
            in.reset();
            break;

          default:
            buffer.append((char) c);
            break;
          }

      }

    String text = buffer.toString();
    Token token = new TextToken(text);

    buffer.delete(0, buffer.length());

    return token;

  }
}
