var map_table; 

var startX = -1;
var startY = -1;
var endX = -1;
var endY = -1;

var lineBoxTop;
var lineBoxBottom;
var lineBoxLeft;
var lineBoxRight;

var mapHeight = 24;
var mapWidth = 24;

var g_tileWidth = 60;
var g_tileHeight = 60;

var debug = 0;

function IsIE () 
{
	if (navigator.userAgent.indexOf ("MSIE") != -1)
	{
		return 1;
	}
	return 0;
}

function log (msg)
{
	if (!debug)
		return;
	var log_table = document.getElementById("log_table");
	var newRow = document.createElement ("tr");
	var newCell = document.createElement ("td");
	newCell.innerHTML = msg;
	newRow.appendChild (newCell);
	log_table.appendChild (newRow);
}

function CheckLineEnd (x, y)
{
	if (x >= lineBoxRight && y >= lineBoxBottom)
		return 1;
	if (x <= lineBoxLeft && y <= lineBoxTop)
		return 1;
	if (x >= lineBoxRight && y <= lineBoxTop)
		return 1;
	if (x <= lineBoxLeft && y >= lineBoxBottom)
		return 1;
	return 0;
}

function HandleCheck (name)
{
	var currentTile;

	var nameArray = name.split(',');
	var tileX = parseInt (nameArray [0]);
	var tileY = parseInt (nameArray [1]);
	var x = ((tileX * g_tileWidth) + (g_tileWidth / 2));
	var y = ((tileY * g_tileHeight) + (g_tileHeight / 2));

	lineStartX = ((startX * g_tileWidth) + (g_tileWidth / 2));
	lineStartY = ((startY * g_tileHeight) + (g_tileHeight / 2));
	lineEndX = ((endX * g_tileWidth) + (g_tileWidth / 2));
	lineEndY = ((endY * g_tileHeight) + (g_tileHeight / 2));

	// ax + by + c = 0
	var a = lineStartY - lineEndY;
	var b = lineEndX - lineStartX;
	var c = -(a * lineStartX + b * lineStartY);

	log ("Checking from (" + lineStartX + "," + lineStartY  + ") to (" + lineEndX + "," + lineEndY + ") for (" + x + "," + y + ") a("+a+"),b("+b+"),c("+c+")");

	//currentTile = ShowElement (name + "_lit");

	if (lineStartX == x && lineStartY == y)
	{
		//currentTile.innerHTML = "<center><span class='distance'>A</span></center>";
		return;
	}

	if (lineEndX == x && lineEndY == y)
	{
		//currentTile.innerHTML = "<center><span class='distance'>B</span></center>";
		return;
	}

	if (CheckLineEnd (tileX, tileY))
	{
		//currentTile.innerHTML = "<center><span class='distance'>C</span></center>";
		return;
	}

	// get the points for the square
	topLeftX = x - ((g_tileWidth / 2));
	topLeftY = y - ((g_tileHeight / 2));
	bottomLeftX = x - ((g_tileWidth / 2));
	bottomLeftY = y + ((g_tileHeight / 2));
	bottomRightX = x + ((g_tileWidth / 2));
	bottomRightY = y + ((g_tileHeight / 2));
	topRightX = x + ((g_tileWidth / 2));
	topRightY = y - ((g_tileHeight / 2));

	// check if they are all below the line
	var allNegative = 1
	if(a * topLeftX + b * topLeftY + c > 0)
		allNegative = 0;
	if(a * bottomLeftX + b * bottomLeftY + c > 0)
		allNegative = 0;
	if(a * bottomRightX + b * bottomRightY + c > 0)
		allNegative = 0;
	if(a * topRightX + b * topRightY + c > 0)
		allNegative = 0;

	if (allNegative)
	{
		//currentTile.innerHTML = "<center><span class='distance'>-</span></center>";
		return;
	}

	var allPositive = 1;
	if(a * topLeftX + b * topLeftY + c < 0)
		allPositive = 0;
	if(a * bottomLeftX + b * bottomLeftY + c < 0)
		allPositive = 0;
	if(a * bottomRightX + b * bottomRightY + c < 0)
		allPositive = 0;
	if(a * topRightX + b * topRightY + c < 0)
		allPositive = 0;

	if (allPositive)
	{
		//currentTile.innerHTML = "<center><span class='distance'>+</span></center>";
		return;
	}

	log ('Found ' + name);
	currentTile = ShowElement (name + "_lit");

	var xDif = (startX > tileX ? startX - tileX : tileX - startX);
	var yDif = (startY > tileY ? startY - tileY : tileY - startY);

	currentTile.innerHTML = "<center><span class='distance'>"+Math.max(xDif,yDif)+"</span></center>";
}

function GetCoordinate (x, y)
{
	return ("<span class='coords'>" + String.fromCharCode(65 + parseInt(x)) + ":" + (parseInt(y) + 1) + "</span>");
}

function HandleStart (name, x, y)
{
	startX = x;
	startY = y;

	lineBoxLeft = x;
	lineBoxRight = x;
	lineBoxTop = y;
	lineBoxBottom = y;

	log ("HandleStart " + name);

	var currentTile = ShowElement (name + "_start");
	document.getElementById ("status").innerHTML = "Select a tile to check for Line of Sight from "+ GetCoordinate (startX, startY) + ".";
}

function HandleEnd (name, x, y)
{
	endX = x;
	endY = y;
	log ("HandleEnd " + name);

	if (x > lineBoxRight)
		lineBoxRight = x;
	else
		lineBoxLeft = x;

	if (y > lineBoxBottom)
		lineBoxBottom = y;
	else
		lineBoxTop = y;

	var currentTile = ShowElement (name + "_end");

	document.getElementById ("status").innerHTML = "Line of Sight from "+ GetCoordinate (startX, startY) + " to " + GetCoordinate (endX, endY) + ".";

	log ('LOS for ' + mapHeight + ',' + mapWidth);
	for (row = 0; row < mapHeight; row++)
	{
		for (column = 0; column < mapWidth; column++)
		{
			var cellName = column + ',' + row;
			HandleCheck (cellName);
		}
	}
}

function HandleClear (name, x, y)
{
	// clear the highlights
	var currentStartTile = HideElement (document.getElementById(startX + "," +startY + "_start"));
	var currentEndTile = HideElement (document.getElementById(endX + "," +endY + "_end"));

	startX = -1;
	startY = -1;
	endX = -1;
	endY = -1;

	document.getElementById ("status").innerHTML = "Clearing Map ...";

	for (row = 0; row < mapHeight; row++)
	{
		for (column = 0; column < mapWidth; column++)
		{
			var currentTile = document.getElementById(column + "," + row + "_lit");
			currentTile.innerHTML = "<span class='distance'></span>";
			currentTile = HideElement (currentTile);

			// dont' clear blocked tiles?
			//var currentTileBlocked = document.getElementById(column + "," + row + "_blocked");
			//currentTileBlocked = HideElement (currentTileBlocked);
		}	
	}

	document.getElementById ("log_table").innerHTML = "";

	HandleStart (name, x, y);
}

function HandleCtrlClick (name)
{
	var currentTile = ShowElement (name + "_blocked");
	if (!currentTile) // if it is already there .. remove it
	{
		var element = document.getElementById (name + "_blocked");
		HideElement (element);
	}	
}

function HandleClick (event, name)
{
	var ctrlPressed=0;
	var altPressed=0;
	var shiftPressed=0;

	var evt = navigator.appName=="Netscape" ? event : window.event;

	if (navigator.appName=="Netscape" && parseInt(navigator.appVersion)==4) 
	{
		// NETSCAPE 4 CODE
		var mString =(e.modifiers+32).toString(2).substring(3,6);
		shiftPressed=(mString.charAt(0)=="1");
		ctrlPressed =(mString.charAt(1)=="1");
		altPressed  =(mString.charAt(2)=="1");tile_end="pics/tile_lit_end.png"
	}
	else 
	{
		// NEWER BROWSERS [CROSS-PLATFORM]
		shiftPressed=evt.shiftKey;
		altPressed  =evt.altKey;
		ctrlPressed =evt.ctrlKey;
	}

	if (ctrlPressed || altPressed || shiftPressed)
	{
		HandleCtrlClick (name);
		return;
	}

	var nameArray = name.split(',');
	var x = parseInt (nameArray [0]);
	var y = parseInt (nameArray [1]);

	if (startX < 0 || startY < 0)
	{
		HandleStart (name, x, y);
		return;
	}

	if (endX < 0 || endY < 0)
	{
		HandleEnd (name, x, y);
		return;
	}
	

	log ("clear " + name);
	HandleClear (name, x, y);
}

var g_LitTile = 0;
var g_HighlightTop = 0;
var g_HighlightSide = 0;

function HideElement (element)
{
	if (!element)
		return 0;
	
	if (element.length  <= 0)
		return 0;
	if (!element.style)
		return 0;
	if (!element.style.visibility)
		return 0;

	element.style.visibility = "hidden";
	return 0;
}

function ShowElement (name)
{
	var element = document.getElementById (name);
	if (!element)	
		return 0;

	if (!element.style)
		return 0;

	if (element.style.visibility == "visible")
		return 0;

	element.style.visibility = "visible";

	return element;
}

function HandleOver (name)
{
	var nameArray = name.split(',');
	var x = parseInt (nameArray [0]);
	var y = parseInt (nameArray [1]);

	g_HighlightTop = ShowElement ('top_highlight_' + x);
	g_HighlightSide = ShowElement ('side_highlight_' + y);
	g_LitTile = ShowElement(name + "_lit");
}

function HandleOut (name)
{
	g_HighlightSide = HideElement(g_HighlightSide);
	g_HighlightTop = HideElement(g_HighlightTop);
	g_LitTile = HideElement(g_LitTile);
}

function CreateDiv (newId, tileWidth, tileHeight, tileClass, img)
{
	var newTile = document.createElement("div");

	if (tileClass == 'tile_lit')
		SetDefaultTileLitProperties (newTile);

	if (tileClass == 'tile')
		SetDefaultTileProperties (newTile);

	newTile.setAttribute('id', newId);
	newTile.style.backgroundImage = "url(\""+img+"\")";
	newTile.style.width = tileWidth+"px";
	newTile.style.height = tileHeight+"px";

	return newTile;
}

function SetDefaultTileLitProperties (newTileLit)
{
	// putting these in here because they don't seem to get picked up from the class in the CSS
	newTileLit.style.visibility = "hidden";
	newTileLit.style.position = "absolute";	
	newTileLit.style.top = "0";	
	newTileLit.style.left = "0";	
}

function SetDefaultTileProperties (newTile)
{
	newTile.setAttribute ('class', 'tile');
	newTile.style.position = "relative";	
	newTile.style.padding ="0px";	
}

function CreateHighlight (newId, newHighlightImage, tileWidth, tileHeight,  newAlign, newInnerHTML, headerRow)
{
	var headerCell = document.createElement ("td");
	var headerCellDiv = document.createElement ("div");
	var highlightDiv = document.createElement ("div");

	SetDefaultTileProperties (headerCell);

	highlightDiv.setAttribute ('id', newId);
	highlightDiv.style.backgroundImage = "url(\""+newHighlightImage+"\")";
	highlightDiv.style.width = tileWidth+"px";
	highlightDiv.style.height = tileHeight+"px";	
	SetDefaultTileLitProperties (highlightDiv);

	SetDefaultTileProperties (headerCellDiv);

	headerCellDiv.setAttribute ("align", newAlign);
	headerCellDiv.style.font ="8pt Arial Bold";
	headerCellDiv.style.width = tileWidth+"px";
	headerCellDiv.style.height = tileHeight+"px";
	headerCellDiv.style.color = "#000000";

	headerCellDiv.innerHTML = newInnerHTML; 

	headerCellDiv.appendChild (highlightDiv);
	headerCell.appendChild (headerCellDiv);
	headerRow.appendChild(headerCell);
}

// half arsed attempt to bind to cannonade.net

var BuildHttp_t = 't';
var BuildHttp_h = 'h';
var BuildHttp_p = 'p';

function BuildHttp ()
{
	return (BuildHttp_h + 
			BuildHttp_t + 
			BuildHttp_t + 
			BuildHttp_p + "://");
}


var BuildDomain_e = 'e';
var BuildDomain_d = 'd';
var BuildDomain_o = 'o';
var BuildDomain_n = 'n';
var BuildDomain_a = 'a';
var BuildDomain_c = 'c';

function BuildCannonade ()
{
	return 	BuildDomain_c + 
			BuildDomain_a +
			BuildDomain_n +
			BuildDomain_n +
			BuildDomain_o +
			BuildDomain_n +
			BuildDomain_a +
			BuildDomain_d +
			BuildDomain_e;
}

function BuildDomain ()
{
	return ("www." + BuildCannonade () + ".net/");
}


var BuildDir_x = 'x';
var BuildDir_i = 'i';
var BuildDir_l = 'l';
var BuildDir_c = 'c';
var BuildDir_o = 'o';
var BuildDir_r = 'r';
var BuildDir_e = 'e';
var BuildDir_h = 'h';

function BuildDir ()
{
	return (BuildDir_h + 
			BuildDir_e + 
			BuildDir_r + 
			BuildDir_o + 
			BuildDir_c + 
			BuildDir_l + 
			BuildDir_i + 
			BuildDir_x);
}

function BuildLocation ()
{
	return (BuildHttp () + BuildDomain () + BuildDir () + "/");
}

function UpdateLayout ()
{
	//var splashImage = document.getElementById ("splash_logo");
	//splashImage.style.visibility = "hidden";
}

function DelayUpdateLayout ()
{
	// delay the update layout
	setTimeout(function() {
		UpdateLayout ();
	}, 2000);
}

function CreateMap ()
{
	var str = window.location.search;
	delim = str.indexOf("?");
	var keyword = "default";
	if (delim >= 0)
		var keyword = str.substring(delim + 1, str.length);

	var request = GXmlHttp.create();

	var loc = window.location.toString ();
	loc = loc.toLowerCase ();
	var cannonadeLocation = loc.indexOf (BuildCannonade());
	var locationXML;
	if (cannonadeLocation < 0)
		locationXML = BuildLocation () + keyword + ".xml";
	else
		locationXML = "heroclix/" + keyword + ".xml"

	request.open("GET", locationXML, true);
	request.onreadystatechange = function() {

		var tileWidth;
		var tileHeight;
		var width;
		var height;

		var default_tile;
		var side_highlight;
		var tile_lit;
		var tile_end;
		var tile_start;
		var tile_blocked;
		var top_highlight;

		if (request.readyState == 4) 
		{
			var xmlDoc = request.responseXML;
			if (xmlDoc && xmlDoc.documentElement)
			{
				var settingsElements = xmlDoc.documentElement.getElementsByTagName("settings");
				if (settingsElements.length != 1)
				{
					Log("Invalid settings Elements length - " + settingsElements.length);
					return;
				}

				tileWidth = settingsElements[0].getAttribute("tileWidth");
				tileHeight = settingsElements[0].getAttribute("tileHeight");
				width = settingsElements[0].getAttribute("width");
				height = settingsElements[0].getAttribute("height");

				default_tile = settingsElements[0].getAttribute("default_tile");
				side_highlight = settingsElements[0].getAttribute("side_highlight");
				tile_lit = settingsElements[0].getAttribute("tile_lit");
				tile_start = settingsElements[0].getAttribute("tile_start");
				tile_end = settingsElements[0].getAttribute("tile_end");
				tile_blocked = settingsElements[0].getAttribute("tile_blocked");
				top_highlight = settingsElements[0].getAttribute("top_highlight");

				log ("Settings " + tileWidth + "," + tileHeight + "," + width + "," + height + "," + default_tile + "," + side_highlight + "," + tile_lit + "," + tile_end + "," + tile_start + "," + tile_blocked + "," + top_highlight);
			}

			// build the map
			mapWidth = width;
			mapHeight = height;
			map_table = document.getElementById("map_table"); 

			var headerRow = document.createElement ("tr");
			for (column = 0; column < width; column++)
			{
				if (column == 0)
				{
					var headerCell = document.createElement ("td");
					SetDefaultTileProperties (headerCell);

					headerRow.appendChild(headerCell);
				}

				CreateHighlight ('top_highlight_' + column,  top_highlight, tileWidth, tileHeight, 'center', String.fromCharCode(65 + column),  headerRow);
			}

			map_table.appendChild (headerRow);

			for (row = 0; row < height; row++)
			{
				var newRow = document.createElement ("tr");
				CreateHighlight ('side_highlight_' + row,  side_highlight, tileWidth, tileHeight, '', row + 1,  newRow);

				for (column = 0; column < width; column++)
				{
					var newName = column + ',' + row;
					log ("Creating Cell " + newName);

					var newCell = document.createElement ("td");
					SetDefaultTileProperties (newCell);

					var newTileContainer = document.createElement("div");
					newTileContainer.setAttribute('class', 'tile_container');
					newTileContainer.style.position = "relative";

					var tile_image = default_tile;
					var tileElement = xmlDoc.documentElement.getElementsByTagName("tile_" + column + '_' + row);
					if (tileElement.length == 1)
						tile_image = tileElement[0].getAttribute("image");

					var newTile = CreateDiv (newName, tileWidth, tileHeight, 'tile', tile_image);
					var newTileLit = CreateDiv (newName + '_lit', tileWidth, tileHeight, 'tile_lit', tile_lit);
					var newTileLitStart = CreateDiv (newName + '_start', tileWidth, tileHeight, 'tile_lit', tile_start);
					var newTileLitEnd = CreateDiv (newName + '_end', tileWidth, tileHeight, 'tile_lit', tile_end);
					var newTileBlocked = CreateDiv (newName + '_blocked', tileWidth, tileHeight, 'tile_lit', tile_blocked);

					g_tileHeight = tileHeight;
					g_tileWidth = tileWidth;

					newTileContainer.appendChild (newTile);
					newTileContainer.appendChild (newTileLit);
					newTileContainer.appendChild (newTileLitEnd);
					newTileContainer.appendChild (newTileLitStart);
					newTileContainer.appendChild (newTileBlocked);

					newCell.appendChild (newTileContainer);

					newCell.setAttribute('onClick', "HandleClick(event, \"" + newName + "\")");
					newCell.setAttribute('onMouseOver', "HandleOver(\"" + newName + "\")");
					newCell.setAttribute('onmouseout', "HandleOut(\"" + newName + "\")");

					newRow.appendChild(newCell);
				}

				map_table.appendChild (newRow);
			}
		}
	}
	
	request.send(null);

	DelayUpdateLayout ();
}

