/*
 *  MobiOne PhoneUI Framework
 *  version 0.1.2
 *  <http://genuitec.com/mobile/resources/phoneui>
 *  (c) Copyright 2010, 2011 Genuitec, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 
   
var phoneui = {};

/** 
  * Support for deprecated API mobione namespace
  * @deprecated 
  * @see phoneui
  */
var mobione = phoneui; 

// Initialize webapp for use by phoneui framework
$(document).ready(function() {
	jQuery.preloadCssImages();
	
	var webappCache = window.applicationCache;
	if (webappCache) {
		/*
		webappCache.addEventListener("checking", function() {
			phoneui.showActivityDialog("Checking for update...");
		}, false);
		*/
		var wasDownloaded = false;
		webappCache.addEventListener("noupdate", function() {
			phoneui.hideActivityDialog();
		}, false);
		webappCache.addEventListener("downloading", function() {
			phoneui.showActivityDialog("Updating...");
			wasDownloaded = true;
		}, false);
		webappCache.addEventListener("cached", function() {
			phoneui.hideActivityDialog();
		}, false);
		webappCache.addEventListener("updateready", function() { 
			location.reload(); // Reload page right after update came. 
		}, false);
		webappCache.addEventListener("obsolete", function() {
			phoneui.hideActivityDialog();
			alert("Error: The manifest is no longer available (code 404). Unable to cache web page for offline use.");
		}, false);
		webappCache.addEventListener("error", function(str) {
			phoneui.hideActivityDialog();
			if (wasDownloaded) {
				alert("Error: Unable to cache web page for offline use. Visit Safari settings and clear cache.");
			}
		}, false);

	}
	
	// Default platform (mostly for desktop browsers
	phoneui._platform = {
		init : function() {
			$(window).resize(function(e) {
				handleResizing();
			});
		},
		initAddressBarHiding : function() {},
		hideAddressBar : function() {},
		docsize : function() { return { x : window.innerWidth, y : window.innerHeight }; } 
	};

	if (window.navigator.userAgent.toLowerCase().indexOf('iphone') != -1) {
		// iphone platform
		phoneui._platform = {
			init : function() {			
		    	function checkOrientation() {
		    		handleResizing();
		    		if (m1Design.shouldHideAddressBar) {
		    			phoneui._platform.initAddressBarHiding();
		    		}
		   			if ('postOrientationChange' in phoneui) {
		   				phoneui.postOrientationChange(window.orientation);			
					}
				}
				window.onorientationchange = checkOrientation;

				$('input, textarea, select').bind('blur', function(e) {
					// virtual keyboard disappeared, let's hide address bar
					phoneui._platform.hideAddressBar();
				});
			},
			initAddressBarHiding : function() {
				setTimeout(function() {
					phoneui._platform.hideAddressBar();
				}, 1000);
			},
			hideAddressBar : function() {
				window.scrollTo(0, 0);
			},
			docsize : function() {
				var p = (window.orientation % 180) == 0;
				// Take statusbar into account
				var bb = 20;
				var bbVisible = 
					!(window.PhoneGap) && 
					!window.navigator.standalone;
				if (bbVisible) {
					// Take buttonbar into account
					bb += (p ? 44 : 30);
					// Take addressbar height into account
					bb += m1Design.shouldHideAddressBar ? 0 : 60;
				}
				return { 
					x : (p ? 320 : 480), 
					y : ((p ? 480 : 320) - bb) }; 
			}
		};
	}

	function resizeScreen(currentScreen) {
		var s = phoneui._platform.docsize();
		// Set root screen element height - otherwise addressbar wouldn't disappear on iOS
		var t = $("." + m1Design.css('top-root') + ", " + currentScreen.anchor_id);
		t.height(s.y);
		t.width(s.x);
		currentScreen.resize(s.x, s.y); // Make first resize
		reinitscrollers($(currentScreen.anchor_id));
	}
	
	function handleResizing() {
		if (currentScreen) {		
			resizeScreen(currentScreen);
		}
	}
	
	var isSliding = false;
	var hyperLinkClickSrc = null;
	var firstScreenTime = 1;
	var defAncPars = [m1Design.root(), 'NONE', firstScreenTime];
	var currentScreen = parseAnchor('');
	
	phoneui.getCurrentScreen = function() {
		return currentScreen;
	}
	
	handleResizing();

	// FORMAT: page_id:transition:time
	function parseAnchor(str) {
		var spl = str == "" ? [] : str.substr(1).split(':');
		
		// Append default params
		if (spl.length < defAncPars.length) {
			spl = spl.concat(defAncPars.slice(spl.length));
		}
		
		function obj() {};
		obj.prototype = m1Design.pages[spl[0]];
		var ret = new obj();
		ret.transition = spl[1];
		ret.time = spl[2];
		ret.equals = function(el) {
			return !el || (this.anchor_id == el.anchor_id);
		};
		ret.toString = function() { return this.anchor_id + ":" + this.transition; };
				
		return ret; 
	}
	
	// Install checkNewScreen as history change listener
	if ('onhashchange' in window) {
		window.onhashchange = checkNewScreen;
	} else {
		setInterval(checkNewScreen, 200);
	}

	phoneui._platform.init();

	checkNewScreen();
	
	var prevHref;
	function checkNewScreen() {
		var initialCall = !prevHref;
		if (prevHref != window.location.href) {
			prevHref = window.location.href;
			
			var nextScreen = parseAnchor(window.location.hash);
			
			if (!nextScreen.equals(currentScreen)) {
				var trans = nextScreen.transition;
				var back = false;
	
				if ((+nextScreen.time) < (+currentScreen.time)) {
					// We're moving back in history!
					trans = currentScreen.transition;
					back = true;
				}
				
				function doAnimate() {
					var $next = $(nextScreen.anchor_id);

					resizeScreen(nextScreen);

					animateNavigation( 
							$next, $(currentScreen.anchor_id), 
							initialCall ? "NONE" : trans, back);
	
					currentScreen = nextScreen;
					callPostTransition();
				}
	
				if (nextScreen.dynamic &&
						// following case is special one - returning back from static page
						// to dynamic one shouldn't cause reload, otherwise our SLM pages
						// stops to work
						!(back && currentScreen && !currentScreen.dynamic)) {
					// Load page first
					loadExternalPage(nextScreen, doAnimate);
				} else {
					// Animate!
					doAnimate();
				}
			}
		}
	}

	function parseDPIPageData(data) {
		var pg = $('<div></div>');
		pg.html(data);
		var rt = pg.find('.' + m1Design.css('root'));
		preProcess(rt);
		rt.appendTo('.' + m1Design.css('top-root'));
	}
	
	function loadPageCssAndJs(nextScreen, onok) {
		var $next = $(nextScreen.anchor_id);
		if ($next.length > 0) {
			// Remove old div
			$next.remove();
		}

		// Load stylesheet as well
		$('<link rel="stylesheet" type="text/css" href="' + nextScreen.css_url() +'" >').appendTo("head");

		// LOADING AND ACTIVATE THE PAGE JS
		$.ajax({
		  url: nextScreen.js_url(),
		  dataType: 'script',
		  success: onok,
		  error: onok // Call onok anyway, we don't care about failed JS loading
		});
	}

	function loadExternalPage(nextScreen, onok) 
	{
		phoneui.showActivityDialog();
		
		loadPageCssAndJs(nextScreen, function () {
    		var req = new XMLHttpRequest();
    		req.open("GET", nextScreen.html_url(), true);
    		// req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2005 00:00:00 GMT");
    		var timer = setTimeout(function() {
    		       req.abort();
    		     }, 10000);
    		req.onreadystatechange = function() {
    			if (req.readyState == req.DONE) {
    				var ok = (req.status >= 200 && req.status < 300) || (req.status == 0 && req.responseText.length > 0); 
    				if (ok) {
    					clearTimeout(timer);

						parseDPIPageData(req.responseText);
    				}

    				phoneui.hideActivityDialog();

    				if (ok) {
    					onok();
    				}
    			}
    		}
    		req.send(null);
        });		
	}
	
	function callPreTransition(nextScreen) {
		if ('prePageTransition' in phoneui) {
			var result = 
				phoneui.prePageTransition(currentScreen.anchor_id, nextScreen.anchor_id);
			return !!result;
		}		
		return true;
	}
	
	function callPostTransition() {	    
		if ('postPageTransition' in phoneui) {
			phoneui.postPageTransition(currentScreen.anchor_id);
		}		
	}

	/**
	 * Get ID of current page. 
	 *
	 * @return ID String of the page. Is in the form of anchor (e.g., #m1-page1)
	 */
	phoneui.getCurrentPageId = function() {
		return currentScreen.anchor_id;
	}

	phoneui.submitForm = function(formId, button, urlToGoAfter) {
		var result = false;
		var form = document.forms(formId);
		if (form == null) return result;
		
		var onsubmitName = "preSubmitForm_" + form.name;
		if (onsubmitName in phoneui) {
			result = phoneui[onsubmitName](form);
			if (result == false) {
				return result;
			}
		}	
		
		var method = $(form).attr('method');
		var restype = $(form).attr('resulttype');
		var str = $(form).serialize();
		var path = $(form).attr('action');
		var aftersubmitName = "postSubmitForm_" + form.name;

		if (restype == 'WEB_PAGE') {
			// Pure Web submisson
			$(form)[0].submit();
			return;
		}
		
		phoneui.showActivityDialog();
		
		jQuery.ajax({
			type: method,
			url: path,
			data: str,
			cache: false,
			beforeSend: function(){ 
				return true; //return false if execution should terminate
			},
			error: function(XMLHttpRequest, textStatus, errorThrown) {
				console.log(textStatus);
				phoneui.hideActivityDialog();
				if (aftersubmitName in phoneui) {
					phoneui[aftersubmitName](false,textStatus);
				}			 
			},
			complete: function(xMLHttpRequest, textStatus) {

			},
			success: function(data) {
					result = true;

					if (aftersubmitName in phoneui) {
						result = phoneui[aftersubmitName](true, data);
					}
					
					if (result) {
						if (restype == 'DYNAMIC_PAGE') {
							var nextScreen = parseAnchor(urlToGoAfter);
							
							if (callPreTransition(nextScreen)) {
								loadPageCssAndJs(nextScreen, function() {
									parseDPIPageData(data);
	
									phoneui.hideActivityDialog();
	
									setNewLocation(urlToGoAfter);

									resizeScreen(nextScreen);

									var $next = $(nextScreen.anchor_id);
									animateNavigation( 
											$next, $(currentScreen.anchor_id), 
											nextScreen.transition, false);
	
									nextScreen.time = currentScreen.time + 1;
									currentScreen = nextScreen;
									callPostTransition();
								});
							}
						} else if (urlToGoAfter) {
							// only restype == 'DATA' should be here 
							phoneui.hideActivityDialog();
							setNewLocation(urlToGoAfter);
						}
					}
			}
		});	

		return result;
	}
	
	function animateNavigation($new, $old, transition, revertTransition) {
		if(isSliding === false && ($new.attr('id') != $old.attr('id')))  {
			if ($new.length == 0) {
				return; // Target page is not found
			}

			var trNone = transition == 'NONE';
			var trFade = transition == 'FADE';
			var trFlipRight = transition == 'FLIP_LEFT';
			var trFlipLeft = transition == 'FLIP_RIGHT';
			var trSlideRight = transition == 'SLIDE_RIGHT';			
			var trSlideLeft = transition == 'SLIDE_LEFT' || transition == 'DEFAULT';
			
			isSliding = true;
			function afterTransition() {
				isSliding = false;
			}

			function doAfterTransition($el, fn) {
				var performAfterTrans = function() {
					fn();
					afterTransition();
					$el.unbind('webkitAnimationEnd', performAfterTrans);
				}
				$el.bind('webkitAnimationEnd', performAfterTrans);
			}

			var cssIn = m1Design.css("in"); 
			var cssOut = m1Design.css("out");
			if (trFade) {
				var cssFade = m1Design.css("fade") + " " + cssIn;
				doAfterTransition($new, function () { 
					$old.hide();
					$new.removeClass(cssFade);
				});
				$new .show().css({left: '0px'}).addClass(cssFade);
			} else if (trFlipRight || trFlipLeft) {
				var reverse = (trFlipLeft == revertTransition) ? (" " + m1Design.css("reverse")) : "";
				var cssFlip = m1Design.css("flip");
				$old .addClass(cssFlip + " " + cssOut + reverse);
	
				doAfterTransition($old, function() {
					$old.hide();
					$old.removeClass(cssFlip + " " + cssOut + reverse);
					doAfterTransition($new, function() {
						$new .removeClass(cssFlip + " " + cssIn + reverse).css({left: '0'});
					});
					$new.show().css({left: '0'}).addClass(cssFlip + " " + cssIn + reverse);
				});
			} else if (trSlideRight || trSlideLeft) {
				var cssSlide = m1Design.css("slide");
				var reverse = (trSlideLeft == revertTransition) ? (" " + m1Design.css("reverse")) : "";
				doAfterTransition($new, function() {
					$old.hide();
					$old.removeClass(cssSlide + " " + cssOut + reverse);
					$new.removeClass(cssSlide + " " + cssIn + reverse);
				});
				
				$old .addClass(cssSlide + " " + cssOut + reverse);
				$new .show().addClass(cssSlide + " " + cssIn + reverse);
			} else {
				// No animation for "NONE" transitions
				$old.hide();
				$new.css({left:'0px', display:'block'});
				afterTransition();
			}
		}
	};
	
	function reinitscrollers(root) {
		root.find('.' + m1Design.css("iscroll-scroller")).each(function() {
			var el = $(this).get(0);
			if (el.myScroll) {
				// Slightly delay scroll refresh to allow all elements re-calculate their sizes
				setTimeout(function() {
					el.myScroll.refresh();
				}, 100);
			}
		});
	}
	
	function setNewLocation(href) {
		if (href.match(/^#/)) {
			var nextScreen = parseAnchor(href);
			if (!nextScreen.equals(currentScreen)) {
				if (callPreTransition(nextScreen)) {
					// Add timestamp
					window.location = href + ":" + ((+currentScreen.time) + 1);
				}
			}
		} else if (href.match(/^sms:/i)) {
			// Special processing for SMS URL - they do not work in standalone mode
			// when set directly as window.location.href. So, we're implementing
			// workaround here
			var el = jQuery('<a href="' + href + '" style="position:absolute;"/>')
				.appendTo(document.body);
			var e = el[0];
			
			var evt = e.ownerDocument.createEvent('MouseEvents');
			evt.initMouseEvent('click', true, true, 
					e.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
			e.dispatchEvent(evt);
			el.remove();
		} else {
			window.location.href = href;
		}		
	}
	
	// This function is called for each page to initialize it's controls
	function preProcess(context) {
		$('.' + m1Design.css("iscroll-scroller"), context).each(function() {
			var el = $(this).get(0);

			if (!('myScroll' in el)) {
				el.myScroll = new iScroll(el, { 
					hScrollbar : false, 
					vScrollbar : true, 
					bounce: $(this).attr('data-bounce') == 'true',
					desktopCompatibility : true,
					shouldPreventDefault : function(el) {
						var clname = m1Design.css("iscroll-no-prevent-default");
						for (;el != document.body && !$(el).hasClass(clname);el = el.parentElement) {
						}
						return el == document.body;
					} 
				});
			}
		});	

		$('.' + m1Design.css("hyperlink"), context).click(function(event) {
			event.preventDefault();
			hyperLinkClickSrc = this;
			
			var href = $(this).attr('href');
			setNewLocation(href);
			
			setTimeout(function() {
				hyperLinkClickSrc = null;
			}, 0);
		});
	
		var btns = $('.' + m1Design.css("clickable"), context);
		btns.bind("touchstart mousedown", function() {
			$(this).removeClass(m1Design.css("unclicked")).addClass(m1Design.css("clicked"));
		});
		
		btns.bind("touchend touchcancel mouseup mouseleave", function() {
			var that = this;
			if ($(that).is("." + m1Design.css("clicked"))) {
				$(that).addClass(m1Design.css("unclicked"));
				// Delay dropping "clickable" for 100 ms, allow all effects to be drawn 
				setTimeout(function() {
					$(that).removeClass(m1Design.css("unclicked")).removeClass(m1Design.css("clicked"));
				}, 150);
			}
		});

		// Support for "spinner mode" in SLM
		var processSLM = function(i, v) {	
			var sel = $("#" + $(v).attr("data-hiddenInputId"), context);
			var selInfoId = $("#" + $(v).attr("data-selectionInfoId"), context);
			if (selInfoId) {
				var onSelectionChange = function() {
					var labelsArray = [];
					var lis = sel.children('option');
					for(var i = 0; i < lis.length; i++) {
						var lbl = $(lis[i]);
						if (lbl.get(0).selected) {
							labelsArray.push(lbl.text());
						}
					}
					if ($(v).attr('data-multiple')=='false') {
						selInfoId.text(labelsArray[0]);
					} else {
						selInfoId.text("" + labelsArray.length);
					}
				}
	
				onSelectionChange();
				sel.unbind('change', onSelectionChange).bind('change', onSelectionChange);
				// For iOS4 support, subscribe to blur too 
				sel.unbind('blur', onSelectionChange).bind('blur', onSelectionChange);
				moveHiddenInputOverFake($(sel)[0], $(v)[0]);
			}
		};
		$('.' + m1Design.css('select-list-menu-spinner'), context).each(processSLM);
		$('.' + m1Design.css('select-list-menu'), context).each(processSLM);
		
		function moveHiddenInputOverFake(el, fakeEl) {			
			var off = {left:0, top:0};
			for (var op = fakeEl; op != null; op = op.offsetParent) {
				off.left += op.offsetLeft;
				off.top += op.offsetTop;
				
				if (op.myScroll) {
					off.left += op.myScroll.x;
					off.top += op.myScroll.y;
				}
			}
			
			el.parentElement.style.left = off.left + "px";
			el.parentElement.style.top = off.top + "px";
			
		}

		$('input select').bind('focus blur', function() {
			$('.' + m1Design.css('select-list-menu-spinner'), context).each(function(i, v) {	
				var sel = $("#" + $(v).attr("data-hiddenInputId"));			
				var el = sel.get(0);

				moveHiddenInputOverFake(el, $(v)[0]);
			});
		});
		
		$('.' + m1Design.css("select-list-menu-spinner"), context).click(function(e) {
			var sel = $("#" + $(this).attr("data-hiddenInputId"));
			var el = sel.get(0);

			moveHiddenInputOverFake(el, $(this)[0]);

			var evt = el.ownerDocument.createEvent('MouseEvents');
			evt.initMouseEvent('mousedown', true, true, el.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null);
			el.dispatchEvent(evt);
		});
		
		// End of support for "spinner mode" in SLM
				
		var prevTableClick = new Date();
		$('.' + m1Design.css("selection-list") + ' > li[data-val]', context).click(function() {
			// Avoid double clicking on selection list items
			if (((new Date()).getTime() - prevTableClick.getTime()) > 100) {
				// 100 ms
				tableListMngt($(this));
			}
			prevTableClick = new Date();
		});
		
		jQuery.each($('.' + m1Design.css("selection-list")), function(i, v) {
			processSelectionList(v);
		});
	}
	preProcess($('.' + m1Design.css("top-root")));
	
	if ('documentReadyHandler' in phoneui) {
		phoneui.documentReadyHandler();
	} 
	
	function processSelectionList(elt) {
		var selInfoId = $("#" + $(elt).attr("data-selectionInfoId"));
		var labelsArray = [];
		var resultMap = {};
		var lis = $(elt).children('li[data-val]');
		for(var i = 0; i < lis.length; i++) {
			var lbl = $(lis[i]);
			if(lbl.hasClass(m1Design.css("selected"))) {
				resultMap[lbl.attr('data-val')] = true;
				if (selInfoId) {
					labelsArray.push(lbl.text());
				}
			}
		}
		var hiddenSel = $("#" + $(elt).attr("data-hiddenInputId"));
		
		// Update options states
		hiddenSel.children('option').each(function() {
			this.selected = resultMap[this.value];
		});
		
		if (selInfoId) {
			if ($(elt).attr('data-multiple')=='false') {
				selInfoId.text(labelsArray[0]);
			} else {
				selInfoId.text("" + labelsArray.length);
			}
		}
	}
	
	function tableListMngt(item) {		
		var elt = $(item).closest('ul')[0];	 
		if($(elt).attr('data-multiple')=='false') {
			$(elt).children('li[data-val]').removeClass(m1Design.css("selected"));
			$(item).addClass(m1Design.css("selected"));
		} else {
			if ($(item).is("." + m1Design.css("selected"))) {
				$(item).removeClass(m1Design.css("selected"));
			} else {
				$(item).addClass(m1Design.css("selected"));
			}
		}
		processSelectionList(elt);
	}
			
	function SetCookie(sName, sValue) {
			document.cookie = sName + "=" + escape(sValue);
			var date = new Date();
			var expdate = date.getTime();
			expdate += 3600*1000 //expires (milliseconds - 1000 is for a day)
			date.setTime(expdate);
			document.cookie += ("; expires=" + date.toUTCString());
	}
	
	function GetCookie(sName) {
			var aCookie = document.cookie.split("; ");
			for (var i=0; i < aCookie.length; i++)
			{
					var aCrumb = aCookie[i].split("=");
					if (sName == aCrumb[0])
							return unescape(aCrumb[1]);
			}
			return null;
	}

	var cname = 'phc';
	var hsp = $('.' + m1Design.css('homescreen-prompt'));
	if(window.navigator.standalone != true && 
			window.navigator.userAgent.toLowerCase().indexOf('iphone')!=-1) {
		if(GetCookie(cname)) {
			// Hide the dialog box - to avoid scrolling
			hsp.hide();
		} else {
			// Show prompt dialog
			SetCookie(cname,'true');
			var s = phoneui._platform.docsize();
			hsp .css({top: (s.y - 20) + 'px', opacity: '0.0'});
			setTimeout(function() { hsp .animate(
					{top: (s.y - 120) + 'px', opacity: '1.0'}, 
					{duration: 400, complete: function() {
						setTimeout(function() { hsp .animate({opacity: '0'}, {
							duration:400,
							complete: function() { hsp .hide(); }
						})}, 5000);
					} }); }, 600);
		}
	} else {
		hsp .hide();
	}
}); 

if (m1Design.shouldHideAddressBar) {
	window.addEventListener("load", function() {
		phoneui._platform.initAddressBarHiding();
	}, false);
}

document.addEventListener('DOMContentLoaded', function() {
	document.addEventListener('touchmove', function(e){ e.preventDefault(); });
});

/**
 * Page Transition Effects
 */
phoneui.transitions = {
	none : 'NONE',
	fade : 'FADE',
	flipRight : 'FLIP_RIGHT',
	flipLeft : 'FLIP_LEFT',
	slideRight : 'SLIDE_RIGHT',			
	slideLeft : 'SLIDE_LEFT'
};

/**
 * Navigate to page with transition effect
 *
 * @param pageId String 
 * @param transition, The phoneui.transitions visual effect 
 */
phoneui.gotoPage = function(pageId, transition) {
	var currentScreen = phoneui.getCurrentScreen();
	var newScreen = phoneui.getPageByAnchorId(pageId);
	if (newScreen == null) {
		console.log('Page ' + pageId + ' not found');
		return;
	}
	if (newScreen != currentScreen) {
		window.location.hash = newScreen.id + ":" + 
			(transition ? transition : phoneui.transitions.slideLeft) + 
			(currentScreen ? ":" + ((+currentScreen.time) + 1) : "");
	}
}

/**
 * Navigate to previous URL in history
 */
phoneui.back = function() {
	history.go(-1);
}

/**
 * Returns page object from passed anchorId (id of root HTML element for the page)
 */
phoneui.getPageByAnchorId = function(anchorId) {
	for (var p in m1Design.pages) {
		var page = m1Design.pages[p];
		if (page.anchor_id == anchorId || (page.anchor_id == ('#' + anchorId))) {
			return page;
		}
	}
	return null;
}

/**
 *  Show a small dialog composed of an animated graphic and an optional text 
 *  message. Use this function to indicate to the user that a potentially
 *  long running activity is underway, such as loading resources or waiting for
 *  computation to complete.
 *
 *  @param text option String message to show
 *  @see #hideActivityDialog
 */
phoneui.showActivityDialog = function (text) {
	if (!text && (text != "")) {
		text = "Loading..."; 
	}

	$('.' + m1Design.css('loading-text')) .html(text);

	if (!phoneui.showActivityDialog.controller) {
		var canvas = $('.' + m1Design.css("loading-spinner"))[0];
	
		var ctx = canvas.getContext("2d");
		var bars = 12;
		var currOffs = 0;
	
		function draw(ctx, offset) {
			clearFrame(ctx);
			ctx.save();
			ctx.translate(15, 15); // Center coordinates
			for(var i = 0; i<bars; i++){
				var cb = (offset+i) % bars;
				var angle = 2 * Math.PI * cb / bars;
	
				ctx.save();
				ctx.rotate(angle);
	
				var op = (1 + i)/bars;
				ctx.fillStyle = "rgba(255, 255, 255, " + op*op*op + ")";			
				ctx.fillRect(-1, 3, 2, 6);
	
				ctx.restore();
			}
			ctx.restore();
		}
		function clearFrame() {
			ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
		}
		function nextAnimation(){
			currOffs = (currOffs + 1) % bars;
			draw(ctx, currOffs);
		}
		phoneui.showActivityDialog.controller = {
			timer: -1,
			stop: function (){
				clearFrame();
				clearInterval(this.timer);
			},
			start: function (){
				this.timer = setInterval(nextAnimation, 80); // 20 fps
			}
		};
	}
	phoneui.showActivityDialog.controller.start();

	$('.' + m1Design.css('loading')) .show();
}

/**
 *  Terminate the activity dialog and remove it from the display. 
 *  This function is a NOP if the activity dialog is not already exposed.
 *
 *  @see #showActivityDialog
 */
phoneui.hideActivityDialog = function () {
	if (phoneui.showActivityDialog.controller) {
		phoneui.showActivityDialog.controller.stop();
	}
	$('.' + m1Design.css('loading')) .hide();
}

/**
 *  Current PhoneUI framework version info
 */
phoneui.version = { 
	major : 0, 
	minor : 1, 
	maintenance : 2, 
	toString : function() {
		return this.major + "." + this.minor + "." + this.maintenance;
	}
}

