/*
	Copyright (C) 2003-2009 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 piece of TurtleScript as found by the Tokenizer.
 *
 * Because of the goals of KTurtle it this class very elaborate. Much info
 * about each token is kept so descriptive error messages can be printed,
 * and proper highlighting and context help made possible.
 *
 * Tokens are made by the Tokenizer accoring to the TurtleScript, then they are stored
 * in the node tree by the Parser or used by the Highlighter of for context help.
 *
 * A large potion 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
		{
			Error   = -2,  // when the Tokenizer finds something it cannot deal with (like a single dot)
			Unknown = -1,  // when the Translator found no translation (like when calling a learned function)
			NotSet  =  0,  // when Tokens are contructed without being initialized (needed for ErrorList)

//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!
 */

			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,
			Assert,
			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,
			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,
			ParenthesisCategory,
			TrueFalseCategory,
			FunctionCallCategory,
			ExpressionCategory,
			ArgumentSeparatorCategory,
			MathOperatorCategory,
			CommentCategory,
			AssignmentCategory,
			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);

		virtual ~Token() {}


		const QString& look()
		               const { return _look; }
		int type()     const { return _type; }
		int category() const { return typeToCategory(_type); }
		int startRow() const { return _startRow; }
		int startCol() const { return _startCol; }
		int endRow()   const { return _endRow; }
		int endCol()   const { return _endCol; }

		void setType(int type)         { _type = type; }
		void setStartRow(int startRow) { _startRow = startRow; }
		void setStartCol(int startCol) { _startCol = startCol; }
		void setEndRow(int endRow)     { _endRow = endRow; }
		void setEndCol(int endCol)     { _endCol = endCol; }

		/// Compares 2 Tokens. Needed for ErrorList (QValueList) 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&);

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


	private:
		int     _type;
		QString _look;
		int     _startRow, _startCol, _endRow, _endCol;
};


#endif  // _TOKEN_H_
