#ifndef _COLORER_INTERFACES_H_
#define _COLORER_INTERFACES_H_

#include<common/io/InputSource.h>
#include<common/io/Writer.h>
#include<xml/xml.h>

/** @addtogroup colorer
    @{
*/

/**
  Informs application about internal HRC parsing problems.
*/
class HRCParserException : public Exception{
public:
  HRCParserException();
  HRCParserException(const String& msg);
};


/**
  Informs application about different
  Parsing problems and warning.
*/
class ErrorHandler
{
public:
  /**
    Nonfatal parse error.
    Called when target class finds some non-fatal error.
    @param msg Error message
  */
  virtual void error(const String &msg) = 0;
  /**
    Fatal parse error.
    Called when target class finds fatal error, which could
    significantly change or break expected behaviour.
    @param msg Error message
  */
  virtual void fatalError(const String &msg) = 0;
  /**
    Simple warnings/info messages.
    Called when target class want to inform application
    about some warnings or informational messages.
    @param msg Warning message
  */
  virtual void warning(const String &msg) = 0;

  virtual ~ErrorHandler(){};
};


/**
  Service editor line information requests.
  Basic class, used in TextParser processing.
*/
class LineHandler
{
public:
  /**
    Returns line with specified number.
    Returns DString class, which incapsulates information
    about line with number <code>lno</code>.
    @param lno Requested line number
    @return Unicode string, enwrapped into DString class.
  */
  virtual DString getLine(int lno) = 0;
protected:
  LineHandler(){};
  virtual ~LineHandler(){};
};

/**
  HRC Region implementation.
  Contains information about HRC Region and it attributes:
  <ul>
    <li>name
    <li>description
    <li>parent
  </ul>
*/
class Region{
public:
  /** Full Qualified region name (<code>def:Text</code> for example) */
  virtual const String *getName() const{ return name; };
  /** Region description */
  virtual const String *getDescription() const{ return description; };
  /** Direct region ancestor (parent) */
  virtual const Region *getParent() const{ return parent; };
  /** Quick access region id (incrementable) */
  virtual int getID() const{ return id; };
  /** Checks if region has the specified parent in all of it's ancestors.
      This method is useful to check if region has specified parent,
      and use this information, as region type specification.
      For example, <code>def:Comment</code> has <code>def:Syntax</code> parent,
      so, some syntax checking can be made with it's content.
  */
  bool hasParent(const Region *region) const{
    const Region *elem = this;
    while(elem != null){
      if (region == elem) return true;
      elem = elem->getParent();
    };
    return false;
  };
  /**
    Basic constructor.
    Used only by HRCParser.
  */
  Region(const String *_name, const String* _description, const Region *_parent, int _id){
    name = new SString(_name);
    description = null;
    if (_description != null) description = new SString(_description);
    parent = _parent;
    id = _id;
  };
  virtual ~Region(){
    delete name;
    delete description;
  };
protected:
  /** Internal members */
  String *name, *description;
  const Region *parent;
  int id;
};

class Scheme;
/** Interface to return parse information from TextParser.
    TextParser class generate calls of this class methods
    sequentially while parsing the text from top to bottom.
    All enterScheme and leaveScheme calls are properly enclosed,
    addRegion calls can overlap with each other.
*/
class RegionHandler{
public:
  /** Start of text parsing.
      Called only once, when TextParser starts
      parsing of the specified block of text.
      @param lno Start line number
  */
  virtual void startParsing(int lno){};
  /** End of text parsing.
      Called only once, when TextParser stops
      parseing of the specified block of text.
      @param lno End line number
  */
  virtual void endParsing(int lno){};
  /** Clear line event.
      Called once for each parsed text line, when TextParser starts to parse
      specified line of text. This method is called before any of the region
      information passed, and used often to clear internal handler
      structure of this line before adding new one.
      @param lno Line number
  */
  virtual void clearLine(int lno){};
  /** Informs handler about lexical region in line.
      This is a basic method, wich transfer information from
      parser to application.
      @param lno Current line number
      @param sx Start X position of region in line
      @param ex End X position of region in line
      @param region Region information
  */
  virtual void addRegion(int lno, int sx, int ex, const Region *region) = 0;
  /** Informs handler about entering into specified scheme.
      Parameter <code>region</code> is used to specify
      scheme background region information.
      @param lno Current line number
      @param sx Start X position of region in line
      @param ex End X position of region in line
      @param region Scheme Region information (background)
      @param scheme Additional Scheme information
  */
  virtual void enterScheme(int lno, int sx, int ex, const Region *region, const Scheme *scheme) = 0;
  /** Informs handler about leaveing specified scheme.
      Parameter <code>region</code> is used to specify
      scheme background region information (equals to the same in #addRegion method)
      @param lno Current line number
      @param sx Start X position of region in line
      @param ex End X position of region in line
      @param region Scheme Region information (background)
      @param scheme Additional Scheme information
  */
  virtual void leaveScheme(int lno, int sx, int ex, const Region *region, const Scheme *scheme) = 0;
protected:
  RegionHandler(){};
  virtual ~RegionHandler(){};
};


/** HRC Scheme instance information.
    Used in RegionHandler calls.
*/
class Scheme
{
public:
  /** Full qualified schema name.
  */
  virtual const String *getName() const = 0;
protected:
  Scheme(){};
  virtual ~Scheme(){};
};

/** HRC FileType (or prototype) instance
*/
class FileType{
public:
  /** Is this type already loaded
      All types could be loaded with #HRCParser::loadType()
  */
  virtual bool isLoaded() const = 0;
  /** Public name of file type (HRC 'name' attribute)
      @return File type Name
  */
  virtual const String *getName() const = 0;
  /** Public group name of file type (HRC 'group' attribute)
      @return File type Group
  */
  virtual const String *getGroup() const = 0;
  /** Public description of file type (HRC 'description' attribute)
      @return File type Description
  */
  virtual const String *getDescription() const = 0;
  /** Returns the base scheme of this file type.
      Basically, this is the scheme with same public name, as it's type.
      @return File type base scheme, to be used as root scheme of text parsing.
  */
  virtual const Scheme *getBaseScheme() const = 0;
  /** Returns parameter value of this file type.
      Parameters are stored in prototypes as
      \<parameters>
        \<param name="name" value="value"/>
      \</parameter>
      @note Parameters could be used to store client-application
            specific information about each type of file.
      @param name Parameter's name
  */
  virtual const String *getParameter(String &name) const = 0;
protected:
  FileType(){};
  virtual ~FileType(){};
};

/** Abstract template of HRCParser class implementation.
    Defines basic operations of loading and accessing
    HRC information.
*/
class HRCParser
{
public:
  /** Error Handler, used to inform application about different error conditions
      @param eh ErrorHandler instance, or null to drop error handling.
  */
  virtual void setErrorHandler(ErrorHandler *eh) = 0;
  /** Loads HRC from specified InputSource stream.
      Referred HRC file can contain prototypes and
      real types definitions. If it contains just prototype definition,
      real type load must be performed before using with #loadType() method
      @param is InputSource stream of HRC file
  */
  virtual void loadSource(InputSource *is) = 0;
  /** Loads specified FileType.
      If type is already loaded, does nothing.
  */
  virtual void loadType(FileType *filetype) = 0;

  /** Returns total number of types/prototypes
  */
  virtual int getFileTypeCount() const = 0;
  /** Enumerates sequentially all prototypes
      @param index index of type.
      @return Requested type, or null, if #index is too big
  */
  virtual FileType *enumerateFileTypes(int index) const = 0;
  /**
      @param name Requested type name.
      @return File type, or null, there are no type with specified name.
  */
  virtual FileType *getFileType(const String *name) const = 0;

  /** Searches and returns the best type for specified file.
      This method uses fileName and firstLine parameters
      to perform selection of the best HRC type from database.
      @param fileName Name of file
      @param firstLine First line of this file, could be null
      @param typeNo Sequential number of type, if more than one type
                    satisfy these input parameters.
  */
  virtual FileType *selectType(const String *fileName, const String *firstLine, int typeNo = 0) const = 0;

  /** Total number of declared regions
  */
  virtual int getRegionCount() const = 0;
  /** Returns region by internal id
  */
  virtual const Region *getRegion(int id) const = 0;
  /** Returns region by name
  */
  virtual const Region *getRegion(const String *name) const = 0;

  /** HRC base version.
      Usually this is the 'version' attribute of 'hrc' element
      of first loaded HRC file.
  */
  virtual const String *getVersion() const = 0;

  virtual ~HRCParser(){};
protected:
  HRCParser(){};
};


/** Basic lexical/syntax parser interface.
    This class provides interface to lexical text parsing abilities of
    Colorer library.
    It uses LineHandler as source of input data, and RegionHandler
    as interface to transfer results of text parse process.

    Process of syntax parsing supports internal caching algorithims,
    which allows to store internal parser state and reparse text
    only partially (on change, on request).
*/
class TextParser
{
public:
  /** Sets root scheme (filetype) of parsed text
      @param type FileType, which contains reference to it's baseScheme
  */
  virtual void setFileType(const FileType *type) = 0;
  /** LineHandler, used as input of parsing text
  */
  virtual void setLineHandler(LineHandler *lh) = 0;
  /** RegionHandler, used as outputter of parsed information
  */
  virtual void setRegionHandler(RegionHandler *rh) = 0;

  /** Performs cachable parsing
      @param from Start parsing line
      @param num Number of lines to parse
  */
  virtual int  fullParse(int from, int num) = 0;
  /** Performs non-cachable parsing
      @param from Start parsing line
      @param num Number of lines to parse
  */
  virtual int  quickParse(int from, int num) = 0;
  /** Performs break of parsing process from external thread.
      It is used to stop parse from external source. This needed
      in some editor systems implementation, when editor system
      detects background changes in highlighted text, for example.
  */
  virtual void breakParse() = 0;
  /** Clears cached text stucture information
  */
  virtual void clearCache() = 0;

  virtual ~TextParser(){};
protected:
  TextParser(){};
};

/** @} */ // end of group 'colorer'
#endif
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the Colorer Library.
 *
 * The Initial Developer of the Original Code is
 * Cail Lomecb <ruiv@uic.nnov.ru>.
 * Portions created by the Initial Developer are Copyright (C) 1999-2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */