/// <reference path="jQuery.intellisense.js"/>
/// <reference path="xeko.js"/>

var xeko = {
	"forceLogin": function(msg) {
		if (xeko.agentinfo.agentIsGuest) {
			xeko.widgets.logIn.showPrompt(msg);
			return false;
		} else {
			return true;
		}
	},
	"events": {
		"lists": {},
		"notify": function(method, eventname) {
			var collection = "xeko.events.lists." + eventname;
			if (!eval(collection)) {
				eval(collection + " = []");
			}

			eval(collection + ".push('" + method + "')");
		},
		"trigger": function(eventname) {
			var list = eval("xeko.events.lists." + eventname);
			for (var i in list) {
				eval(list[i] + "()");
			}
		}
	},
	"outboundlinks": {
		"enabled": false,
		"url": "",
		"regex": /^http:\/\/(www\.)?xeko(\.flyingmachine)?\.com/, //needs to validate true for any Xeko url
		"auditLink": function(elm, e) {
			var targetURL = $(elm).attr("href");
			if (targetURL.substr(0, 4) == "http" && !xeko.outboundlinks.regex.test(targetURL)) {
				xeko.outboundlinks.redirect(e, targetURL);
			}
		},
		"redirect": function(event, targetURL) {
			if (xeko.outboundlinks.enabled) {
				if (!this.regex.test(targetURL)) {
					event.preventDefault();

					var domain = targetURL.substr(targetURL.indexOf("://") + 3)
					domain = domain.substr(0, domain.indexOf("/"));
					$("div#outbound>div>p>span").text(domain + " ");

					xeko.outboundlinks.url = targetURL;

					$("#outbound").fadeIn("fast");
				}
			}
		}
	},
	"drawers": {
		"closeDrawers": function() {
			for (drawerName in this.items) {
				this.slideDrawer(drawerName, true);
			}
		},
		"slideDrawer": function(drawerName, forceClose) {
			var obj = eval("xeko.drawers.items." + drawerName);
			var toClose = (forceClose) ? true : (parseInt($("#" + obj.id).css("top")) < parseInt(obj.open)) ? false : true;
			if (!toClose) {
				xeko.drawers.closeDrawers();
			}
			var targetTop = (toClose) ? obj.closed : obj.open;
			if (!jQuery.browser.msie) {
				$("#shadow").attr("class", (toClose) ? "off" : "on");
			}
			$("#" + obj.id).animate({ top: targetTop });
			if (!toClose) {
				xeko.events.trigger(obj.onopenevent);
			}
		},
		"items": []
	},
	"paging": {
		"itemsPerPage": {},
		"totalItems": {},
		"currentPage": {},
		"numPages": {},
		"rangeSelector": {},
		"paginationSelector": {},
		"itemsLabel": {},
		"callback": {},
		"firstItem": {},
		"lastItem": {},
		"init": function(instance, totalItems, itemsPerPage, rangeSelector, paginationSelector, itemsLabel, callback) {
			// Instatiate this instance
			xeko.paging.totalItems[instance] = totalItems;
			xeko.paging.itemsPerPage[instance] = itemsPerPage;
			xeko.paging.callback[instance] = callback;
			xeko.paging.rangeSelector[instance] = rangeSelector;
			xeko.paging.paginationSelector[instance] = paginationSelector;
			xeko.paging.itemsLabel[instance] = itemsLabel;

			xeko.paging.currentPage[instance] = 1;
			xeko.paging.numPages[instance] = Math.ceil(xeko.paging.totalItems[instance] / xeko.paging.itemsPerPage[instance]);

			$(paginationSelector).hide();
		},
		"construct": function(instance) {
			/********************************************************************************
			* Pagination rules are:
			* 	- Current page button is grouped in a group of four surrounding page buttons
			* 	- First page button and last page buttonare always displayed
			* 	- All other page buttons are represented by "..."
			********************************************************************************/

			// local vars for brevity
			var numPages = xeko.paging.numPages[instance];
			var itemsPerPage = xeko.paging.itemsPerPage[instance];
			var currentPage = xeko.paging.currentPage[instance];
			var totalItems = xeko.paging.totalItems[instance];
			var rangeSelector = xeko.paging.rangeSelector[instance];
			var paginationSelector = xeko.paging.paginationSelector[instance];
			var itemsLabel = xeko.paging.itemsLabel[instance];
			var callback = xeko.paging.callback[instance];

			// These values are updated every time pagination is constructed
			var firstItem = (itemsPerPage * (currentPage - 1)) + 1;
			xeko.paging.firstItem[instance] = firstItem;
			var lastItem = (itemsPerPage * (currentPage - 1)) + itemsPerPage;
			lastItem = (lastItem > totalItems) ? totalItems : lastItem;
			xeko.paging.lastItem[instance] = lastItem;

			var currentClass = "";
			var disabled = false;
			
			// Current range
			$(rangeSelector).html("showing " + firstItem + " - " + lastItem + " of <strong>" + totalItems + "</strong> " + itemsLabel);

			if (xeko.paging.numPages[instance] > 1) {
				$(paginationSelector).show();

				// Clear existing buttons
				$(paginationSelector).html("");

				// Previous
				disabled = (currentPage == 1) ? "disabled" : "";
				$(paginationSelector).append("<input class=\"prev\" type=\"button\" />")
					.children(".prev")	// select added elms
					.attr("value", " ")
					.attr("disabled", disabled)
					.attr("class", "prev" + disabled)
				;

				// Add 1px clear image, style fix for firefox paging buttons
				$(paginationSelector).append("<img style='width: 1px; height: 15px;' src='/images/clear.gif'/>");

				// If page button is within 5 (or first, or last) then display
				// If page button is hidden and less than current then "..." and skip to current-2;
				// If page button is hidden and greater than current then "..." and skip to last
				for (var i = 1; i <= numPages; i++) {
					// If this page button is +/-1 the current page (or very first or very last page) show
					if ((i <= currentPage + 2 && i >= currentPage - 2) || i == numPages || i == 1) {
						currentClass = (i == currentPage) ? " current" : "";
						disabled = (i == currentPage) ? "disabled" : "";
						$(paginationSelector).append("<input class=\"pageTo pageTo" + i + "\" type=\"button\" />")
							.children(".pageTo" + i)	// select added elm
							.attr("value", i)
							.addClass(currentClass)
							.attr("disabled", disabled)
						;
					}
					else if (i < currentPage) {
						$(paginationSelector).append("...");
						i = currentPage - 3;
					}
					else {
						$(paginationSelector).append("...");
						i = numPages - 1;
					}
				}

				// Next
				disabled = (currentPage == numPages) ? "disabled" : "";
				$(paginationSelector)
					.append("<input class=\"next\" type=\"button\" />")	// New input element
					.children(".next")	// select added elm
					.attr("value", " ")
					.attr("disabled", disabled)
					.attr("class", "next" + disabled)
				;

				// Pagination events
				$(".prev").bind("click", function(e) { xeko.paging.pageBy(-1, instance); });
				$(".next").bind("click", function(e) { xeko.paging.pageBy(1, instance); });
				$(".pageTo").bind("click", function(e) { xeko.paging.pageTo($(this).val(), instance); });
			}
		},
		"pageTo": function(n, instance) {
			if (parseInt(n) > 0 && parseInt(n) <= xeko.paging.numPages[instance]) {
				xeko.paging.currentPage[instance] = parseInt(n);
				eval(xeko.paging.callback[instance]);
				$("html").scrollTop(0);
			}
		},
		"pageBy": function(n, instance) {
			xeko.paging.pageTo(xeko.paging.currentPage[instance] + parseInt(n), instance);
		},
		"isInRange": function(currentItem, instance) {
			return (currentItem >= xeko.paging.firstItem[instance] && currentItem <= xeko.paging.lastItem[instance])
		}
	},
	"theme": {
		"changeTheme": function(targetTheme) {
			// Get from cookie
			if (targetTheme == null || targetTheme == "") {
				targetTheme = $.cookie("theme");
			}

			if (targetTheme == null || (targetTheme != "bees" && targetTheme != "fish")) {
				targetTheme = "fish";
			}

			// Remvoe old classes, add new one and save to cookie
			$("body").removeClass("bees").removeClass("fish");
			$("body").addClass(targetTheme);
			$.cookie("theme", targetTheme);
		}
	},
	"sounds": {
		"toggleSound": function(status) {
			// Get from cookie
			if (status == null || status == "") {
				status = $.cookie("sound");
			}

			// toggle sounds on by default
			if (status == null || (status != "playing" && status != "muted")) {
				status = "playing";
			}

			// save to cookie
			$.cookie("sound", status);
		},
		"getStatus": function() {
			// check sound cookie
			var soundStatus = $.cookie("sound");

			// set default to play
			if (soundStatus == null || soundStatus == "") {
				$.cookie("sound", "playing");
				soundStatus = "playing";
			}
			//alert(soundStatus);
			//return (soundStatus);

			var flashObj = document.getElementById("headerflash");
			flashObj.setSoundStatus(soundStatus);
		}
	},
	"widgets": [],
	"pages": [],
	"messaging": {},
	"debug": {
		"enabled": false,
		"trace": function(msg) {
			if (this.enabled && window.console) {
				window.console.log(msg);
			}
		}
	},
	"flashHeader": {
		"object": null,
		"triggerPoints": function() {
			$("#headerflash").get(0).addPointsFromJS();
		}
	},
	"lightbox": {
		"show": function(msg, wait, instance) {
			// instance manages multiple lightboxes appearing simultaneously. Default value is empty string
			if (!instance) instance = "";

			var waitClass = wait ? " wait" : "";
			$("body").append("<div id=\"xeko-lightbox" + instance + "\" class=\"lightbox" + waitClass + "\"><div><p>" + msg + "</p><p class='animation'><img src='/images/g/g_animatedlogo.gif'/></p></div></div>");
			$("#xeko-lightbox" + instance).fadeIn("fast");

			xeko.debug.trace("start " + instance);
		},
		"hide": function(instance) {
			// instance manages multiple lightboxes appearing simultaneously. Default value is empty string
			if (!instance) instance = "";

			$("#xeko-lightbox" + instance).fadeOut("fast");
			$("#xeko-lightbox" + instance).remove();
		}
	},
	"textPopup": {
		"show": function(headline, msg, elm) {
			var popup = $("#textPopup");

			// headline
			if (headline.length > 0) $("h2", popup).text(headline).show();
			else $("h2", popup).hide();

			// text
			$("p", popup).html(msg);

			$("#textPopupStage").show();

			// Position
			var posTop, posLeft;
			var scrollTop = $(window).scrollTop();
			var scrollLeft = $(window).scrollLeft();
			var buttonTop = $(elm).offset().top - scrollTop; // offset from document
			var buttonLeft = $(elm).position().left - scrollLeft; // offset from parent
			var popupHeight = popup.outerHeight();
			var popupWidth = popup.outerWidth();

			// Keep the popup from appearing off-screen
			if ((buttonTop + popupHeight) > $(window).height()) posTop = (buttonTop - popupHeight) + scrollTop;
			else posTop = buttonTop + 20 + scrollTop;
			if ((buttonLeft + (popupWidth * 2)) > $(window).width()) posLeft = (buttonLeft - popupWidth) + scrollLeft;
			else posLeft = buttonLeft + 20 + scrollLeft;

			// do not allow negative placement, or placement over the header
			if (posTop < 160) posTop = 160;
			if (posLeft < 0) posLeft = 0;

			xeko.debug.trace("buttonTop: " + buttonTop);
			xeko.debug.trace("buttonLeft: " + buttonLeft);
			xeko.debug.trace("popupHeight: " + popupHeight);
			xeko.debug.trace("popupWidth: " + popupWidth);
			xeko.debug.trace("posTop: " + posTop);
			xeko.debug.trace("posLeft: " + posLeft);
			xeko.debug.trace("scrollTop: " + scrollTop);
			xeko.debug.trace("scrollLeft: " + scrollLeft);

			popup
				.css("top", posTop)
				.css("left", posLeft)
				.fadeIn("normal");
		},
		"hide": function() {
			$("#textPopupStage").hide();
			$("#textPopup").fadeOut("fast");
		}
	},
	"rewards": {
		"getVerticalRewardsHtml": function(xml) {
			var pointsTotal = 0;
			var html = $("<div />");
			$("agentreward", xml).each(function() {
				var rewardId = $("rewarditemid", this).text();
				var rewardType = jQuery.trim($("rewarditemtype", this).text());

				switch (rewardType) {
					case "Unlimited Play":
						//				$("#codeCrackerRewards").append("<div>unlimited play</div>");
						break;
					case "China Points":
					case "Costa Rica Points":
					case "Indonesia Points":
					case "Madagascar Points":
					case "General Points":
						// It's possible to earn multiple points rewards in a single go, so we must aggregate them
						var thesePoints = parseInt($("agentpoints>value", this).text());
						thesePoints = isNaN(thesePoints) ? 0 : thesePoints;
						pointsTotal += thesePoints;
						break;
					case "Badge":
						var badgeId = $("badge>imageidentifier", this).text();
						var src = "/images/badges/g_badge_" + badgeId + ".png";
						html.append("<div><img src=\"" + src + "\" alt=\"\" /> badge</div>");
						break;
					case "Random China Card":
					case "Random Costa Rica Card":
					case "Random Indonesia Card":
					case "Random Madagascar Card":
					case "Digital Card":
						var hotspot = xeko.utilities.removeSpaces($("card>hotspot", this).text());
						var cardNo = $("card>number", this).text();
						var src = "/images/cardart/" + hotspot + "/xekocards/" + cardNo + ".jpg";
						html.append("<div><img src=\"" + src + "\" alt=\"\" /> card</div>");
						break;
				}
			});

			// Points should go at the top of the list
			if (pointsTotal > 0) {
				html.prepend("<div><strong>" + pointsTotal + "</strong> points</div>");
			}

			return html.html();
		}
	},
	"validation": {
		"showMessage": function(id, msg) {
			$("#alert_" + id).remove();
			$("#" + id).before("<p class='validationAlert' id='alert_" + id + "'>" + msg + "</p>");
		},
		"clearMessage": function(id) {
			$("#alert_" + id).remove();
		},
		"clearAll": function() {
			$(".validationAlert").hide();
		},
		"validateEmail": function(email) {
			var validEmail = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
			return validEmail.test(email);
		},
		"validateAgentId": function(agentId) {
			var validAgentId = /^(\S){5,}$/; // valid Agent ID is five or more chars long and contains no whitespace
			if (validAgentId.test(agentId)) return true;
			else return false;
		},
		"validatePassword": function(pwd) {
			var validPwd = /^(\S){5,}$/; // valid password is five or more chars long and contains no whitespace
			if (validPwd.test(pwd)) return true;
			else return false;
		}
	},
	"utilities": {
		"formatDavinciDate": function(dte) {
			return dte.getFullYear() + "/" + (dte.getMonth() + 1) + "/" + dte.getDate() + " " + dte.getHours() + ":" + dte.getMinutes() + ":" + dte.getSeconds();
		},
		"parseDate": function(str) {
			var t = Date.parse(str);
			var dte = new Date(t);
			return dte;
		},
		"formatDate": function(dte) {
			var months = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
			var date = months[dte.getMonth()] + " " + dte.getDate() + ", " + dte.getFullYear();
			return date;
		},
		"daysBetween": function(dte1, dte2) {
			// Convert to milliseconds
			var dte1Milliseconds = dte1.getTime();
			var dte2Milliseconds = dte2.getTime();
			var diff = Math.abs(dte1Milliseconds - dte2Milliseconds);

			// Convert back to days
			var millisecondsInOneDay = 1000 * 60 * 60 * 24;
			var days = Math.round(diff / millisecondsInOneDay);
			
			// Never display "0" as days remaining; "1" is minimum
			days = (days < 1) ? 1 : days;
			
			return days;
		},
		"toggle": function(x) {
			// toggle from 1 to 0 and back
			if (x.toString() == "1") return "0";
			else return "1";
		},
		"loadXmlFromString": function(str) {
			var xmlDoc;

			try //Internet Explorer
						{
				xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
				xmlDoc.async = "false";
				xmlDoc.loadXML(str);
			}
			catch (e) {
				try //Firefox, Mozilla, Opera, etc.
								{
					parser = new DOMParser();
					xmlDoc = parser.parseFromString(str, "text/xml");
				}
				catch (e) { }
			}
			return xmlDoc;
		},
		"htmlEncode": function(str) {
			var div = document.createElement('div');
			var text = document.createTextNode(str);
			div.appendChild(text);
			return div.innerHTML;
		},
		"makeId": function(str) {
			return str.replace(/ /g, "");
		},
		"removeSpaces": function(str) {
			return str.replace(/ /g, "");
		},
		"addLineBreaks": function(str) {
			return str.replace(/\n/g, "\n<br />");
		},
		"xmlEncode": function(s) {
			s = escape(s);
			s = s.replace(/\+/g, "%2B");
			return s;
		},
		"urlEncode": function(s) {
			s = s.replace(/, /g, ",");
			s = s.replace(/ /g, "%20");
			return s;
		},
		"formatShortDate": function(dte, omitDay) {
			var date = "";
			if (dte.length > 0) {
				dte = this.parseDate(dte);
				if (dte != null) {
					var months = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
					var day = dte.getDate();
					if (day.length == 1) day = "0" + day;
					if (omitDay) date = months[dte.getMonth()] + " " + dte.getFullYear();
					else date = months[dte.getMonth()] + " " + day + ", " + dte.getFullYear();
				}
			}
			return date;
		},
		"formatDateFromOldServices": function(dateStr, omitDay) {
			var dte = new Date(Date.parse(dateStr.substr(5, 2) + "/" + dateStr.substr(8, 2) + "/" + dateStr.substr(0, 4)));
			return dte;
		},
		"formatMonthYear": function(dte) {
			var monthName = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
			return monthName[dte.getMonth()] + " " + dte.getFullYear();
		},
		"formatPoints": function(nStr) {
			nStr += '';
			x = nStr.split('.');
			x1 = x[0];
			x2 = x.length > 1 ? '.' + x[1] : '';
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(x1)) {
				x1 = x1.replace(rgx, '$1' + ',' + '$2');
			}
			return x1 + x2;
		},
		"appendGuidToId": function($elm, guid) {
			var id = $elm.attr("id");
			$elm.attr("id", id + guid);
		}
	},
	"webservice": {
		"baseurl": "http://dev.xeko.com/davinci.1.0/xeko/~xeko/"
	}
}

$(document).ready(function() {
	$("#body").show();
	
	//set up lightbox
	$("body").append("<div id='shadow'></div>");
	$("div#shadow").click(function() {
		xeko.drawers.closeDrawers();
	});

	//outbound link handling
	$("a").live("click", function(e) {
		xeko.outboundlinks.auditLink(this, e);
	});
	
	$("#outboundContinue").click(function(e) {
		e.preventDefault();
		window.open(xeko.outboundlinks.url, "_blank");
		$("#outbound").fadeOut("fast");
	});
	
	$("#outboundCancel, #outboundClose").click(function(e) {
		e.preventDefault();
		$("#outbound").fadeOut("fast");
	});

	// inline PNG images for IE 6
	if ($.browser.msie && parseInt($.browser.version) < 7) {
		// Show the button for now
		// $(this).attr("src", "/images/clear.gif");
	}

	// Text Popup close button
	$("#textPopup>img, #textPopupStage").click(function() {
		xeko.textPopup.hide();
	});

	// Make sure user is logged in before navigating to the Create Challenge page
	$(".challengesCreateChallenge").click(function(e) {
		e.preventDefault();
		if (xeko.forceLogin(xeko.messaging.alert.CHALLENGE_CREATE_LOGIN_REQUIRED)) {
			location = "/createchallenge";
		}
	});
	
	// Wire up contextual help
	$(".contextualHelp").click(function(e) {
		e.preventDefault();
		xeko.textPopup.show($(this).attr("title"), $("p", this).html(), this);
	});
});


//-- Elf Island open/close div function
function OpenClose(obj) {
	if (obj.style.display == 'block') {
 		obj.style.display = 'none';
	} else {
 		obj.style.display = 'block';
	}
}

