/*
 *	Copyright (c) 2007, Thomas L. Robinson
 *	
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions
 *	are met:
 *	
 *	Redistributions of source code must retain the above copyright
 *	notice, this list of conditions and the following disclaimer.
 *	Redistributions in binary form must reproduce the above copyright
 *	notice, this list of conditions and the following disclaimer in the
 *	documentation and/or other materials provided with the distribution.
 *	Neither the name of the tlrobinson.net nor the names of its contributors
 *	may be used to endorse or promote products derived from this software
 *	without specific prior written permission.
 *	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *	A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 *	CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

var body, dock, title, icons;
var numIcons, pct, lastX, totalWidth, startY, old_D_SIZE, old_window_D_SIZE;
var D_SIZE, D_BIG_SIZE, D_MARGIN, W_MARGIN = 40;
var hovering		= false,
	clicked			= false,
	resizing		= false,
	animating		= false,
	window_resized	= false;
	
// Initialization
function initDock() {
	
	set_size(64); // MOD: default size of the unscaled icons
	
	window.addEventListener("resize", windowResize, false);
	document.addEventListener("selectstart", function(evt) { var e = evt || window.event; e.stopPropagation(); }, true);
	document.addEventListener("mousedown", function() { clicked = true; }, true);
	document.addEventListener("mouseup", function() { clicked = false; }, true);

	// assemble dock
	body = document.getElementsByTagName("body")[0];
	dock = document.getElementById("dock");
	var dock_outer = document.createElement("div");
	dock_outer.setAttribute("id", "dock-outerbg");
	var dock_inner = document.createElement("div");
	dock_inner.setAttribute("id", "dock-innerbg");
	dock_outer.appendChild(dock_inner);
	dock.appendChild(dock_outer);
	
	dock.setAttribute("onmousemove", "dockMouseOver(event);");
	dock.setAttribute("onmouseout", "dockMouseOut(event);");
	dock.setAttribute("onmousedown", "dockResizeBegin(event);");
	
	// prepare icons
	icons = dock.getElementsByTagName("img");
	numIcons = icons.length;
	for (var i = 0; i < numIcons; i++) {
		icons[i].setAttribute("onmousemove", "dockMouseOver(event);");
		icons[i].setAttribute("onmouseout", "dockMouseOut(event);");
		icons[i].setAttribute("onselectstart", "return false;");
		icons[i].setAttribute("class", "icon");
		icons[i].iconNum = i;
	}
	
	// assemble title
	title = document.createElement("div");
	title.setAttribute("id", "dock-title");
	title.style.display = "none";
	body.appendChild(title);
	
	windowResize(); // reset dock and fit to the window if too big
}

// Utility functions:

function set_size(size) {
	if (size < 16) size = 16;			// MOD: min icon size
	else if (size > 128) size = 128;	// MOD: max icon size
	D_SIZE = size;						// MOD: icon size when not magnified, set to a constant to disable resizing
	D_BIG_SIZE = 2 * D_SIZE;			// MOD: icon max size when magnified, set to D_SIZE to disable magnification
	D_MARGIN = D_SIZE / 5;				// MOD: padding between icons
}

function fitToWindow() {
	set_size((window.innerWidth - W_MARGIN - D_MARGIN - icons.length * D_MARGIN) / icons.length);
}

function calcTotalWidth() {
	return icons.length * (D_SIZE + D_MARGIN) + D_MARGIN;
}

// Calculate and update icon sizes when hovering:

function dockUpdate(xposition, scale) {
	// calculate location of mouse along (old) dock
	var loc = xposition - ((window.innerWidth - totalWidth) / 2) - D_MARGIN - 32;
	
	// calculate positions and move icons
	var totalWidthTemp = 0;
	var CONST1 = loc - (D_SIZE/2), CONST2 = D_SIZE+D_MARGIN;
	for (var i = 0; i < numIcons; i++) {
		var amount = Math.abs(CONST1 - CONST2*i) / 2;
		if (scale != 1.0)
			amount = D_SIZE + scale * (amount - D_SIZE)
		
		var width = D_BIG_SIZE - amount;
		var nextWidth = icons[i].nextWidth = (width > D_SIZE) ? width : D_SIZE;
	
		icons[i].style.left   = (totalWidthTemp+D_MARGIN) + "px";
		icons[i].style.height = icons[i].style.width  = nextWidth + "px";
		
		totalWidthTemp += nextWidth + D_MARGIN;
	}
	
	// calculate margins and move dock
	totalWidth = totalWidthTemp + D_MARGIN;
	var margins = (window.innerWidth - totalWidth) / 2;
	
	dock.style.height = (D_SIZE+15) + "px";
	dock.style.width = totalWidth + "px";
	dock.style.left = margins + "px";
	
	// MOD: comment out this whole section to disable titles
	totalWidthTemp = margins + D_MARGIN;
	for (var i = 0; i < numIcons; i++) {
		nextWidth = icons[i].nextWidth;
		if (xposition > totalWidthTemp && xposition < (totalWidthTemp+nextWidth)) {
			title.style.left = (totalWidthTemp + (nextWidth / 2) - 100) + "px";
			title.style.bottom = (8 + 2*D_SIZE) + "px";
			title.innerHTML = icons[i].getAttribute("alt");
			break;
		}
		totalWidthTemp += nextWidth + D_MARGIN;
	}
}

// Reset dock to normal size when not hovering:

function resetDock() {
	totalWidth = calcTotalWidth();
	
	var margins = (window.innerWidth - totalWidth) / 2;
	
	dock.style.height = (D_SIZE+15) + "px";
	dock.style.width = totalWidth + "px";
	dock.style.left = margins + "px";
	
	for (var i = 0; i < numIcons; i++) {
		icons[i].style.left = (D_MARGIN + (D_SIZE + D_MARGIN) * i) + "px";
		icons[i].style.width = D_SIZE+"px";
		icons[i].style.height = D_SIZE+"px";
	}
}

// Event handlers:

// dock clicked to begin resizing
function dockResizeBegin(evt) {
	var e = evt || window.event;
	e.stopPropagation();
	e.preventDefault();
	
	resizing = true;
	body.addEventListener("mousemove", dockResizing, false);
	body.addEventListener("mouseup", dockResizeEnd, false);
	body.setAttribute("onselectstart", "return false;");
	
	startY = e.clientY;
	old_D_SIZE = D_SIZE;
	
	startAnimateOut();
}

// mouse up after resize
function dockResizeEnd(evt) {
	var e = evt || window.event;
	e.stopPropagation();
	e.preventDefault();
	
	resizing = false;
	body.removeEventListener("mousemove", dockResizing, false);
	body.removeEventListener("mouseup", dockResizeEnd, false);
	body.removeAttribute("onselectstart");
	
	if (hovering)
		startAnimateIn();
}

// mouse move during resize
function dockResizing(evt) {
	var e = evt || window.event;
	e.stopPropagation();
	e.preventDefault();
	
	if (clicked == false) {
		dockResizeEnd();
		resetDock();
	} else {
		set_size(old_D_SIZE + (startY - e.clientY));
		if ((window.innerWidth - W_MARGIN) < calcTotalWidth())
			fitToWindow();
		resetDock();
	}
}

// window resized
function windowResize() {
	if ((window.innerWidth - W_MARGIN) < calcTotalWidth()) {
		if (!window_resized) {
			old_window_D_SIZE = D_SIZE;
			window_resized = true;
		}
		fitToWindow();
	} else {
		if (window_resized) {
			if (old_window_D_SIZE <= D_SIZE) {
				set_size(old_window_D_SIZE);
				window_resized = false;
			} else {
				fitToWindow();
			}
		}
	}
	resetDock();
}

// MOD: replace calls to startAnimateIn() and startAnimateOut() in the following
// two functions with resetDock() to disable animation.

// mouse moving over dock or dock icons
function dockMouseOver(evt) {
	var e = evt || window.event;
	lastX = e.clientX;
	
	if (!animating && hovering && !resizing)
		dockUpdate(lastX, 1.0);
	else if (!hovering && !animating) {
		if (!resizing)
			startAnimateIn(); // resetDock();
		hovering = true;
	}
}

// mouse leaving dock and dock icons
function dockMouseOut(evt) {
	var e = evt || window.event;
	
	if (e == null || e.type == "resize" || (e.type == "mouseout" && (
		(e.relatedTarget.tagName != "IMG" && e.relatedTarget.id.substr(0,4) != "dock") ||
		(e.relatedTarget.tagName == "IMG" && e.relatedTarget.className != "icon")))) {
			// TODO: figure out why sometimes this doesn't get called
			if (!resizing)
				startAnimateOut(); // resetDock();
			hovering = false;
	}
}


// Animation

var animInterval;

function startAnimateIn() {
	pct = 0.0;
	animating = true;
	window.clearInterval(animInterval);
	animInterval = window.setInterval("animateIn()", 0.05);
		
	title.style.display = "block";
}

function startAnimateOut() {
	pct = 1.0;
	animating = true;
	window.clearInterval(animInterval);
	animInterval = window.setInterval("animateOut()", 0.05);
		
	title.style.display = "none";
}

function animateIn() {
	if (pct < 1.0) {
		dockUpdate(lastX, pct);
		pct += 0.2;
	} else {
		window.clearInterval(animInterval);
		animating = false;
	}
}

function animateOut() {
	if (pct > 0.0) {
		dockUpdate(lastX, pct);
		pct -= 0.2;
	} else {
		window.clearInterval(animInterval);
		resetDock();
		animating = false;
	}
}

// Initialization stuff. Customize for your own environment.

// add our init function to window.onload while saving any previous ones
var oldonload = window.onload;
if (typeof window.onload != 'function') {
	window.onload = initDock;
} else {
	window.onload = function() {
		if (oldonload) {
			oldonload();
		}
		initDock();
	}
}

// write the stylesheet tag to the document, so it gets loaded
//document.write('<link rel="stylesheet" type="text/css" href="/dock/dock.css" />');


