(function() {
	//
	// object to hold a reference to the app
	window.app = {};
	//
	var App = function(data) {
		this.domRoot = data.domRoot;
		//
		this.isLowIE = false;
		//
		this.overlay = null;
		this.overlayPod = null;
		//
		this.overlayActive = false;
		//
		this.connectingXmlHttp = null;
		this.trying = false;
		this.booting = false;
		this.checkCount = 0;
		this.connectingTimeout = null;
		//
		this.CHECK_DELAY = 2500;
		this.CHECK_COUNT_TRYING = 18;
		// 25 seconds
		this.CHECK_COUNT_BOOT = 15;
		// 37 seconds
		this.CHECK_COUNT_CONNECTING = 40;
		// Viper roughly takes about 150 seconds to reboot,up and running. But leave the check count to 240 seconds.
		this.CHECK_COUNT_REBOOTING = 96;
		// 100 seconds
		this.CHECK_COUNT_FIBRE_TRYING = 0;
		// 25 seconds
		this.CHECK_COUNT_FIBRE_REBOOTING = 25;
		// 60 seconds
	}
	//
	App.prototype = {
		init : function() {
			var _this = this;
			//
			//Utility.trace("APP INIT");
			//
			// init the page
			_this.initPage();
			//
			// after window has fully loaded.... show the menu and start carousel
			jQuery(window).on('load',function() {
				//
				//Utility.trace("WINDOW LOAD");
			});
			//
			// initialise ajax xml http object for the 'connecting' overlay
			if(window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
				_this.connectingXmlHttp = new XMLHttpRequest();
			} else {// code for IE6, IE5
				_this.connectingXmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			//
			return this;
		},
		//
		// ---------------------------------------------------------------------------------------------------- //
		// -- UI BUILD
		// ---------------------------------------------------------------------------------------------------- //
		initPage : function() {
			var _this = this;
			//
			//
			// hide any non-js content
			jQuery(document).find('.non-js').each(function(i, el) {
				Utility.trace(el);
				jQuery(el).css('display', 'none');
			});
			// add simple rollover effects to all btn elements
			jQuery(_this.domRoot).find('a[class^="btn"]').each(function() {
				Utility.addSimpleSwitchRollover(this);
			});
			//
			// back and next buttons
			// this functionality moved to the actual buttons themselves so that these pages work for non-JS browsers
			/*jQuery(_this.domRoot).find('a[name$="#back"]').bind('click', function() {
			_this.onBackClick();
			return false;
			});
			var check = jQuery(_this.domRoot).find('a[name$="#check"]');
			var _url = jQuery(check).attr('href');
			jQuery(check).attr('href', '#');
			//
			jQuery(check).bind('click', function() {
			var url = _url;
			_this.onCheckClick(url);
			return false;
			});*/
			//
			// init IMAGE REVEALS
			/**/
			var reveal = jQuery(_this.domRoot).find('.image-reveal').get();
			var btn = jQuery(reveal).find('.drop-btn').get();
			jQuery(btn).css({
				display : 'block'
			});
			// attach reveal behaviour
			jQuery(btn).bind('click', function() {
				_this.onRevealClick(this);
				return false;
			});
			//
			jQuery(reveal).find('.image-container').css({
				height : 0
			});
			//
			jQuery(reveal).find('.image-container').find('img').css({
				'padding-top' : 20
			});
			//
			// init HELP BUTTONS
			jQuery(_this.domRoot).find('.help-btn').each(function(i, el) {
				// bind click
				jQuery(el).bind('click', function() {
					_this.onHelpClick(this);
					return false;
				});
			});
			// init HELP CLOSE BUTTONS
			jQuery(_this.domRoot).find('.help-close').each(function(i, el) {
				// bind click
				jQuery(el).bind('click', function() {
					_this.onHelpCloseClick(this);
					return false;
				});
			});
			//
			// updates formnext and formback "next_page" values with relevant URL based on vars in hash tag
			_this.setNextPageValues();
		},
		//
		// ---------------------------------------------------------------------------------------------------- //
		// -- CHECK CONNECTION
		// ---------------------------------------------------------------------------------------------------- //
		// called from try to connect button or other scripts in page
		// displays the trying to connect overlay...
		// launches periodic background status checks, communicating with the router via ajax
		checkConnection : function(delay) {
			var _this = this;
			var delaySecs = 0;
			// calculate number of seconds to be displayed in the overlay
			if(delay > 0) {
				delaySecs = delay * _this.CHECK_DELAY;
				// round down to full 10 seconds
				delaySecs = Math.floor(delaySecs / 10000);
				delaySecs *= 10;
			}
			//
			_this.showOverlay('trying', false, delaySecs);
			//
			_this.trying = true;
			_this.booting = false;
			//
			if(delay > 0) {
				_this.checkCount = delay;
			} else {
				_this.checkCount = _this.CHECK_COUNT_TRYING;
			}
			//
			_this.checkSetup();
		},
		// standalone version of above function... called from sky_self_heal-checking.html
		// overlay will be transparent
		checkConnectionSA : function() {
			var _this = this;
			//
			_this.showOverlay('trying', true);
			//
			_this.trying = true;
			_this.booting = false;
			//
			_this.checkCount = _this.CHECK_COUNT_BOOT;
			//
			_this.checkSetup();
		},
		//
		// called periodically from a timeout, to launch a new background check
		// of the router status
		onCheckTimer : function() {
			var _this = this;
			//
			_this.checkCount--;
			if(_this.checkCount > 0) {
				_this.checkSetup();
			} else {
				_this.goNext();
			}
			//
			// PUT POLLING FUNCTION HERE
		},
		// set-up of background ajax request
		checkSetup : function() {
			var _this = this;
			// abort any old xmlhttp requests
			_this.connectingXmlHttp.abort();
			// abort any old timers
			clearTimeout(_this.connectingTimeout);
			//
			_this.connectingTimeout = setTimeout(function() {
				_this.onCheckTimer();
			}, _this.CHECK_DELAY);
			//
			try {
				_this.connectingXmlHttp.onreadystatechange = function() {
					_this.checkStateChange();
				};
				_this.connectingXmlHttp.open("GET", "sky_self_heal_connection_status.cgi", true);
				_this.connectingXmlHttp.send();
			} catch (error) {
				// nothing to do, just wait for the timer
			}
		},
		// set-up of background ajax request
		checkStateChange : function() {
			var _this = this;
			if((_this.connectingXmlHttp.readyState == 4) && ((_this.connectingXmlHttp.status == 200) || (_this.connectingXmlHttp.status == 0))) {
				// if the router responds that it is in a connecting state, clear any timeouts,
				// abort any http requests, and
				if(_this.connectingXmlHttp.responseText.substring(0, 1) == "1") {
					_this.booting = false;
					if(_this.trying == true) {
						_this.trying = false;
						_this.checkCount = _this.CHECK_COUNT_CONNECTING;
						_this.showOverlay('connecting');
						_this.checkSetup();
					}
				} else if(_this.connectingXmlHttp.responseText.substring(0, 1) == "3") {
					_this.booting = true;
				} else if(_this.connectingXmlHttp.responseText.length > 0) {
					if((_this.connectingXmlHttp.responseText.substring(0, 1) == "2") || (_this.trying == false) || (_this.booting == true) || (_this.checkCount == 1)) {
						_this.goNext();
					}
				}
			}
		},

		sendReboot : function() {
			var _this = this;
			// send the reboot cgi request
			try {
				_this.connectingXmlHttp.onreadystatechange = null;
				_this.connectingXmlHttp.open("GET", "sky_self_heal_reboot.cgi", true);
				_this.connectingXmlHttp.send();
			} catch (error) {
				// nothing to do, just wait for the timer
			}

		},
		// initiate a user requested reboot
		cpeReboot : function() {
			var _this = this;
			//
			_this.showOverlay('rebooting');
			//
			_this.trying = true;
			_this.booting = false;
			_this.checkCount = _this.CHECK_COUNT_REBOOTING;
			setTimeout(function(){_this.sendReboot();},2000);//Just to give some delay to show overlay properly.
			// delay the polling setup by a few seconds to allow the router to reboot
			_this.connectingTimeout = setTimeout(function() {
				_this.checkSetup();
			}, _this.CHECK_DELAY);
		},
		// called to retrieve the next full page from the router
		goNext : function() {
			var _this = this;
			// abort any old xmlhttp requests
			_this.connectingXmlHttp.abort();
			// abort any old timers
			clearTimeout(_this.connectingTimeout);
			// hide overlay right before transitioning to a new page
			//this does not look too good - old page appears for a good seconds before the browser goes to a new one
			//window.onunload = function() {Utility.killOverlay();_this.overlay = null;_this.overlayPod = null;_this.overlayActive = false;};
			//
			document.forms[0].submit();
		},
		// called from back button
		goBack : function() {
			var _this = this;
			//
			document.forms[1].submit();
		},
		//
		// ---------------------------------------------------------------------------------------------------- //
		// -- FIBRE JOURNEY UTILITIES
		// ---------------------------------------------------------------------------------------------------- //
		// Called from _this.initPage() if window.location.hash contains "steps="
		// hash will be in the form #steps=X_X_X
		setNextPageValues : function() {
			var _this = this;
			//
			var loc = window.location.href;
			var page = loc.substring((loc.lastIndexOf("/") + 1), loc.lastIndexOf("."));
			var step = page.substr(page.lastIndexOf("step") + 4);
			var hash = window.location.hash;
			//
			if(hash.length > 1) {
				// delete the hash value so that the url looks cleaner... if we try and change the location.href to remove hash altogether page will reload
				window.location.hash = "";
				//
				if(hash.indexOf('steps') != -1) {
					//
					var steps = hash.split("=")[1];
					var array = steps.split("_");
					//
					// set i = to the index of the current step in the array
					for(var i = 0, n = array.length; i < n; i++) {
						if(array[i] == step) {
							break;
						};
					}
					//
					var base = "sky_self_heal_fibre-step";
					var ext = ".html";
					//
					// if we are at the last step in journey... formnext.nextpage = sky_self_heal_fibre-sorry_call_us_msg.html
					if(i == (n - 1)) {
						document.formnext.next_page.value = "sky_self_heal_fibre-sorry_call_us_msg.html";
					} else {
						document.formnext.next_page.value = base + array[i + 1] + ext + hash;
					}
					// if we are at the first step in journey... formback.nextpage = sky_self_heal_fibre-step2.html
					if(i == 0) {
						document.formback.next_page.value = "sky_self_heal_fibre-step2.html";
					} else {
						document.formback.next_page.value = base + array[i - 1] + ext + hash;
					}
				}
			}
		},
		// called from Step2a in the Fibre Journey
		initFibreJourneyA : function() {
			var _this = this;
			//
			var array = _this.parseLightsForm();
			//
			if(array.toString() == "0,0,0,0") {
				// if lights are still all off send user to the "call us" page
				// document.formnext.next_page.value will have already be set by the call to setNextPageValues() when page step2a loads, so all we need to do is call goNext();
				_this.goNext();
			} else {
				// if some lights are illuminated, init the fibre journey as per normal in Step2
				_this.initFibreJourney();
			}
		},
		// called from Step 2 in the Fibre Journey
		initFibreJourney : function() {
			var _this = this;
			//
			var array = _this.parseLightsForm();
			//
			// defaults based on whether power has been selected as solid
			var steps;
			if(array[0] == "1") {
				steps = "5_6_7_8_9";
			} else {
				steps = "4_2a";
			}
			// validate against defined journeys
			switch (array.toString()) {
				case "0,0,0,0":
					//steps = "4";
					steps = "4_2a";
					break;
				case "1,0,0,1":
					//steps = "3_5_6";
					steps = "3_5_6_9";
					break;
				case "1,1,1,0":
					//steps = "4_9";
					steps = "9";
					break;
				case "1,0,0,0":
					steps = "5_6_7_8_9";
					break;
				case "1,0,1,0":
					steps = "5_6_9";
					break;
				case "1,1,0,0":
					steps = "7_8_9";
					break;
				case "1,2,0,0":
					steps = "5_6_7_8_9";
					break;
				case "1,2,1,0":
					steps = "5_6_9";
					break;
				case "1,2,0,1":
					//steps = "3_5_6";
					steps = "3_5_6_9";
					break;
				case "1,1,0,1":
					//steps = "3";
					steps = "3_9";
					break;
				case "1,1,2,0":
					steps = "5_6_7_8_9";
					break;
			}
			//
			var next = steps.split("_")[0];
			//
			//Utility.trace("sky_self_heal_fibre-step"+next+".html#steps-"+steps);
			//
			document.formnext.next_page.value = "sky_self_heal_fibre-step" + next + ".html#steps=" + steps;
			//
			_this.goNext();
		},
		// called from Step 2 in the Fibre Journey
		initFibreOntJourney : function() {
			var _this = this;
			var next_page_value="";
			var array = _this.parseOntLightsForm();
			
			// validate against defined journeys
			switch (array.toString()) {
				case "0,0,0,0":
					next_page_value="sky_self_heal_roi_fibre_ont-scenario1.html";
					break;
				case "1,0,0,0":
					next_page_value="sky_self_heal_roi_fibre_ont-scenario2.html";
					break;
				case "1,0,2,0":
					next_page_value="sky_self_heal_roi_fibre_ont-sorry_call_us_msg.html";
					break;
				case "1,2,0,0":
					next_page_value="sky_self_heal_roi_fibre_ont-scenario4.html";
					break;
				case "1,1,0,0":
					next_page_value="sky_self_heal_roi_fibre_ont-scenario5.html";
					break;
				case "1,1,0,3":
					next_page_value="sky_self_heal_roi_fibre_ont-success.html";
					break;
			}
			document.formnext.next_page.value = next_page_value ;
			_this.goNext();
		},
		initExtOntJourney : function() {
			var _this = this;
			var next_page_value="";
			var array = _this.parseOntLightsForm();
			
			// validate against defined journeys
			switch (array.toString()) {
				case "0,0,0,0":
					next_page_value="sky_self_heal_roi_ext_ont-scenario1.html";
					break;
				case "1,0,0,0":
					next_page_value="sky_self_heal_roi_ext_ont-scenario2.html";
					break;
				case "1,0,2,0":
					next_page_value="sky_self_heal_roi_ext_ont-sorry_call_us_msg.html";
					break;
				case "1,2,0,0":
					next_page_value="sky_self_heal_roi_ext_ont-scenario4.html";
					break;
				case "1,1,0,0":
					next_page_value="sky_self_heal_roi_ext_ont-scenario5.html";
					break;
				case "1,1,0,3":
					next_page_value="sky_self_heal_roi_ext_ont-success.html";
					break;
			}
			document.formnext.next_page.value = next_page_value ;
			_this.goNext();
		},

		parseLightsForm : function() {
			var _this = this;
			//
			var form = document.forms.formlights;
			var power = _this.getValue(form.power);
			var dsl = _this.getValue(form.dsl);
			var lan1 = _this.getValue(form.lan1);
			var lan2 = _this.getValue(form.lan2);
			//
			Utility.trace([power, dsl, lan1, lan2]);
			//
			return [power, dsl, lan1, lan2];
		},
		parseOntLightsForm : function() {
			var _this = this;
			//
			var form = document.forms.formlights;
			var power = _this.getValue(form.power);
			var pon = _this.getValue(form.pon);
			var los = _this.getValue(form.los);
			var lan = _this.getValue(form.lan);
			//
			Utility.trace([power, pon, los, lan]);
			//
			return [power, pon, los, lan];
		},

		//
		getValue : function(group) {
			for(var i = 0, n = group.length; i < n; i++) {
				if(group[i].checked) {
					return group[i].value;
				}
			}
		},
		//
		// ---------------------------------------------------------------------------------------------------- //
		// -- EVENT HANDLERS
		// ---------------------------------------------------------------------------------------------------- //
		//
		//
		onRevealClick : function(el) {
			var _this = this;
			// toggle the reveal element
			var img = jQuery(el).parent().find('.image-container');
			var h = jQuery(img).find('img').outerHeight();
			//
			if(jQuery(img).height() < h) {
				// SHOW image
				jQuery(el).find('span').first().html(replaceText(jQuery(el).find('span').first().html().toString(), 'Show', 'Hide'));
				jQuery(el).find('.drop-arrow').removeClass('da-down').addClass('da-up');
				//
				jQuery(img).stop().animate({
					height : h
				}, 400, 'easeOutCubic', function() {
					// Animation complete
				});
			} else {
				// HIDE image
				jQuery(el).find('span').first().html(replaceText(jQuery(el).find('span').first().html().toString(), 'Hide', 'Show'));
				jQuery(el).find('.drop-arrow').removeClass('da-up').addClass('da-down');
				//
				jQuery(img).stop().animate({
					height : 0
				}, 400, 'easeOutCubic', function() {
					// Animation complete
				});
			}
			//
			function replaceText(html, a, b) {
				var str = html.replace(a, b);
				return str;
			}

		},
		//
		onHelpClick : function(el) {
			var _this = this;
			//
			var id = jQuery(el).attr('name');
			var posy = jQuery(el).parent().position().top - 27;
			//
			// hide all help pods... reveal active help pod
			jQuery(_this.domRoot).find('.pod-help').each(function(i, el) {
				if(jQuery(el).attr('id') == id) {
					jQuery(el).css({
						position : 'absolute',
						top : posy,
						display : 'block'
					});
				} else {
					jQuery(el).css('display', 'none');
				}
			});
		},
		//
		onHelpCloseClick : function(el) {
			var _this = this;
			//
			var pod = jQuery(el).parent().css('display', 'none');
		},
		//
		// ---------------------------------------------------------------------------------------------------- //
		// -- OVERLAY
		// ---------------------------------------------------------------------------------------------------- //
		//
		showOverlay : function(ref, transparent, delay) {
			var _this = this;
			//
			Utility.trace("showOverlay: " + ref);
			//
			var opacity = (transparent == true) ? 0 : 0.8;
			//var spinner = (jQuery('body').hasClass('fibre')) ? "icon_spinner_purple.gif" : "icon_spinner.gif";   
			var spinner = "icon_spinner.gif"; //all spinners are now purple
			//
			//window.location.hash = "checking";
			//
			if(_this.overlay == null) {
				_this.overlay = Utility.createOverlay('body', {
					rgb : '#000000',
					opacity : opacity
				});
				//
				jQuery(_this.overlay).css({
					opacity : 0,
					visibility : 'visible'
				});
				//
				//
				insertHTML = '<div class="pod-checking">';
				insertHTML += '<div class="content">';
				//insertHTML += '<div class="icon-spinner"><span class="spinner"><img src="../../html_sky_selfheal_vdsl/assets/js/'+Utility.pathmodifier()+'assets/images/'+ spinner + '" width="100%" height="100%" /></span></div>';
				insertHTML += '<div class="icon-spinner"><span class="spinner"><img src="../'+Utility.pathmodifier()+'assets/images/'+ spinner + '" width="100%" height="100%" /></span></div>'
				insertHTML += '<h1></h1>';
				insertHTML += '<p></p>';
				insertHTML += '</div>';
				insertHTML += '</div>';
				//
				_this.overlayPod = jQuery(insertHTML).get();
				//
				jQuery(_this.overlayPod).css({
					position : 'absolute',
					visibility : 'hidden',
					display : 'block'
					//
				});
				jQuery(_this.overlay).append(_this.overlayPod);

			}
			//
			// UPDATE OVERLAY POD MESSAGE
			_this.updateOverlayPod(ref, delay);
			//
			if(_this.overlayActive == false) {
				//
				_this.overlayActive = true;
				//
				var containerWidth = jQuery(window).width();
				var containerHeight = jQuery(window).height();
				//jQuery(_this.overlay).height();
				var w = jQuery(_this.overlayPod).width();
				var h = jQuery(_this.overlayPod).height();
				var podRect = {
					"x" : "center",
					"y" : "center",
					"w" : w,
					"h" : h
				};
				//
				var pos = Utility.getAbsolutePositionValues(podRect, containerWidth, containerHeight);
				//alert(pos.x + ":" + pos.y + ":" + pos.w + ":" + pos.h);
				//
				if(navigator.userAgent.indexOf('IEMobile') != -1) {
					jQuery(_this.overlay).css({
						height : jQuery(document).height()
					});
				}
				//
				if(navigator.userAgent.indexOf('BlackBerry') != -1) {
					jQuery(_this.overlay).css({
						height : jQuery(document).height()
					});
					jQuery(_this.overlayPod).css({
						left : pos.x,
						top : pos.y,
						visibility : 'visible'
					});
				} else {
					jQuery(_this.overlay).animate({
						opacity : 1
					}, 500, function() {
						// Animation complete
						jQuery(_this.overlayPod).css({
							left : pos.x,
							top : (containerHeight + 10),
							visibility : 'visible'
						}).animate({
							top : pos.y
						}, 1000, 'easeOutBack', function() {
							// Animation complete
							if(!touch) {
								jQuery(this).css({
									'margin-left' : '-' + (w / 2) + 'px',
									'margin-top' : '-' + (h / 2) + 'px',
									left : '50%',
									top : '50%'
								});
							}
						});
					});
				}
			}
		},
		//
		updateOverlayPod : function(ref, delay) {
			var _this = this;
			var tryingDelay = 45;
			//
			if(delay > 0) {
				tryingDelay = delay;
			}
			//
			Utility.trace("updateOverlayPod: " + ref);
			//
			if(!jQuery('#overlay').length > 0) {
				_this.showOverlay(ref);
				return;
			}
			//
			var c = jQuery(_this.overlay).find('.content');
			var s = jQuery(_this.overlay).find('.icon-spinner');
			var h = jQuery(_this.overlay).find('h1');
			var p = jQuery(_this.overlay).find('p');
			//
			jQuery(c).css('text-align', 'center');
			jQuery(s).css('display', 'block');
			//
			switch (ref) {
				case 'trying':
					jQuery(h).html('Trying to connect');
					jQuery(p).html('Please wait. This can take up to ' + tryingDelay + ' seconds.');
					break;
				case 'connecting':
					jQuery(h).html('Connecting...');
					jQuery(p).html('This is usually pretty quick but could take up to 4 minutes.');
					break;
				case 'rebooting':
					jQuery(h).html('Restarting Sky Hub');
					jQuery(p).html('This is usually pretty quick but could take up to 2 minutes.');
					break;
				case 'error':
					jQuery(c).css('text-align', 'left');
					jQuery(s).css('display', 'none');
					jQuery(h).html('Cannot Connect To Sky Hub');
					var msg = 'Check that your Sky Hub is plugged in to the mains power and reload the page to try again.<br\><br\>';
					msg += 'If you still can\'t connect, call us on <strong>0845 123 456</strong> and a Sky representative will take you through the next steps in fixing your connection.';
					jQuery(p).html(msg);
					break;
			}
		},
		//
		hideOverlay : function(i) {
			var _this = this;
			//
			var tl = jQuery({});
			tl.queue("hideAnim");
			//
			tl.queue("hideAnim", function(next) {
				next();
				jQuery(_this.overlayPod).animate({
					top : jQuery(_this.overlay).height()
				}, 500, 'easeInBack', function() {
					// Animation complete
				});
			});
			tl.delay(300, "hideAnim");
			tl.queue("hideAnim", function(next) {
				//
				jQuery(_this.overlay).animate({
					opacity : 0
				}, 500, function() {
					Utility.killOverlay();
					_this.overlay = null;
					_this.overlayPod = null;
					_this.overlayActive = false;
					tl.clearQueue("hideAnim");
				});
			});
			// start the queue
			tl.dequeue("hideAnim");
		}
	}
	// ---------------------------------------------------------------------------------------------------- //
	// -- INIT
	// ---------------------------------------------------------------------------------------------------- //
	$(function(){
		//Utility.trace("DOCUMENT READY");
		//
		window.app = new App({
			domRoot : jQuery(this).find('#content')
		}).init();
	});
	//
	// ---------------------------------------------------------------------------------------------------- //
	// -- UPDATE HEAD ELEMENTS
	// ---------------------------------------------------------------------------------------------------- //
	var iPad = (navigator.userAgent.indexOf('iPad') != -1);
	//
	if(iPad) {
		// change viewport for iPad
		// <meta name="viewport" content="width=1000">
		jQuery('meta[name="viewport"]').attr('content', 'width=1000');
		// change css for iPad
		// <link type="text/css" rel="stylesheet" href="../../html_sky_selfheal_vdsl/assets/js/assets/css/main-mobile.css"/>
		jQuery('link[href*="mobile.css"]').attr('href', 'assets/css/ipad.css');
	}
	// for small desktop displays we remove the mobile css as the media query includes up to widths of 1024
	var touch = Modernizr.touch;
	if(screen.width >= 1024 && !touch) {
		jQuery('link[href*="mobile.css"]').remove();
	}
})();
