//  
//  TokenList.cs
//  
//  Author:
//       Robert BRACCAGNI alias Gai-Luron <lfsgailuron@free.fr>
// 
//  Copyright (c) 2010 Gai-Luron
// 
//  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 3 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, see <http://www.gnu.org/licenses/>.


using System;
using System.Collections;
using System.Text;

namespace GLScript
{

	public class token
	{
		public int typ;
		public string fileName;
		public int lineNumber;
		public string value;
		public int startThenPart = 0;
		public int endThenPart = 0;
		public int startElsePart = 0;
		public int endElsePart = 0;
		public int startFor = 0;
		public int endFor = 0;
		public ArrayList args;
		public Parseur parsed = null;
		public token(int ptyp, string pfileName, int pLine, string pvalue)
		{
			this.typ = ptyp;
			this.fileName = pfileName;
			this.lineNumber = pLine;
			this.value = pvalue;
		}
		public token(int ptyp, string pfileName, int pLine, string pvalue, ArrayList pargs )
		{
			this.typ = ptyp;
			this.fileName = pfileName;
			this.lineNumber = pLine;
			this.value = pvalue;
			this.args = pargs;
		}
	}
	public class TokenBuffer
    {
        public System.Collections.ArrayList TokenList = new System.Collections.ArrayList();
        public TokenBuffer(string str, string fileName, int StartLineInSrc, Hashtable localconst, Hashtable globalconst )
        {
            createTokenBuffer(str, fileName, StartLineInSrc, localconst, globalconst );
        }
		void createTokenBuffer(string str, string fileName, int StartLineInSrc, Hashtable localconst, Hashtable globalconst )
        {
            int tok;
			int lastTok;
            string currFile = fileName;
            Scanner scnr = new Scanner();
            scnr.SetSource(str, 0);
			lastTok = 0;
            while (true)
            {
                tok = scnr.yylex();
//				Console.WriteLine(tok + ":'" + scnr.yytext + "'");
				if (tok == (int)Tokens.EOF || tok == Scanner.E_END)
                    break;
                string yytext = scnr.yytext;
				if (tok == Scanner.E_ARVAR)
				{
					yytext = scnr.strBloc;
				}
				if (tok == Scanner.E_FUNCTION)
				{
					yytext = scnr.strBloc;
				}
				if (tok == Scanner.E_IDENT)
				{
					if (localconst != null && localconst.Contains(scnr.yytext))
					{
						yytext = (string)localconst[scnr.yytext];
					}
					else if (localconst != null && globalconst.Contains(scnr.yytext))
					{
						yytext = (string)globalconst[scnr.yytext];
					}

                }
				if (tok == Scanner.E_ARVAR || tok == Scanner.E_FUNCTION) // If type Var, alors tokenize les arguments
				{
					ArrayList args = new ArrayList();
					for (int i = 0; i < scnr.args.Count; i++)
					{
						args.Add( new TokenBuffer( (string)scnr.args[i],fileName,StartLineInSrc + scnr.YyLine-1,localconst,globalconst ));
					}
					TokenList.Add(new token(tok, currFile, StartLineInSrc + scnr.YyLine-1, yytext, args));
				}
				else{
					if ((tok == Scanner.E_INTEGER || tok == Scanner.E_FLOAT ) && float.Parse( yytext ) < 0)
					{
						if (lastTok == Scanner.E_PAR_CLOSE
							|| lastTok == Scanner.E_INTEGER
							|| lastTok == Scanner.E_FLOAT
							|| lastTok == Scanner.E_BRACKET_CLOSE)
						{
							TokenList.Add(new token(Scanner.E_PLUS, currFile, StartLineInSrc + scnr.YyLine-1, "+"));
						}

					}
					TokenList.Add(new token(tok, currFile, StartLineInSrc + scnr.YyLine - 1, yytext));
				}
				lastTok = tok;
			}
        }
    }
}
