


//*-----------------------------------------------------------------------------------
//*  
//*  Based on: Prototype JavaScript framework, version 1.4.0
//*  (c) 2005 Sam Stephenson <sam@conio.net>
//*
//*  Prototype is freely distributable under the terms of an MIT-style license.
//*  For details, see the Prototype web site: http://prototype.conio.net/
//*
//*  Note: stripped down version of prototype by mad4milk (http://moofx.mad4milk.net).
//*  
//*-----------------------------------------------------------------------------------

var Class = {
	create: function() {
		return function() { this.initialize.apply(this, arguments); };
	}
};

Object.extend = function(destination, source) {
	for (var property in source) { if(source) { destination[property] = source[property]; } }
	return destination;
};

var $A = function(iterable) {
	var nArray = [];
	for (var i = 0; i < iterable.length; i++) { nArray.push(iterable[i]); }
	return nArray;
};

function $() {
	function get$(el) {
		if (typeof el == 'string') { el = document.getElementById(el); }
		return el;
	}
	if (arguments.length == 1) { return get$(arguments[0]); }
	var elements = [];
	$A(arguments).each( function(el) { elements.push(get$(el)); } );
	return elements;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() { return __method.apply(object, arguments); };
};

Function.prototype.bindAsEventListener = function() {
	var __method = this, args = $A(arguments), object = args.shift();
	return function(event) { return __method.apply(object, [event || window.event].concat(args)); };
};

Array.prototype.each = Array.prototype.forEach;


/*gsb - Use iui.hasClass  ... unused ... 
if (!window.Element) { var Element = {}; }

Object.extend(Element, {

	remove: function(element) {
		element = $(element);
		element.parentNode.removeChild(element);
	}

	hasClassName: function(element, className) {
		element = $(element);
		return !!element.className.match(new RegExp("\\b"+className+"\\b"));
	},

	addClassName: function(element, className) {
		element = $(element);
		if (!Element.hasClassName(element, className)) { element.className = (element.className+' '+className); }
	},

	removeClassName: function(element, className) {
		element = $(element);
		if (Element.hasClassName(element, className)) {
			element.className = element.className.replace(className, '');
		}
	}
});

document.getElementsByClassName = function(className) {
	var elements = [];
	var all = document.getElementsByTagName('*');
	$A(all).each( function(el)
		{ if(iui.hasClass(el, className)) { elements.push(el); } } );
	return elements;
};
... unused ... */

/*--------------------------------------------------------------------------*/

(function() {

	var slideSpeed = 20;
	var slideInterval = 0;

	var currentPage = null;
	var currentDialog = null;
	var currentWidth = 0;
	var currentHash = location.hash;
	var hashPrefix = "#_";
	var pageHistory = [];
	var newPageCount = 0;
	var checkTimer;
	var hasOrientationEvent = false;
	var portraitVal = "portrait";
	var landscapeVal = "landscape";
	var basis = document.getElementsByTagName('body')[0];

	/***************************************************************************************************/

	window.iui =
	{
		animOn: true,

		httpHeaders: { "X-Requested-With" : "XMLHttpRequest" },

		showPage: function(page, backwards)
		{
			if (page)
			{
				/*if (window.iui_ext) window.iui_ext.injectEventMethods(page); TG */

				if (currentDialog)
				{
					currentDialog.removeAttribute("selected");
					// EVENT blur->currentDialog
					sendEvent("blur", currentDialog);
					currentDialog = null;
				}

				if (hasClass(page, "dialog"))
				{
					// EVENT focus->page
					sendEvent("focus", page);
					showDialog(page);
				}
				else
				{
					sendEvent("load", page);    // 127(stylesheet), 128(script), 129(onload)
												// 130(onFocus), 133(loadActionButton)
					var fromPage = currentPage;
					// EVENT blur->currentPage
					sendEvent("blur", currentPage);
					currentPage = page;
					// EVENT focus->currentPage
					sendEvent("focus", page);

					// adjust footer... argh!
					// dirty hack to move the footer to proper location since
					// iPhone does not re-evaluate the CSS.  So,
					// ...simply force an element height adjustment.
					if( document.body.getAttribute("orient") == landscapeVal ) { 
						currentPage.style.minHeight = "225px";
						currentPage.style.maxWidth= "480px";
					} else {
						currentPage.style.minHeight = "385px";
						currentPage.style.maxWidth= "320px";
					}
					setTimeout( function() {
							$('footer').style.top = (currentPage.offsetHeight-20)+"px";
							$('footer').style.display = "block";
						}, 10);


					if (fromPage)
					{
						if (backwards) { sendEvent("unload", fromPage); }
						setTimeout(slidePages, 0, fromPage, page, backwards);
					}
					else { updatePage(page, fromPage); }
				}
			}
		},

		showPageById: function(pageId)
		{
			var page = $(pageId);
			if (page)
			{
				var index = pageHistory.indexOf(pageId);
				var backwards = index != -1;
				if (backwards) { pageHistory.splice(index, pageHistory.length); }
				iui.showPage(page, backwards);
			}
		},

		showPageByHref: function(href, args, method, replace, cb)
		{
			function spbhCB(xhr) 
			{
				if (xhr.readyState == 4)
				{
					var frag = document.createElement("div");
					frag.innerHTML = xhr.responseText;
					sendEvent("beforeinsert", document.body, {fragment:frag} );
					if (replace)
					{
						replaceElementWithFrag(replace, frag);
					}
					else
					{
						iui.insertPages(frag);
					}
					if (cb) { setTimeout(cb, 1000, true); }
				}
			}
			iui.ajax(href, args, method, spbhCB);
		},

		ajax: function(url, args, method, cb)
		{
			var xhr = new XMLHttpRequest();
			method = method ? method.toUpperCase() : "GET";
			if (args && method == "GET")
			{
				url =  url + "?" + iui.param(args);
			}
			xhr.open(method, url, true);
			if (cb)
			{
				xhr.onreadystatechange = function() { cb(xhr); };
			}

			var data = null;
			if (args && method != "GET")
			{
				xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				data = iui.param(args);
			}

			for (var header in iui.httpHeaders)
			{
				if(header) { xhr.setRequestHeader(header, iui.httpHeaders[header]); }
			}
			xhr.send(data);
		},

		param: function( o )
		{
			var s = [];
			for ( var key in o )
			{ 
				if(s) { s[ s.length ] = encodeURIComponent(key) + '=' + encodeURIComponent(o[key]); }
			}
			return s.join("&").replace(/%20/g, "+");
		},

		insertPages: function(frag)
		{
			var nodes = frag.childNodes;
			var targetPage;
			for (var i = 0; i < nodes.length; ++i)
			{
				var child = nodes[i];
				if (child.nodeType == 1)
				{
					if (!child.id) { child.id = "__" + (++newPageCount) + "__"; }
					var clone = $(child.id);
					var docNode;
					if (clone)
					{
						clone.parentNode.replaceChild(child, clone);
						docNode = $(child.id);
					}
					else { docNode = document.body.appendChild(child); }
					sendEvent("afterinsert", document.body, {insertedNode:docNode});   
					if (child.getAttribute("selected") == "true" || !targetPage) { targetPage = child; }
					i=i-1;
				}
			}
			if (targetPage) { iui.showPage(targetPage); }
		},

		getSelectedPage: function()
		{
			for (var child = document.body.firstChild; child; child = child.nextSibling)
			{
				if (child.nodeType == 1 && child.getAttribute("selected") == "true") { return child; }
			}
			return null;
		},

		isNativeUrl: function(href)
		{
			for(var i = 0; i < iui.nativeUrlPatterns.length; i++)
			{
				if(href.match(iui.nativeUrlPatterns[i])) { return true; }
			}
			return false;
		},

		nativeUrlPatterns: [
			new RegExp("^http:\\/\\/maps\\.google\\.com\\/maps\\?"),
			new RegExp("^mailto:"),
			new RegExp("^tel:"),
			new RegExp("^http:\\/\\/www\\.youtube\\.com\\/watch\\?v="),
			new RegExp("^http:\\/\\/www\\.youtube\\.com\\/v\\/"),
			new RegExp("^javascript:")
		],

		hasClass: function(self, name)
		{
			var re = new RegExp("(^|\\s)"+name+"($|\\s)");
			return re.exec(self.getAttribute("class")) !== null;
		},

		addClass: function(self, name)
		{
			if (!iui.hasClass(self,name)) { self.className += " "+name; }
		},

		removeClass: function(self, name)
		{
			if (iui.hasClass(self,name)) {
				var reg = new RegExp('(\\s|^)'+name+'(\\s|$)');
				self.className=self.className.replace(reg,' ');
			}
		},

		remove: function(self) { /*gsb added... */
			if(typeof self == "string") { self = $(self); }
			self.parentNode.removeChild(self);
		}

	};

// *************************************************************************************************

	addEventListener("load", function(event)
	{
		var page = iui.getSelectedPage();
		var locPage = getPageFromLoc();

		if (page) { iui.showPage(page); }

		if (locPage && (locPage != page)) { iui.showPage(locPage); }

		setTimeout(preloadImages, 0);

		if (typeof window.onorientationchange == "object")
		{
			window.onorientationchange=orientChangeHandler;
			hasOrientationEvent = true;
			setTimeout(orientChangeHandler, 0);
		}

		setTimeout(checkOrientAndLocation, 0);
		checkTimer = setInterval(checkOrientAndLocation, 300);
	}, false);

	addEventListener("unload", function(event) { return; }, false);

	addEventListener("click", function(event)
	{
		function unselect() { link.removeAttribute("selected"); }

		var link = findParent(event.target, "a");
		if (link)
		{

			if (link.href && link.hash && link.hash != "#" && !link.target)
			{
				link.setAttribute("selected", "true");
				iui.showPage($(link.hash.substr(1)));
				setTimeout(unselect, 500);
			}
			else if (link == $("backButton"))
			{
				history.back();
			}
			else if (link.getAttribute("type") == "submit")
			{
				var form = findParent(link, "form");
				if (form.target == "_self")
				{
					form.submit();
					return;  // allow default
				}
				submitForm(form);
			}
			else if (link.getAttribute("type") == "cancel")
			{
				cancelDialog(findParent(link, "form"));
			}
			else if (link.target == "_replace")
			{
				link.setAttribute("selected", "progress");
				iui.showPageByHref(link.href, null, "GET", link, unselect);
			}
			else if (iui.isNativeUrl(link.href))
			{
				return;
			}
			else if (link.target == "_webapp")
			{
				location.href = link.href;
			}
			else if (!link.target)
			{
				link.setAttribute("selected", "progress");
				iui.showPageByHref(link.href, null, "GET", null, unselect);
			}
			else { return; }

			event.preventDefault();			 
		}
	}, true);

	addEventListener("click", function(event)
	{
		var div = findParent(event.target, "div");
		if (div && hasClass(div, "toggle"))
		{
			div.setAttribute("toggled", div.getAttribute("toggled") != "true");
			event.preventDefault();			 
		}
	}, true);


	function sendEvent(type, node, props)
	{
		if (node)
		{
			var event = document.createEvent("UIEvent");
			event.initEvent(type, false, false);  // no bubble, no cancel
			for (var i in props) { if (props) {  event[i] = props[i]; } }
			node.dispatchEvent(event);
		}
	}

	function getPageFromLoc()
	{
		var page;
		var result = location.hash.match(/#_([^\?_]+)/);
		if (result) { page = result[1]; }
		if (page) { page = $(page); }
		return page;
	}

	function orientChangeHandler()
	{
		var orientation=window.orientation;
		switch(orientation)
		{
		case 0:
			setOrientation(portraitVal);
			break;	

		case 90:
		case -90: 
			setOrientation(landscapeVal);
			break;
		}
	}


	function checkOrientAndLocation()
	{
		if (!hasOrientationEvent)
		{
			if (window.innerWidth != currentWidth)
			{		
				currentWidth = window.innerWidth;
				var orient = currentWidth == 320 ? portraitVal : landscapeVal;
				setOrientation(orient);
			}
		}

		if (location.hash != currentHash)
		{
			var pageId = location.hash.substr(hashPrefix.length);
			iui.showPageById(pageId);
		}
	}

	function setOrientation(orient)
	{
		document.body.setAttribute("orient", orient);
		// dirty hack to move the footer to proper location since
		// iPhone does not re-evaluate the CSS.  So,
		// ...simply force an element height adjustment.
		if( orient == landscapeVal ) { 
			currentPage.style.minHeight = "225px";
			currentPage.style.maxWidth= "480px";
		} else {
			currentPage.style.minHeight = "385px";
			currentPage.style.maxWidth= "320px";
		}
		setTimeout(scrollTo, 100, 0, 1);
		setTimeout( function(p) {  //adjust footer... argh!
				$('footer').style.top = (currentPage.offsetHeight-20)+"px";
				$('footer').style.display = "block";
			}, 10, currentPage);
	}

	function showDialog(page)
	{
		currentDialog = page;
		page.setAttribute("selected", "true");

		if (hasClass(page, "dialog")) { showForm(page); }
	}

	function showForm(form)
	{

		// Walking through this code on 9/28 shows that neither
		// submitForm or cancelDialog is called here, but 
		// submitForm seems to be called elsewhere and so does
		// removeAttribute("selected")

		form.onsubmit = function(event)
		{
			// submitForm and preventDefault seem to be called in the click handler
			// so we don't need to call them again here

			// event.preventDefault();
			// submitForm(form);
		};

		form.onclick = function(event)
		{
			if (event.target == form && hasClass(form, "dialog")) { cancelDialog(form); }
		};
	}

	function cancelDialog(form)
	{
		form.removeAttribute("selected");
	}

	function updatePage(page, fromPage)
	{
		if (!page.id) { page.id = "__" + (++newPageCount) + "__"; }

		location.hash = currentHash = hashPrefix + page.id;
		pageHistory.push(page.id);

		var pageTitle = $("pageTitle");
		if (page.title) { pageTitle.innerHTML = page.title; }
		var ttlClass = page.getAttribute("ttlclass");
		pageTitle.className = ttlClass ? ttlClass : "";

		if (page.localName.toLowerCase() == "form" && !page.target) { showForm(page); }

		var backButton = $("backButton");
		var aboutButton = $("aboutButton");
		if (backButton)
		{
			var prevPage = $(pageHistory[pageHistory.length-2]);
			if (prevPage && !page.getAttribute("hideBackButton"))
			{
				aboutButton.style.display = "none";
				backButton.style.display = "inline";
				backButton.innerHTML = (prevPage.id == "home") ? "Home" : (prevPage.title ? prevPage.title : "Back");
				var bbClass = prevPage.getAttribute("bbclass");
				backButton.className = (bbClass) ? 'button ' + bbClass : 'button';
			}
			else
			{
				aboutButton.style.display = "inline";
				backButton.style.display = "none";
			}
		}	 
	}

	function slidePages(fromPage, toPage, backwards)
	{
		function slideDone()
		{
			if (!hasClass(toPage, "dialog")) { fromPage.removeAttribute("selected"); }
			checkTimer = setInterval(checkOrientAndLocation, 300);
			setTimeout(updatePage, 0, toPage, fromPage);
			fromPage.removeEventListener('webkitTransitionEnd', slideDone, false);
			sendEvent("aftertransition", fromPage, {out:true});
			sendEvent("aftertransition", toPage, {out:false});
		}
	 
		var axis = (backwards ? fromPage : toPage).getAttribute("axis");

		clearInterval(checkTimer);

		sendEvent("beforetransition", fromPage, {out:true});
		sendEvent("beforetransition", toPage, {out:false});
		if (canDoSlideAnim() && axis != 'y')
		{
			slide2(fromPage, toPage, backwards, slideDone);
		}
		else
		{
			slide1(fromPage, toPage, backwards, axis, slideDone);
		}
	}

	function canDoSlideAnim()
	{
		return (iui.animOn) && (typeof WebKitCSSMatrix == "object");
	}

	function slide1(fromPage, toPage, backwards, axis, cb)
	{
		function slide()
		{
			percent -= slideSpeed;
			if (percent <= 0)
			{
				percent = 0;
				clearInterval(timer);
				cb();
			}

			if (axis == "y")
			{
				if(backwards) { fromPage.style.top = (100-percent) + "%";}
				else { toPage.style.top = percent + "%"; }
			}
			else
			{
				fromPage.style.left = (backwards ? (100-percent) : (percent-100)) + "%"; 
				toPage.style.left = (backwards ? -percent : percent) + "%"; 
			}
		}

		if (axis == "y") { (backwards ? fromPage : toPage).style.top = "100%"; }
		else { toPage.style.left = "100%"; }

		scrollTo(0, 1);
		toPage.setAttribute("selected", "true");
		var percent = 100;
		slide();
		var timer = setInterval(slide, slideInterval);
	}


	function slide2(fromPage, toPage, backwards, cb)
	{
		toPage.style.webkitTransitionDuration = '0ms'; // Turn off transitions to set toPage start offset
		// fromStart is always 0% and toEnd is always 0%
		// iPhone won't take % width on toPage
		var toStart = 'translateX(' + (backwards ? '-' : '') + window.innerWidth +	'px)';
		var fromEnd = 'translateX(' + (backwards ? '100%' : '-100%') + ')';
		toPage.style.webkitTransform = toStart;
		toPage.setAttribute("selected", "true");
		toPage.style.webkitTransitionDuration = ''; // Turn transitions back on
		function startTrans()
		{
			fromPage.style.webkitTransform = fromEnd;
			toPage.style.webkitTransform = 'translateX(0%)'; //toEnd
		}
		fromPage.addEventListener('webkitTransitionEnd', cb, false);
		setTimeout(startTrans, 0);
	}

	function preloadImages()
	{
		var preloader = document.createElement("div");
		preloader.id = "preloader";
		document.body.appendChild(preloader);
	}

	function submitForm(form)
	{
		function clear() { iui.removeClass(form, "progress"); }
		iui.addClass(form, "progress");
		iui.showPageByHref(form.action, encodeForm(form), form.method || "GET", null, clear);
	}

	function encodeForm(form)
	{
		function encode(inputs)
		{
			for (var i = 0; i < inputs.length; ++i)
			{
				  if (inputs[i].name) { args[inputs[i].name] = inputs[i].value; }
			}
		}

		var args = {};
		encode(form.getElementsByTagName("input"));
		encode(form.getElementsByTagName("textarea"));
		encode(form.getElementsByTagName("select"));
		encode(form.getElementsByTagName("button"));
		return args;		
	}

	function findParent(node, localName)
	{
		while (node && (node.nodeType != 1 || 
				node.localName.toLowerCase() != localName)) {node = node.parentNode; }
		return node;
	}

	function hasClass(self, name)
	{
		return iui.hasClass(self,name);
	}

	function replaceElementWithFrag(replace, frag)
	{
		var page = replace.parentNode;
		var parent = replace;
		while (page.parentNode != document.body)
		{
			page = page.parentNode;
			parent = parent.parentNode;
		}
		page.removeChild(parent);

		var docNode;
		while (frag.firstChild) {
			docNode = page.appendChild(frag.firstChild);
			sendEvent("afterinsert", document.body, {insertedNode:docNode});
		}
	}

	function ddd() { console.log.apply(console, arguments); }

	/*gsb function $(id) { return document.getElementById(id); } */

})();

/*--------------------------------------------------------------------------*/


document.getElementsByClassName = function(className) {
	var elements = [];
	var all = document.getElementsByTagName('*');
	$A(all).each( function(el)
		{ if(iui.hasClass(el, className)) { elements.push(el); } } );
	return elements;
};

/*--------------------------------------------------------------------------*/


