// JavaScript Document
// Nathan Toye 3-8-09
var Path = {
	/* see Daniel Pupius' article at 13thparallel.org for details on Bezier curves */
	coord: function (x,y) { if(!x) var x=0; if(!y) var y=0; return {x: x, y: y}; },
	B1: function(t) { return (t*t*t); },
	B2: function(t) { return (3*t*t*(1-t)); },
	B3: function(t) { return (3*t*(1-t)*(1-t)); },
	B4: function(t) { return ((1-t)*(1-t)*(1-t)); },
	getBezier: function(percent,C1,C2,C3,C4) {
		var pos = new Path.coord();
		pos.x = C1.x * Path.B1(percent) + C2.x * Path.B2(percent) +C3.x * Path.B3(percent) + C4.x * Path.B4(percent);
		pos.y = C1.y * Path.B1(percent) + C2.y * Path.B2(percent) + C3.y * Path.B3(percent) + C4.y * Path.B4(percent);
		return pos; 
	},
	getLine: function(percent, C1, C2) {
		var pos = new Path.coord();
		pos.x = C1.x + ((C2.x - C1.x) * percent);
		pos.y = C1.y + ((C2.y - C1.y) * percent);
		return pos;
	}
};
var Animate = {
	init: function (element, Z1, Z2, Z3, Z4){
		if (!Z3 && !Z4) {
			var line = true;
		}
		var curpos = 0;
		var speed = 0.01;
		var framerate = 25;
		var object = element;
		var stage = 0;
		this.move = function() {
			move();
		}
		function move() {
			if (stage > 1){
				if(!line){
					curpos = Path.getBezier(1, Z1, Z2, Z3, Z4);
				}else{
					if (Core.hasClass(object, "jsViewing")){
						curpos = Path.getLine(1, Z1, Z2);
					}else{
						curpos = FW.S1;
					}
				}
				object.style.left = Math.round(curpos.x) + "px";
				object.style.top = Math.round(curpos.y) + "px";
				return;
			} else {
				stage = stage + ((1-stage)*0.10) + speed;
			}
			if(!line){
				curpos = Path.getBezier(stage, Z1, Z2, Z3, Z4);
			}else{
				curpos = Path.getLine(stage, Z1, Z2);
			}
			object.style.left = Math.round(curpos.x) + "px";
			object.style.top = Math.round(curpos.y) + "px";
			object._timer = setTimeout(move, 1000 / framerate);
		}
	}
}; 
var FW = {
	init: function() {
		// Bezier entry path (is reversed P1 is end, P4 is start)
		FW.P1 = new Path.coord(210,139);
		FW.P2 = new Path.coord(150,0);
		FW.P3 = new Path.coord(0,0);
//		FW.P4 = new Path.coord(650,0);
		FW.P4 = new Path.coord(650,0);
		// Exit line (P1 above to E1)
//		FW.E1 = new Path.coord(210,500);
		FW.E1 = new Path.coord(210,500);
		// Set Control Points for Summary Windows
		FW.S1 = new Path.coord(-600, 0);
		FW.S2 = new Path.coord(0,0);
		// Set Start Control Point for List Window
//		FW.L1 = new Path.coord(0,380);
		// Target div
		FW.tDiv = document.getElementById("flyingWindowsTarget");
		FW.tDiv.id = "flyingWindows";
		// unhide all links
		var links = document.getElementsByTagName("a");
		for (var j = 0, m = links.length; j < m; j++){
			if (Core.hasClass(links[j], "hidden")){
				Core.removeClass(links[j], "hidden");
			}
		}
		// get main image buttons. set event listeners for the main buttons.
		var mainLinks = Core.getElementsByClass("mainLink");
		for (var i = 0, n = mainLinks.length; i < n; i++){
			// Grab each section that the images refer to and hide it.
			var href = mainLinks[i].getAttribute("href").split("#");
			var ref = href[1];
			var section = document.getElementById("js" + ref);
			// test to see if window has already been processed
			if (section.parentNode == FW.tDiv){
//				alert(i + " is a duplicate");
				Core.addEventListener(mainLinks[i], "click", FW.clickListener);
				continue;
			}
			FW.tDiv.appendChild(section);
			Core.addClass(section, "descriptionWindow");
			section.style.left = Math.round(FW.S1.x) + "px";
			FW.makeServiceWindow(section);
			Core.addEventListener(mainLinks[i], "click", FW.clickListener);
		}
		FW.closeInit();
		FW.intro();
	},
	closeInit: function(){
		var div = document.createElement("div");
		Core.addClass(div, "close");
		var para = document.createElement("p");
		var linkA = document.createElement("a");
		var linkTextA = document.createTextNode("Close Window");
		linkA.setAttribute("href", "#close");
		linkA.appendChild(linkTextA);
		para.appendChild(linkA);
		div.appendChild(para);
		FW.tDiv.appendChild(div);
		Core.addEventListener(linkA, "click", FW.closeWin);
	},
	closeWin: function(event){
		Core.preventDefault(event);
		var subs = Core.getElementsByClass("serviceWindow jsViewing");
		if (subs.length > 0){
			Core.removeClass(subs[0], "jsViewing");
			var remove = new Animate.init(subs[0], FW.P1, FW.E1);
			remove.move();
		}else{
			var mains = Core.getElementsByClass("descriptionWindow jsViewing");
			if (mains.length > 0){
				clearTimeout (mains[0]._timer)
				FW.tDiv.className = "";
				mains[0].style.left = Math.round(FW.S1.x) + "px";
				mains[0].style.top = Math.round(FW.S1.y) + "px";
				Core.removeClass(mains[0], "jsViewing");
				FW.intro("mainIntro");
			}
		}
	},
	intro: function(cs){
		var intro = document.getElementById("jsmainIntro");
		if (cs){
			Core.addClass(FW.tDiv, cs);
		}
		if (!(Core.hasClass(intro, "jsViewing"))){
			Core.addClass(intro, "jsViewing");
		}
		intro.style.top = 0 + "px";
		intro.style.left = 0 + "px";
	}, 
	clickListener: function(event) {
		Core.preventDefault(event);
		// determine if the click is a main or sub window
		var linkA = this.getAttribute("href").split("#");
		if (!Core.hasClass(this, "mainLink")){
			var inner = true;
			var id = linkA[1];
		} else {
			var id = "js" + linkA[1];
		}
		var serviceWindow = document.getElementById(id);
		// remove any previous elements that are no longer needed
		var onScreen = Core.getElementsByClass("jsViewing");
		for (var i = 0, n = onScreen.length; i < n; i++){
			// disable the click if the current window is already on screen
			if (id == onScreen[i].id){
				return;
			}
			clearTimeout (onScreen[i]._timer);
			if (Core.hasClass(onScreen[i], "serviceWindow")){
				Core.removeClass(onScreen[i], "jsViewing");
				var remove = new Animate.init(onScreen[i], FW.P1, FW.E1);
				remove.move();
			} else if (!inner) {
				FW.tDiv.className = "";
				onScreen[i].style.left = Math.round(FW.S1.x) + "px";
				onScreen[i].style.top = Math.round(FW.S1.y) + "px";
				Core.removeClass(onScreen[i], "jsViewing");
			}
		}
		Core.addClass(serviceWindow, "jsViewing");
		if (inner){
			var service = new Animate.init(serviceWindow, FW.P1, FW.P2, FW.P3, FW.P4);
		} else {
			// add background
			Core.addClass(FW.tDiv, id.slice(2));
			var service = new Animate.init(serviceWindow, FW.S1, FW.S2);
		}
		service.move();
	},
	makeServiceWindow: function(div) {
		var li = div.getElementsByTagName("li");
		if (li.length > 0){
			for (var i = 0, n = li.length; i < n; i++){
				var span = li[i].getElementsByTagName("span");
				var links = li[i].getElementsByTagName("a");
				Core.addEventListener(links[0], "click", FW.clickListener); 
				if (span.length > 0) {
					var liDiv = document.createElement("div");
					Core.addClass(liDiv, "serviceWindow");
//					liDiv.style.left = Math.round(FW.P4.x) + "px";
//					liDiv.style.top = Math.round(FW.P4.y) + "px";
					liDiv.style.left = Math.round(FW.S1.x) + "px";
					liDiv.style.top = Math.round(FW.S1.y) + "px";
					liDiv.id = span[0].id;
					span[0].id = "";
					liDiv.appendChild(span[0]);
					FW.tDiv.appendChild(liDiv);
				}
			}
		}
	}
};
Core.start(FW);
