var currentHeight = "";
var currentWidth  = "";

var goldenRatio = (1 + Math.sqrt(5)) / 2;

var userShape;
var innerTxRect, outerTxRect;

var highlightTimer;
var highlightElemID;

function UpdateVisualization()
{
	var changesMade = false;
	
	var formWidth = document.getElementById("WidthValue");
	var formHeight = document.getElementById("HeightValue");
	
	if (formWidth.value != currentWidth)
	{
		changesMade = true;
		currentWidth = formWidth.value;
	}
	if (formHeight.value != currentHeight)
	{
		changesMade = true;
		currentHeight = formHeight.value;
	}
	
	if (ValidateChanges())
		RenderVisualization();
}

function ValidateChanges()
{
	var widthInvalid = (currentWidth == null || currentWidth.length == 0 || isNaN(currentWidth) || parseInt(currentWidth) <= 0);
	var heightInvalid = (currentHeight == null || currentHeight.length == 0 || isNaN(currentHeight) || parseInt(currentHeight) <= 0);
	
	document.getElementById("WidthValue").style.backgroundColor = (widthInvalid) ? "#DDB3B3" : "#BDDDB3";
	document.getElementById("HeightValue").style.backgroundColor = (heightInvalid) ? "#DDB3B3" : "#BDDDB3";
	
	return !(widthInvalid || heightInvalid);
}

function RenderVisualization()
{
	var visualization = document.getElementById("VisualizationContainer");	
	var details = document.getElementById("VisualizationDetails");
	
	var visWindow = new Rectangle(parseInt(visualization.offsetWidth) - 16, parseInt(visualization.offsetHeight) - 4);
	userShape = new Rectangle(Math.round(parseFloat(currentWidth)), Math.round(parseFloat(currentHeight)));
	
	var grRect1 = new Rectangle(userShape.width, userShape.GetGrHeight());
	var grRect2 = new Rectangle(userShape.GetGrWidth(), userShape.height);
	
	var maxWidth = GetMax(userShape.width, grRect1.width, grRect2.width);
	var maxHeight = GetMax(userShape.height, grRect1.height, grRect2.height);
	
	var widthScale = 1;
	var heightScale = 1;
	var scale = 1;
	
	if (maxWidth > visWindow.width)
		widthScale = visWindow.width / maxWidth;
	if (maxHeight > visWindow.height)
		heightScale = visWindow.height / maxHeight;
	
	scale = GetMin(widthScale, heightScale);
	
	if (scale < 1)
	{
		userShape.ScaleTo(scale);
		grRect1.ScaleTo(scale);
		grRect2.ScaleTo(scale);
	}
	
	if ((grRect1.width <= userShape.width && grRect1.height == userShape.height) || 
	    (grRect1.height <= userShape.height && grRect1.width == userShape.width))
	{
		innerTxRect = grRect1;
		outerTxRect = grRect2;
	}
	else
	{
		innerTxRect = grRect2;
		outerTxRect = grRect1;
	}
	
	var visHtml = "";
	
	visHtml += userShape.ToHtml(85, 20, "#999999", "#C4C4C4");
	visHtml += innerTxRect.ToHtml(85, 30, "#3B515B", "#4A6774");
	visHtml += outerTxRect.ToHtml(85, 10, "#D5620F", "#F29350");
	
	visualization.innerHTML = visHtml;
	
	if (scale < 1)
		document.getElementById("ScaleValue").innerHTML = scale.toFixed(2) + "px = 1px";
	else
		document.getElementById("ScaleValue").innerHTML = "1px = 1px";
	
	var detailsHtml = "";
	
	detailsHtml += "<table align=\"center\">";
	detailsHtml += "<tr>";
	
	detailsHtml += "<td valign=\"middle\" align=\"center\" width=\"10\" style=\"background-color: #C4C4C4; border: 1px solid #999999;\" onmouseover=\"HighlightVis('" + userShape.width + "-" + userShape.height + "');\" onmouseout=\"UnhighlightVis();\">&nbsp;</td>";
	detailsHtml += "<td width=\"155\" style=\"padding-left: 3px;\" onmouseover=\"HighlightVis('" + userShape.width + "-" + userShape.height + "');\" onmouseout=\"UnhighlightVis();\">";
	detailsHtml += "<strong>Your Shape</strong>";
	detailsHtml += "<br />";
	detailsHtml += "Dimensions: " + userShape.width + " &times; " + userShape.height;
	detailsHtml += "<br />";
	detailsHtml += "Side Ratio: " + userShape.GetSideRatio().toFixed(5);
	detailsHtml += "<br />";
	detailsHtml += "Area: " + userShape.GetArea().toFixed(0);
	detailsHtml += "</td>";
	
	detailsHtml += "<td valign=\"middle\" align=\"center\" width=\"10\" style=\"background-color: #4A6774; border: 1px solid #3B515B;\" onmouseover=\"HighlightVis('" + innerTxRect.width + "-" + innerTxRect.height + "');\" onmouseout=\"UnhighlightVis();\">&nbsp;</td>";
	detailsHtml += "<td width=\"155\" style=\"padding-left: 3px;\" onmouseover=\"HighlightVis('" + innerTxRect.width + "-" + innerTxRect.height + "');\" onmouseout=\"UnhighlightVis();\">";
	detailsHtml += "<strong>Largest Internal G.R.</strong>";
	detailsHtml += "<br />";
	detailsHtml += "Dimensions: " + innerTxRect.width + " &times; " + innerTxRect.height;
	detailsHtml += "<br />";
	detailsHtml += "Side Ratio: " + innerTxRect.GetSideRatio().toFixed(5);
	detailsHtml += "<br />";
	detailsHtml += "Area: " + innerTxRect.GetArea().toFixed(0);
	detailsHtml += "</td>";
	
	detailsHtml += "<td valign=\"middle\" align=\"center\" width=\"10\" style=\"background-color: #F29350; border: 1px solid #D5620F;\" onmouseover=\"HighlightVis('" + outerTxRect.width + "-" + outerTxRect.height + "');\" onmouseout=\"UnhighlightVis();\">&nbsp;</td>";
	detailsHtml += "<td width=\"155\" style=\"padding-left: 3px;\" onmouseover=\"HighlightVis('" + outerTxRect.width + "-" + outerTxRect.height + "');\" onmouseout=\"UnhighlightVis();\">";
	detailsHtml += "<strong>Closest External G.R.</strong>";
	detailsHtml += "<br />";
	detailsHtml += "Dimensions: " + outerTxRect.width + " &times; " + outerTxRect.height;
	detailsHtml += "<br />";
	detailsHtml += "Side Ratio: " + outerTxRect.GetSideRatio().toFixed(5);
	detailsHtml += "<br />";
	detailsHtml += "Area: " + outerTxRect.GetArea().toFixed(0);
	detailsHtml += "</td>";
	
	detailsHtml += "</tr>";
	detailsHtml += "</table>";
	
	details.innerHTML = detailsHtml;
}

function GetMax()
{
	var max = -1;
	
	for (var n = 0, l = arguments.length; n < l; n++)
		if (arguments[n] > max)
			max = arguments[n];
	
	return max;
}

function GetMin()
{
	var min = 10000000000;
	
	for (var n = 0, l = arguments.length; n < l; n++)
		if (arguments[n] < min)
			min = arguments[n];
	
	return min;
}

function HighlightVis(elemID)
{
	clearTimeout(highlightTimer);
	
	if (highlightElemID && elemID != highlightElemID)
		UpdateVisualization();
	
	highlightElemID = elemID;
	
	document.getElementById(elemID).style.borderColor = "#5EB557";
	document.getElementById(elemID).style.borderWidth = "2px";
	document.getElementById(elemID).style.zIndex = "100";
	document.getElementById(elemID).style.opacity = "1";
	document.getElementById(elemID).style.filter = "alpha(opacity=100)";
}

function UnhighlightVis(elemID)
{
	highlightTimer = setTimeout("UpdateVisualization();", 100);
}

function Rectangle(width, height)
{
	this.width = width;
	this.height = height;
	
	this.scaledWidth = this.width;
	this.scaledHeight = this.height;
}
Rectangle.prototype.GetSideRatio = function()
{
	if (this.width > this.height)
		return this.width / this.height;
	
	return this.height / this.width;
}
Rectangle.prototype.GetArea = function()
{
	return this.width * this.height;
}
Rectangle.prototype.GetGrWidth = function()
{
	if (this.width > this.height)
		return Math.round(this.height * goldenRatio);
	
	return Math.round(this.height / goldenRatio);
}
Rectangle.prototype.GetGrHeight = function()
{
	if (this.height > this.width)
		return Math.round(this.width * goldenRatio);
	
	return Math.round(this.width / goldenRatio);
}
Rectangle.prototype.ScaleTo = function(scale)
{
	this.scaledWidth = Math.floor(this.width * scale);
	this.scaledHeight = Math.floor(this.height * scale);
}
Rectangle.prototype.ToHtml = function(opacity, zIndex, color1, color2)
{
	if (!opacity) opacity = 25;
	if (!zIndex) zIndex = 1;
	if (!color1) color1 = "#000000";
	if (!color2) color2 = "#999999";
	
	var html = "";
	
	html += "<div id=\"" + this.width + "-" + this.height + "\" style=\"position: absolute; top: 0px; left: 4px; width: " + this.scaledWidth + "px; height: " + this.scaledHeight + "px; z-index: " + zIndex + "; opacity: " + (opacity / 100) + "; filter: alpha(opacity=" + opacity + "); border: 1px solid " + color1 + "; background-color: " + color2 + ";\">&nbsp;</div>";
	
	return html
}