/* CSSParser.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.html;

import java.io.*;

/**
 * Parses a CSS document. This works by way of a delegate that implements the
 * CSSParserCallback interface. The delegate is notified of the following
 * events:
 * - Import statement: handleImport
 * - Selectors handleSelector. This is invoked for each string. For example if
 * the Reader contained p, bar , a {}, the delegate would be notified 4 times,
 * for 'p,' 'bar' ',' and 'a'.
 * - When a rule starts, startRule
 * - Properties in the rule via the handleProperty. This
 * is invoked one per property/value key, eg font size: foo;, would cause the
 * delegate to be notified once with a value of 'font size'.
 * - Values in the rule via the handleValue, this is notified for the total value.
 * - When a rule ends, endRule
 *
 * @author Lillian Angel (langel@redhat.com)
 */
class CSSParser
{

  /**
   * Receives all information about the CSS document structure while parsing it.
   * The methods are invoked by parser.
   */
  static interface CSSParserCallback
  {
    /**
     * Handles the import statment in the document.
     *
     * @param imp - the import string
     */
    public abstract void handleImport(String imp);

    /**
     * Called when the start of a rule is encountered.
     */
    public abstract void startRule();

    /**
     * Called when the end of a rule is encountered.
     */
    public abstract void endRule();

    /**
     * Handles the selector of a rule.
     *
     * @param selector - the selector in the rule
     */
    public abstract void handleSelector(String selector);

    /**
     * Handles the properties in the document.
     *
     * @param property - the property in the document.
     */
    public abstract void handleProperty(String property);

    /**
     * Handles the values in the document.
     *
     * @param value - the value to handle.
     */
    public abstract void handleValue(String value);

  }

  /**
   * The identifier of the rule.
   */
  private static final int IDENTIFIER = 1;

  /**
   * The open bracket.
   */
  private static final int BRACKET_OPEN = 2;

  /**
   * The close bracket.
   */
  private static final int BRACKET_CLOSE = 3;

  /**
   * The open brace.
   */
  private static final int BRACE_OPEN = 4;

  /**
   * The close brace.
   */
  private static final int BRACE_CLOSE = 5;

  /**
   * The open parentheses.
   */
  private static final int PAREN_OPEN = 6;

  /**
   * The close parentheses.
   */
  private static final int PAREN_CLOSE = 7;

  /**
   * The end of the document.
   */
  private static final int END = -1;

  /**
   * The character mapping in the document.
   */
  // FIXME: What is this used for?
  private static final char[] charMapping = null;

  /**
   * Set to true if one character has been read ahead.
   */
  private boolean didPushChar;

  /**
   * The read ahead character.
   */
  private int pushedChar;

  /**
   * Used to indicate blocks.
   */
  private int[] unitStack;

  /**
   * Number of valid blocks.
   */
  private int stackCount;

  /**
   * Holds the incoming CSS rules.
   */
  private Reader reader;

  /**
   * Set to true when the first non @ rule is encountered.
   */
  private boolean encounteredRuleSet;

  /**
   * The call back used to parse.
   */
  private CSSParser.CSSParserCallback callback;

  /**
   * nextToken() inserts the string here.
   */
  private char[] tokenBuffer;

  /**
   * Current number of chars in tokenBufferLength.
   */
  private int tokenBufferLength;

  /**
   * Set to true if any whitespace is read.
   */
  private boolean readWS;

  /**
   * Constructor
   */
  CSSParser()
  {
    tokenBuffer = new char[10];
  }

  /**
   * Appends a character to the token buffer.
   *
   * @param c - the character to append
   */
  private void append(char c)
  {
    if (tokenBuffer.length >= tokenBufferLength)
      {
        char[] temp = new char[tokenBufferLength * 2];
        if (tokenBuffer != null)
          System.arraycopy(tokenBuffer, 0, temp, 0, tokenBufferLength);

        temp[tokenBufferLength] = c;
        tokenBuffer = temp;
      }
    else
      tokenBuffer[tokenBufferLength] = c;
    tokenBufferLength++;
  }

  /**
   * Fetches the next token.
   *
   * @param c - the character to fetch.
   * @return the location
   * @throws IOException - any i/o error encountered while reading
   */
  private int nextToken(char c) throws IOException
  {
    readWS = false;
    int next = readWS();

    switch (next)
      {
      case '\"':
        if (tokenBufferLength > 0)
          tokenBufferLength--;
        return IDENTIFIER;
      case '\'':
        if (tokenBufferLength > 0)
          tokenBufferLength--;
        return IDENTIFIER;
      case '(':
        return PAREN_OPEN;
      case ')':
        return PAREN_CLOSE;
      case '{':
        return BRACE_OPEN;
      case '}':
        return BRACE_CLOSE;
      case '[':
        return BRACKET_OPEN;
      case ']':
        return BRACKET_CLOSE;
      case -1:
        return END;
      default:
        pushChar(next);
        getIdentifier(c);
        return IDENTIFIER;
      }
  }

  /**
   * Reads a character from the stream.
   *
   * @return the number of characters read or -1 if end of stream is reached.
   * @throws IOException - any i/o encountered while reading
   */
  private int readChar() throws IOException
  {
    if (didPushChar)
      {
        didPushChar = false;
        return pushedChar;
      }
    return reader.read();
  }

  /**
   * Parses the the contents of the reader using the
   * callback.
   *
   * @param reader - the reader to read from
   * @param callback - the callback instance
   * @param parsingDeclaration - true if parsing a declaration
   * @throws IOException - any i/o error from the reader
   */
  void parse(Reader reader, CSSParser.CSSParserCallback callback,
             boolean parsingDeclaration)
      throws IOException
  {
    this.reader = reader;
    this.callback = callback;

    try
    {
      if (!parsingDeclaration)
        while(getNextStatement())
          ;
      else
        parseDeclarationBlock();
    }
    catch (IOException ioe)
    {
      // Nothing to do here.
    }
  }

  /**
   * Skips any white space, returning the character after the white space.
   *
   * @return the character after the whitespace
   * @throws IOException - any i/o error from the reader
   */
  private int readWS() throws IOException
  {
    int next = readChar();
    while (Character.isWhitespace((char) next))
      {
        readWS = true;
        int tempNext = readChar();
        if (tempNext == END)
          return next;
        next = tempNext;
      }

    // Its all whitespace
    return END;
  }

  /**
   * Gets the next statement, returning false if the end is reached.
   * A statement is either an At-rule, or a ruleset.
   *
   * @return false if the end is reached
   * @throws IOException - any i/o error from the reader
   */
  private boolean getNextStatement() throws IOException
  {
    int c = nextToken((char) 0);
    switch (c)
      {
        case PAREN_OPEN:
        case BRACE_OPEN:
        case BRACKET_OPEN:
          parseTillClosed(c);
          break;
        case BRACKET_CLOSE:
        case BRACE_CLOSE:
        case PAREN_CLOSE:
          throw new IOException("Not a proper statement.");
        case IDENTIFIER:
          if (tokenBuffer[0] == ('@'))
            parseAtRule();
          else
            parseRuleSet();
          break;
        case END:
          return false;
      }
    return true;
  }

  /**
   * Parses an @ rule, stopping at a matching brace pair, or ;.
   *
   * @throws IOException - any i/o error from the reader
   */
  private void parseAtRule() throws IOException
  {
    // An At-Rule begins with the "@" character followed immediately by a keyword.
    // Following the keyword separated by a space is an At-rule statement appropriate
    // to the At-keyword used. If the At-Rule is a simple declarative statement
    // (charset, import, fontdef), it is terminated by a semi-colon (";".)
    // If the At-Rule is a conditional or informative statement (media, page, font-face),
    // it is followed by optional arguments and then a style declaration block inside matching
    // curly braces ("{", "}".) At-Rules are sometimes nestable, depending on the context.
    // If any part of an At-Rule is not understood, it should be ignored.

    // FIXME: Not Implemented
    // call handleimport
  }

  /**
   * Parses the next rule set, which is a selector followed by a declaration
   * block.
   *
   * @throws IOException - any i/o error from the reader
   */
  private void parseRuleSet() throws IOException
  {
    // call parseDeclarationBlock
    // call parse selectors
    // call parse identifiers
    // call startrule/endrule
    // FIXME: Not Implemented
  }

  /**
   * Parses a set of selectors, returning false if the end of the stream is
   * reached.
   *
   * @return false if the end of stream is reached
   * @throws IOException - any i/o error from the reader
   */
  private boolean parseSelectors() throws IOException
  {
    // FIXME: Not Implemented
    // call handleselector
    return false;
  }

  /**
   * Parses a declaration block. Which a number of declarations followed by a
   * })].
   *
   * @throws IOException - any i/o error from the reader
   */
  private void parseDeclarationBlock() throws IOException
  {
    // call parseDeclaration
    // FIXME: Not Implemented
  }

  /**
   * Parses a single declaration, which is an identifier a : and another identifier.
   * This returns the last token seen.
   *
   * @returns the last token
   * @throws IOException - any i/o error from the reader
   */
  private int parseDeclaration() throws IOException
  {
    // call handleValue
    // FIXME: Not Implemented
    return 0;
  }

  /**
   * Parses identifiers until c is encountered, returning the ending token,
   * which will be IDENTIFIER if c is found.
   *
   * @param c - the stop character
   * @param wantsBlocks - true if blocks are wanted
   * @return the ending token
   * @throws IOException - any i/o error from the reader
   */
  private int parseIdentifiers(char c, boolean wantsBlocks) throws IOException
  {
    // FIXME: Not implemented
    // call handleproperty?
    return 0;
  }

  /**
   * Parses till a matching block close is encountered. This is only appropriate
   * to be called at the top level (no nesting).
   *
   * @param i - FIXME
   * @throws IOException - any i/o error from the reader
   */
  private void parseTillClosed(int i) throws IOException
  {
    // FIXME: Not Implemented
  }

  /**
   * Gets an identifier, returning true if the length of the string is greater
   * than 0, stopping when c, whitespace, or one of {}()[] is hit.
   *
   * @param c - the stop character
   * @return returns true if the length of the string > 0
   * @throws IOException - any i/o error from the reader
   */
  private boolean getIdentifier(char c) throws IOException
  {
    // FIXME: Not Implemented
    return false;
  }

  /**
   * Reads till c is encountered, escaping characters as necessary.
   *
   * @param c - the stop character
   * @throws IOException - any i/o error from the reader
   */
  private void readTill(char c) throws IOException
  {
    // FIXME: Not Implemented
  }

  /**
   * Parses a comment block.
   *
   * @throws IOException - any i/o error from the reader
   */
  private void readComment() throws IOException
  {
    // Should ignore comments. Read until end of comment.
    // FIXME: Not implemented
  }

  /**
   * Called when a block start is encountered ({[.
   *
   * @param start of block
   */
  private void startBlock(int start)
  {
    // FIXME: Not Implemented
  }

  /**
   * Called when an end block is encountered )]}
   *
   * @param end of block
   */
  private void endBlock(int end)
  {
    // FIXME: Not Implemented
  }

  /**
   * Checks if currently in a block.
   *
   * @return true if currently in a block.
   */
  private boolean inBlock()
  {
    // FIXME: Not Implemented
    return false;
  }

  /**
   * Supports one character look ahead, this will throw if called twice in a row.
   *
   * @param c - the character to push.
   * @throws IOException - if called twice in a row
   */
  private void pushChar(int c) throws IOException
  {
    if (didPushChar)
      throw new IOException("pushChar called twice.");
    didPushChar = true;
    pushedChar = c;
  }
}
