/*
main.js
Copyright 2004 Brian Taylor, Jon Lawrence, David Barnett

    This file is part of jsEDIT.

    jsEDIT 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.

    jsEDIT 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 jsEDIT; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

// declare constants
var PRIVATE_SCANCODE = 1000;
var SCANCODE_BACKSPACE = 8;
var SCANCODE_TAB = 9;
var SCANCODE_ENTER = 13;
var SCANCODE_ESC = 27;
var SCANCODE_ARROW_LEFT = 37;
var SCANCODE_ARROW_UP = 38;
var SCANCODE_ARROW_RIGHT = 39;
var SCANCODE_ARROW_DOWN = 40;
var SCANCODE_DELETE = 46;

var ASCII_0 = 48;
var ASCII_9 = 57;

var MAX_DISP_LINES = 25;

//initialize variables
var cur_top_line;
var cur_bottom_line;
var tokens;

function scopeStackContains(scopeStack, searchKey)
{
	for (var i = scopeStack.length - 1; i >= 0; --i)
		for (var j = 0; j < scopeStack[i].length; ++j)
			if (scopeStack[i][j] == searchKey)
				return true;
	return false;
}

function contains(searchArray, searchKey)
{
	for (var i = 0; i < searchArray.length; ++i)
		if (searchArray[i] == searchKey)
			return true;
	return false;
}

function shrinkArrayLeft(arrayToShrink, elementsToRemove)
{
	for (var i = 0; i + elementsToRemove < arrayToShrink.length; ++i)
		for (var j = i; j + elementsToRemove < arrayToShrink.length; ++j)
			arrayToShrink[j] = arrayToShrink[j + elementsToRemove];
	arrayToShrink.length = (arrayToShrink.length - elementsToRemove);
}

function copyArray(arrayToCopy)
{
	var arrayCopy = new Array();
	for (var i = 0; i < arrayToCopy.length; ++i)
		arrayCopy[i] = arrayToCopy[i];
	return arrayCopy;
}

function updateTopLine(curTopLine, curLine)
{
	// cursor above the display
	curTopLine = Math.min(curTopLine, curLine);
	// cursor below the display
	curTopLine = Math.max(curTopLine, curLine - MAX_DISP_LINES + 1);
	// file shorter than display
	curTopLine = Math.min(curTopLine, Math.max(0, allText.length - MAX_DISP_LINES));
	return curTopLine;
}

function updateBottomLine(curTopLine)
{
	return Math.min(curTopLine + MAX_DISP_LINES, allText.length);
}

function buildUri()
{
	var i = 0;
	var uber_string = "";
	var uri_string = "";

	//Get file name here
	var titleMess1 = prompt("Please enter a filename:", titleMess);		//COME BACK HERE
	
	for(i = 0; i < allText.length; ++i)
	{
		uber_string += allText[i] + "\n";
	}
	uri_string = encodeURI(uber_string);
	synText[cur_top_line] = "<input type=\"hidden\" name=\"filename\" value=\"" + titleMess1 + "\"><input type=\"hidden\" name=\"text\" value=\"" + uri_string + "\"><center>are you sure<br>\n<input type=\"submit\" name=\"save\" value=\"Save\"><input type=\"button\" value=\"cancel\" onClick=\"parseSyntax(allText, synText," + cur_top_line + ", " + cur_bottom_line + ", " + curLine + ", " + curCol + ", tokens);writeDiv();\"></center></form>";
	writeDiv();
}

function writeDiv()
{
	//Outputs to the browser
	var ta = getDocTextArea();
	var ln = getDocLineNum();
	var st = getDocStatus();
	var ti = getDocTitle();

	st.innerHTML = statMess;
	ti.innerHTML = codeTitle +" - [" + titleMess +"]";

	var tempTA = "";
	var tempLN = "";

	for(var i = cur_top_line; i < cur_bottom_line; ++i)
	{
		tempTA += synText[i] + "<br>";
		tempLN += (i+1) + "<br>";
	}
	ta.innerHTML = tempTA;
	ln.innerHTML = tempLN;
}

function insertCode()
{
	var changed = false;
	if(curCode == SCANCODE_BACKSPACE)
	{
		changed = true;
		if(curCol==0 && curLine > 0)
		{
			curLine--;
			curCol = allText[curLine].length + 1;
			allText[curLine] += allText[curLine + 1];
			deleteLine(curLine+1);
		}
		else
			allText[curLine] = allText[curLine].substr(0, curCol-1) + allText[curLine].substr(curCol);
		if(curCol > 0)
			curCol--;
		title_update();
	}
	else if(curCode == PRIVATE_SCANCODE + SCANCODE_DELETE)
	{
		changed = true;
		if(curCol < allText[curLine].length)
		{
			var before = allText[curLine].substr(0, curCol);
			var after = allText[curLine].substr(curCol+1, allText[curLine].length);
			allText[curLine] = before + after;
			title_update();
		}
		else if((curCol == allText[curLine].length) && (curLine < allText.length-1))
		{
			var temp_var = allText[curLine+1];
			allText[curLine] += temp_var;
			deleteLine(curLine+1);
			title_update();
		}
	}
	/*else if(curCode == SCANCODE_TAB)
	{
		var before = allText[curLine].substr(0,curCol);
		var after = allText[curLine].substr(curCol, allText[curLine].length);
		allText[curCol] = before + "\t" + after;
	}*/
	else if(curCode == SCANCODE_ENTER)
	{
		changed = true;
		//count up the tabs at the beginning of the line
		var tabLevel = 0;
		while(tabLevel < allText[curLine].length && allText[curLine].charCodeAt(tabLevel) == 9)
			tabLevel++;
		var tabstring="";
		for(var i = 0; i < tabLevel; ++i)
			tabstring += '\t';

		var nextLineText = allText[curLine].substr(curCol);
		allText[curLine] = allText[curLine].substr(0, curCol);
		addLine(curLine++);
		allText[curLine] = tabstring + nextLineText;
		
		curCol = tabLevel;
		title_update();
	}
	else if(curCode == PRIVATE_SCANCODE + SCANCODE_ARROW_LEFT)
	{
		if(curCol > 0)
			curCol--;
	}
	else if(curCode == PRIVATE_SCANCODE + SCANCODE_ARROW_RIGHT)
	{
		if(curCol < allText[curLine].length)
			curCol++;
	}
	else if(curCode == PRIVATE_SCANCODE + SCANCODE_ARROW_UP)
	{
		if(curLine > 0)
		{
			curLine--;
			curCol = Math.min(curCol, allText[curLine].length);
		}
	}
	else if(curCode == PRIVATE_SCANCODE + SCANCODE_ARROW_DOWN)
	{
		if(curLine < allText.length - 1)
		{
			++curLine;
			curCol = Math.min(curCol, allText[curLine].length);
		}
	}
	else
	{
		changed = true;
		var character = String.fromCharCode(curCode);
		var before = allText[curLine].substr(0, curCol);
		var after = allText[curLine].substr(curCol, allText[curLine].length);
		allText[curLine] = before + character + after;
		curCol++;
		title_update();
	}

	curCode = 0;
	
	statMess = "Current Line : " + (curLine + 1) + "   Current col : " + (curCol + 1);
	
	var tempLine = updateTopLine(cur_top_line, curLine);
	if (cur_top_line != tempLine)
	{
		changed = true;
		cur_top_line = tempLine;
	}

	tempLine = updateBottomLine(cur_top_line);
	if (cur_bottom_line != tempLine)
	{
		changed = true;
		cur_bottom_line = tempLine;
	}

	if (changed)
		parseSyntax(allText, synText, cur_top_line, cur_bottom_line, curLine, curCol, tokens);
	else
		tokenFormat(curLine, curCol, cur_top_line, tokens, synText);

	writeDiv();
}

function deleteLine(line)
{
	for(var i = line; i < allText.length -1;i++)
	{
		allText[i] = allText[i+1];
		synText[i] = synText[i+1];
	}
	synText.length--;
	allText.length--;
}

function addLine(line)
{
	for(var i = allText.length - 1; i > line; i--)
	{
		allText[i+1] = allText[i];
		synText[i+1] = synText[i];
	}

	allText[line+1] = "";
	synText[line+1] = "";
}

function title_update()
{
	//this is called if the a key was pressed that changes the file
	if(titleMess.charAt(titleMess.length-1) != "*")
		titleMess += "*";
}

function init_all()
{
	cur_top_line = 0;
	cur_bottom_line = Math.min(allText.length, cur_top_line + MAX_DISP_LINES);
	prototypes = false;
	setLanguage();

	tokens = new Array();

	tokenRegExpsFull = new Array();
	tokenRegExpsNoEnd = new Array()
	tokenRegExpsCont = new Array()

	for (var type = 0; type < tokenRegExps.length; ++type)
	{
		tokenRegExpsFull[type] = mergeRegExps(tokenRegExps[type][0], tokenRegExps[type][1], changeQuant(tokenRegExps[type][2], "?"));
		tokenRegExpsCont[type] = mergeRegExps(tokenRegExps[type][1], changeQuant(tokenRegExps[type][2], "?"));
		tokenRegExpsNoEnd[type] = mergeRegExps(tokenRegExps[type][0], tokenRegExps[type][1]);
	}

	parseSyntax(allText, synText, cur_top_line, cur_bottom_line, curLine, curCol, tokens);

	statMess = "Current Line : " + (curLine + 1) + "   Current col : " + (curCol + 1);
	writeDiv();
	initHandlers();
}

function callKeyDown()
{
}

function callKeyUp()
{
}

function callKeyPress()
{
}
