/*
	Copyright (C) 2003-2006 Cies Breijs <cies AT kde DOT nl>

    This program 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 of the License, or (at your option) any later version.

	This program 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 this program; if not, write to the Free
	Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
	Boston, MA 02110-1301, USA.
*/


#ifndef _TOKEN_H_
#define _TOKEN_H_

#include <QString>



/**
 * @short The Token object, represents a token in programming language.
 *
 * Because of the goals of KTurtle it this class very extended, it stores much info
 * about each token so descriptive error messages can be printed.
 *
 * Basically it is a wrapper around the tokens look, type and start/end position.
 *
 * The tokens made by the Tokeniser accorind to the KTurtle code, then they are stored
 * in the node tree by the Parser. The Executer makes use of tokens while executing.
 *
 * A large part of the code of this class (the Type enum) is generated code.
 *
 * @TODO investigate if it will be beter to replace this class by a struct for speed.
 *
 * @author Cies Breijs
 */
class Token
{
	public:
		/**
		 * This is an enum for the different types a Token can have.
		 * The code for this enum is generated.
		 */
		enum Type
		{

//BEGIN GENERATED token_type_h CODE

/* The code between the line that start with "//BEGIN GENERATED" and "//END GENERATED"
 * is generated by "generate.rb" according to the definitions specified in
 * "definitions.rb". Please make all changes in the "definitions.rb" file, since all
 * all change you make here will be overwritten the next time "generate.rb" is run.
 * Thanks for looking at the code!
 */

			NotSet,
			Unknown,
			Error,
			Root,
			Scope,
			WhiteSpace,
			EndOfLine,
			EndOfInput,
			VariablePrefix,
			Variable,
			FunctionCall,
			String,
			Number,
			True,
			False,
			Comment,
			StringDelimiter,
			ScopeOpen,
			ScopeClose,
			ParenthesisOpen,
			ParenthesisClose,
			ArgumentSeparator,
			DecimalSeparator,
			Exit,
			If,
			Else,
			Repeat,
			While,
			For,
			ForTo,
			To,
			Step,
			Break,
			Return,
			Wait,
			And,
			Or,
			Not,
			Equals,
			NotEquals,
			GreaterThan,
			LessThan,
			GreaterOrEquals,
			LessOrEquals,
			Addition,
			Substracton,
			Multiplication,
			Division,
			Power,
			Assign,
			Learn,
			ArgumentList,
			Reset,
			Clear,
			Center,
			Go,
			GoX,
			GoY,
			Forward,
			Backward,
			Direction,
			TurnLeft,
			TurnRight,
			PenWidth,
			PenUp,
			PenDown,
			PenColor,
			CanvasColor,
			CanvasSize,
			SpriteShow,
			SpriteHide,
			Print,
			FontSize,
			Random,
			GetX,
			GetY,
			Message,
			Ask,
			Pi,
			Tan,
			Sin,
			Cos,
			ArcTan,
			ArcSin,
			ArcCos,
			Sqrt,
			Exp,
			Round

//END GENERATED token_type_h CODE

		};


		/**
		 * This is an enum for the different categories a Token can belong to.
		 * It is used by the highlighter to know how to highlight the code,
		 * and the mainwindow to determain the 'context help keyword'.
		 * The code for this enum is mostly generated.
		 */
		enum Category
		{
			UnknownCategory,

//BEGIN GENERATED token_category_h CODE

/* The code between the line that start with "//BEGIN GENERATED" and "//END GENERATED"
 * is generated by "generate.rb" according to the definitions specified in
 * "definitions.rb". Please make all changes in the "definitions.rb" file, since all
 * all change you make here will be overwritten the next time "generate.rb" is run.
 * Thanks for looking at the code!
 */

			CommandCategory,
			ControllerCommandCategory,
			NumberCategory,
			MathOperatorCategory,
			WhiteSpaceCategory,
			ParenthesisCategory,
			DecimalSeparatorCategory,
			FunctionCallCategory,
			ExpressionCategory,
			MetaCategory,
			AssignmentCategory,
			TrueFalseCategory,
			CommentCategory,
			ArgumentSeparatorCategory,
			BooleanOperatorCategory,
			ScopeCategory,
			VariableCategory,
			StringCategory,
			LearnCommandCategory

//END GENERATED token_category_h CODE

		};


		/**
		 * @short Constructor.
		 * Initialses a empty Token with Token::Type: Token::NotSet.
		 * This default constuctor is needed for ErrorList (QValueList).
		 */
		Token();

		/**
		 * @short Constructor.
		 * Initialses a complete Token.
		 *
		 * @param type     type of the token, see also the @ref Type enum in this class
		 * @param look     the look of the Token as in the unicode string of the tokens
		 *                 appearance in the KTurtle code.
		 * @param startRow row position of the first character of this token in the code
		 * @param startCol column position of the first character of this token in the code
		 * @param endRow   row position of the last character of this token in the code
		 * @param endCol   column position of the last character of this token in the code
		 */
		Token(int type, const QString& look, int startRow, int startCol, int endRow, int endCol);

		/** @short Destructor. Does nothing special. */
		virtual ~Token() {}


		
		/** @returns the unicode string of code that sit behind this token. */
		const QString& look()     const { return _look; }
		
		/** @returns the type of the token. @see setType() */
		int            type()     const { return _type; }

		/** @returns the category of the token. */
		int            category() const { return typeToCategory(_type); }
		
		/** @returns the startRow of the token. @see setStartRow() */
		int           startRow() const { return _startRow; }
		
		/** @returns the startCol of the token. @see setStartCol() */
		int           startCol() const { return _startCol; }
		
		/** @returns the endRow of the token. @see setEndRow() */
		int           endRow()   const { return _endRow; }
		
		/** @returns the endCol of the token. @see setEndCol() */
		int           endCol()   const { return _endCol; }


		/** Sets the @p type of the token. @see type() */
		void setType(int type)          { _type = type; }

		/** Sets the @p startRow of the token. @see startRow() */
		void setStartRow(int startRow)  { _startRow = startRow; }

		/** Sets the @p startCol of the token. @see startCol() */
		void setStartCol(int startCol)  { _startCol = startCol; }

		/** Sets the @p endRow of the token. @see endRow() */
		void setEndRow(int endRow)      { _endRow = endRow; }

		/** Sets the @p endCol of the token. @see endCol() */
		void setEndCol(int endCol)      { _endCol = endCol; }

		/** Compares 2 Tokens. Needed for ErrorList (QValueList), it needs to compare ErrorMessages which contain Tokens. */
		bool operator==(const Token&) const;

		/** Assigns a Token, it needs to compare ErrorMessages which contain Tokens. */
		Token& operator=(const Token&);
		
//		static QString key(int type);    maybe needed in the future when the tokenizer is used for context help

		/// returns the category a type belongs to (generated)
		static int typeToCategory(int);


	private:
		/// The tokens type.
		int            _type;

		/// The tokens look (unicode). Constant; can only set at construction time.
		QString        _look;

		/// The tokens start/end positions.
		int           _startRow, _startCol, _endRow, _endCol;
};


#endif // _TOKEN_H_
