/**
 * This common JavaScript library is dependent on the Prototype JavaScript Framework.
 * See: http://www.prototypejs.org/
 */

/**
 * Create the mfos namespace.
 */
var mfos = {};

/**
 * Create the OpenX output array.
 */
var OA_output = new Array();

/**
 * Add a listener to the dom:loaded or DOM Ready event. This event fires when
 * the JavaScript DOM is ready to be used. dom:loaded is a special prototype
 * event see here: http://www.prototypejs.org/api/document/observe It is cross
 * browser compatible. For compatibility sake the function name remains as
 * addOnLoadListener even though it is not technically correct.
 *
 * @param fn
 *            The function to callback when the DOM has loaded.
 */
function addOnLoadListener(fn) {
   // If the DOM is already done, then execute the function straight away.
   if (document.loaded) {
      fn();
   } else {
      document.observe("dom:loaded", fn);
   }
}

/*
 * Add a listener to the unload event.
 */
function addOnUnloadListener(fn)
{
   if (typeof window.addEventListener != 'undefined') {
      window.addEventListener('unload', fn, false);
   }
   else if (typeof document.addEventListener != 'undefined') {
      document.addEventListener('unload', fn, false);
   }
   else if (typeof window.attachEvent != 'undefined') {
      window.attachEvent('onunload', fn);
   }
   else {
      var oldfn = window.onunload;
      if (typeof window.onunload != 'function') {
         window.onunload = fn;
      }
      else {
         window.onunload = function() {
            oldfn();
            fn();
         };
      }
   }
}

/*
 * Functions to be called when an allhomes public pages DOM has been loaded.
 */
function loadHomesPublic(location) {
   searchBoxDefault();
   newMyAllhomesUserRequest();
}

/*
 * Returns a new HTTP Request for the purpose of requesting an XML document.
 */
function createXmlRequest() {
   var httpRequest;

   if (window.XMLHttpRequest) {
      // Mozilla and Safari
      httpRequest = new XMLHttpRequest();
      if (httpRequest.overrideMimeType) {
         //
         httpRequest.overrideMimeType('text/xml');
      }
   }
   else if (window.ActiveXObject) {
      // IE
      try {
         httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
      }
      catch (e) {
         try {
            httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
         }
         catch (e) {}
      }
   }
   return httpRequest;
}

// http://support.internetconnection.net/CODE_LIBRARY/Javascript_Open_Window_Script.shtml
function openCenteredWindow(mypage,w,h,myname,features) {
   if(screen.width){
      var winl = (screen.width-w)/2;
      var wint = (screen.height-h)/2;
   }else{
      winl = 0;wint =0;
   }

   if (winl < 0) winl = 0;
   if (wint < 0) wint = 0;
   var settings = 'height=' + h + ',';
   settings += 'width=' + w + ',';
   settings += 'top=' + wint + ',';
   settings += 'left=' + winl + ',';
   settings += features;
   win = window.open(mypage,myname,settings);
   win.window.focus();
}

/*
 * Send an asynchronous request for My allhomes user username.
 * The response will be an XML document containing the myallhomes user username or
 * a casual user identification number.
 */
function newMyAllhomesUserRequest() {

   new Ajax.Request('/ah/ahtwyli', {
      method: 'get',
      onSuccess: updateMyAllhomesUserDisplay
   });

}

/*
 * Callback function used to process the response of the new bannerad request.
 * It parses the XML document and inserts the myallhomes logon or casual user id xhtml.
 *
 * Only one parameter should be filled out at the same moment, either "myallhomesuser"
 * or "casualallhomesuser".
 */
function updateMyAllhomesUserDisplay(transport) {

   var userState = transport.responseJSON;

   if (userState) {
      // Update href and image source
      var mahLoginLinks = document.getElementById('mahLogin');
      var mahMainLinks = document.getElementById('mahMain');
      var isUserLoggedIn;

      // User is logged in
      if (userState.myAllHomesUserEmail != null) {
    	  isUserLoggedIn = true;
    	  
    	  mahLoginLinks.innerHTML =
            '<strong>' + userState.myAllHomesUserEmail + '</strong>&nbsp;|&nbsp;' +
            '<a target="_parent" href="/ah/myallhomes/secure/welcome/view">My Account</a>&nbsp;|&nbsp;' +            
            '<a target="_parent" href="/ah/myallhomes/secure/logout">Sign out</a>';
    	  
    	  mahMainLinks.innerHTML =
    		'<ol id="myah"><li><span class="wrap">'+
            '<span class="myah_tm"><a target="_parent" href="/ah/myallhomes/secure/welcome/view"><span class="my">My&nbsp;</span><span class="all">all</span><span class="homes">homes</span></a></span>&nbsp;|&nbsp;' +
            '<a href="/ah/myallhomes/watch-list/view">Watch List</a>&nbsp;|&nbsp;' + 
            '<a href="/ah/myallhomes/trip-plan/view">Trip Plan</a>&nbsp;|&nbsp;' + 
            '<a href="/ah/myallhomes/secure/email-direct-plus/view">EmailDirect+</a>' + 
            '</span></li></ol>';            
      }
      // User is not logged in
      else {
    	  isUserLoggedIn = false;
    	  mahLoginLinks.innerHTML =
    	    '<span class="myah_tm"><a target="_parent" href="/ah/myallhomes/secure/welcome/view"><span class="my">My&nbsp;</span><span class="all">all</span><span class="homes">homes</span></a></span>&nbsp;&nbsp;' +
            '<a target="_parent" href="/ah/myallhomes/secure/welcome/view">Sign in</a>';              
    	  
    	  mahMainLinks.innerHTML =
    		  '<ol id="myah"><li><span class="wrap">'+
              '<a href="/ah/myallhomes/watch-list/view">Watch List</a>&nbsp;|&nbsp;' + 
              '<a href="/ah/myallhomes/trip-plan/view">Trip Plan</a>&nbsp;|&nbsp;' + 
              '<a href="/ah/myallhomes/email-direct/view">EmailDirect</a>'+
              '</span></li></ol>';
      }
     
      document.fire("allhomes:userstatus", {isUserLoggedIn: isUserLoggedIn});
   }
}
 
function generateStateDropDown(stateDropDownJson) {
	var states = $H(stateDropDownJson.otherStates);
	var curState = stateDropDownJson.activeState;
	
	// Show the capital jobs link if we are in ACT or NSW
	if (curState == 'ACT' || curState == 'NSW'){
		$('capitalJobsLink').show();
	}
	
	var selector = new Element('span').update('&nbsp;&nbsp;<a href="#" id="stateSelector"><u>' + curState + '</u> <small>&#9660;</small></a>&nbsp;');
	
	var tNav = $('tertiary_navigation');
	tNav.select('div.header_left strong')[0].insert({after: selector});
	
	var dropDown = new Element('div', {id: 'stateDropDown', style: 'display: none;'});
	
	// Create the links for the remaining states.
	states.each(function(pair) {
		var state = new Element('a', {href: pair.value}).update(pair.key);
		dropDown.insert(state);
	});
	
	tNav.insert(dropDown);
	
	var navDim = tNav.getDimensions();
	var navOff = tNav.positionedOffset();
	var offset = $('stateSelector').positionedOffset();
	$('stateDropDown').setStyle({
	   left: (offset.left - 6) + 'px', // - 6 is 5px padding - 1px border
	   top: (navDim.height + navOff.top - 1) + 'px'
	});
	$('stateSelector').observe('click', function(event) {
		var sdd = $('stateDropDown');
		
		if (sdd.visible() == false) {
			// Setup click close handler
			document.observe('click', handleSelectorClick);
			sdd.show();
		}
		else {
			sdd.hide();
		}
		
		// We don't want to follow the href, because it is just a toggle switch.
		Event.stop(event);
	});
}

function handleSelectorClick(event) {
	$('stateDropDown').hide();
	// Unregister the click handler as we don't need to accept clicks anymore.
	document.stopObserving('click', handleSelectorClick);
}

/*
 * Focus event handler for the search box
 */
function searchBoxFocus() {
   var sb = document.getElementById('searchBox');
   //toggleSBSize(sb, true);
   toggleSBAutoClear(sb,true);
}

function searchBoxFocusById(id) {
   var sb = document.getElementById(id);
   toggleSBAutoClear(sb,true);
}

/*
 * Blur event handler for the search box
 */
function searchBoxBlur() {
   var sb = document.getElementById('searchBox');
   //toggleSBSize(sb, false);
   toggleSBAutoClear(sb,false);
}

function searchBoxBlurById(id) {
   var sb = document.getElementById(id);
   //toggleSBSize(sb, false);
   toggleSBAutoClear(sb,false);
}

/*
 * Change the size of the Search Box when it gets or looses focus
 */
function toggleSBSize(sb, big) {
    if (big) {
        sb.style.width = '25em';
    }
    else {
        sb.style.width = '8em';
    }
}

/*
 * Remove the default search text when the search box gets focus and
 * replace the default serach text when the search box looses focus.
 * But only if the value of the search box is empty.
 *
 * Based on http://lab.dotjay.co.uk/experiments/forms/input-placeholder-text/
 */
function toggleSBAutoClear(sb, focus) {
   sb = $(sb);
   if (focus) {
      if (sb.value == sb.title) {
         sb.value = '';
         sb.removeClassName('inputFieldEmpty');
      }
   }
   else {
      if (sb.value == '') {
         sb.value = sb.title;
         if (!sb.hasClassName('inputFieldEmpty')) {
            sb.addClassName('inputFieldEmpty');
         }
      }
   }
}

/*
 * Set the default Search Box text from the title tag if the value is empty.
 */
function searchBoxDefault() {
   var sb = $('searchBox');
   if (sb) {
      if (sb.value == '') {
         sb.value = sb.title;
         sb.addClassName('inputFieldEmpty');
      }
   }
}

/**
 * Register a region on the page where you want an OpenX ad to go.
 * This function must be called before requestOAValues otherwise the ad will not be fetched.
 *
 * @param element - The HTML Element where the ad should be placed.
 * @param zoneid - The OpenX zone id of the ad to fetch.
 */
function registerOA(element, zoneid) {
   if (typeof mfos.adRegister == "undefined") {
      mfos.adRegister = new Hash();
   }
   mfos.adRegister.set(zoneid, element);
}

/**
 * Add an ad variable context for the request.
 * This function must be called before requestOAValues otherwise the context will not
 * be included in the determinations of ad's.
 *
 * @param name - The openx variable name to include in all requests
 * @param value - The value of the variable
 */
function registerOAVariableContext(name, value) {
   if (typeof mfos.adVariableContext == "undefined") {
      mfos.adVariableContext = new Hash();
   }
   mfos.adVariableContext.set(name, value);
}

/**
 * Generate a url that will fetch ads for the given zone ids.
 * Makes use of the mfos.basURL global variable. And the list of ad context variables
 *
 * This function is based on the OpenX JavaScript in the following file:
 * /openx/www/delivery/spcjs.php?id=3
 * If OpenX undergoes major upgrades this may need to be updated.
 *
 * @param zoneidArray - An array of zone ids that ads are required for.
 * @return A url that will return the ads for the given zones in a JavaScript array.
 */
function generateOAUrl(zoneidArray) {
   var zoneids = escape(zoneidArray.join('|'));
   var proto = (("https:" == document.location.protocol) ? "https://" : "http://");
   var url = proto + mfos.baseURL + "/delivery/spc.php?zones=" + zoneids;

   // Insert the ad context
   if (typeof mfos.adVariableContext != "undefined") {
      mfos.adVariableContext.each(function(pair) {
         url += "&" + escape(pair.key) + "=" + escape(pair.value);
      });
   }

   url += "&r=" + Math.floor(Math.random() * 99999999999);
   url += (document.charset ? '&charset=' + document.charset
         : (document.characterSet ? '&charset=' + document.characterSet
               : ''));
   if (window.location)
      url += "&loc=" + escape(window.location);
   if (document.referrer)
      url += "&referer=" + escape(document.referrer);

   return url;
}

/**
 * Request all the ads that have been registered on the page from the OpenX ad server and display the ads.
 *
 * This function uses the mfos.adRegister Hash table.
 * Only ads that have been registered with registerOA will be used.
 */
function requestOAValues() {
   // Check that we have the mfos openx base url and the adRegister has something in it.
   if (!(mfos.baseURL || (mfos.adRegister && mfos.adRegister.length == 0))) {
      return false;
   }

   var zoneids = mfos.adRegister.keys();

   var url = generateOAUrl(zoneids);

   // For Safari <= 3.x compatibility
   var legacy = {
      expression: function() {
         if (OA_output.length > 0) {
            return true;
         }
         else {
            return false;
         }
      }
   };

   // Get the Ads from the OpenX Ad Server.
   loadScript(url, function() {
      // Insert the ad content into the HTML elements registered with registerOA.
      mfos.adRegister.each(function(pair) {
         $(pair.value).update(OA_output[pair.key]);
      });
   }, legacy);
}

/**
 * Refresh the OpenX banner on demand. This function allows pages to refresh the
 * banner when refreshing parts of the page via ajax like callbacks.
 *
 * @param element - The HTML Element where the ad should be placed.
 * @param zoneid - The OpenX zone id of the ad to fetch.
 */
function refreshOA(element, zoneid) {
   // Check that we have the mfos openx base url, if not get us out of here.
   if (!(mfos.baseURL)) {
      return false;
   }

   // Get the OpenX URL for getting data from one zone, generateOAUrl expects an array which is why zoneid is surrounded in [].
   var url = generateOAUrl([zoneid]);

   // Clear out the old ad data for the given zoneid. This is required for compatibility with old Safari 3.x
   OA_output[zoneid] = null;

   // Compatibility with old Safari < 3.x
   var legacy = {
      expression: function() {
         var args = $A(arguments);
         if (OA_output[args[0]] != null) {
            return true;
         }
         else {
            return false;
         }
      }.bind(this,zoneid)
   };

   // Get the Ad from the OpenX Ad Server.
   loadScript(url, function(element, zoneid) {
      // Insert the ad content into the HTML elements registered with registerOA.
      $(element).update(OA_output[zoneid]);
   }.bind(this,element,zoneid), legacy);
}

/**
 * Update a URL's protocol with the current locations protocol.
 * This function will normally be used to change the protocol on
 * resources to match the requested location.
 *
 * @param URL to update
 * @return updated URL
 */
function updateProtocol(url) {
   var protocol=location.protocol=='https:'?'https:':'http:';
   return url.replace(/http(s){0,1}:/, protocol);
}

/**
 * Create allhomes.legacy object.
 */
var allhomes = {};
allhomes.legacy = {};
/**
 * Used for Safari < 3.x compatibility.
 * timeout: number of milliseconds because the request is discarded.
 * frequency: how often to check if the request has completed.
 */
allhomes.legacy.timeout = 10000;
allhomes.legacy.frequency = 50;

// Find the WebKit version, we need it to filter out content for old Safari < 3.x users.
if (Prototype.Browser.WebKit) {
   Prototype.Browser.WebKitVersion = 0;
   var m = navigator.userAgent.match(/AppleWebKit\/([^\s]*)/);
   if (m && m[1]) {
      Prototype.Browser.WebKitVersion = parseFloat(m[1]);
   }
}

/**
 * Load the given script via a <script> element, which allows for cross site
 * scripting.
 *
 * @param scriptSrc - The script to call.
 * @param callBack - The function to call back after the script has loaded. Optional
 * @param legacy - Object that contains options for detecting callback completion with Safari < 3.x.  Optional
 */
function loadScript(scriptSrc, callBack, legacy) {
   var n = new Element("script", {
      type :"text/javascript",
      src :scriptSrc
   });

   // Only register the callBack if a callBack function was actually provided!
   if (typeof callBack != "undefined") {
      // Now we need to handle the various browser callbacks that happen when the
      // script has loaded.

      // Internet Explorer
      if (Prototype.Browser.IE) {
         n.onreadystatechange = function() {
            var rs = this.readyState;
            if ("loaded" === rs || "complete" === rs) {
               // Stop the event firing twice.
               n.onreadystatechange = null;
               callBack();
            }
         };
      }
      // Safari and probably Google Chrome
      // Safari < 3.x won't work so we will skip them (webkit version < 420)
      else if (Prototype.Browser.WebKit) {
         var webkitVersion = Prototype.Browser.WebKitVersion;
         if (webkitVersion == 0 || webkitVersion >= 420) {
            n.addEventListener("load", function() {
               callBack();
            });
         }
         // Don't register an event for old Safari (< 3.x), use legacy detection
         else {
            if (legacy.varName || legacy.expression) {
               legacyCallBackTimer(legacy, callBack, allhomes.legacy.timeout / allhomes.legacy.frequency);
            }
         }
      }
      // Firefox, Opera and everyone else.
      else {
         n.onload = function() {
            callBack();
         };
      }
   }

   // Insert the script into the HTML HEAD.
   $$("head")[0].insert(n);
}

/**
 * A timer for use with old Safari browsers < 3.x, that looks for a variable to exist or an expression to be true.
 * Once that exists the callBack method is executed.  This method will keep trying until retries is 0.
 *
 * @param legacy - An Object that has 2 potential options: expression or varName, 'expression' contains a function
 *                that must return true or false. 'varName' contains a variable name that when it exists means
 *                that the script has completed.
 * @param callBack - The function to call back on completion of script.
 * @param retries - The number of times to retry before giving up.
 */
function legacyCallBackTimer(legacy, callBack, retries) {
   if (typeof legacy.expression != "undefined" && legacy.expression()) {
      callBack();
      return;
   }
   else if (typeof legacy.varName != "undefined" && typeof window[legacy.varName] != "undefined") {
      callBack();
      return;
   }

   if (retries > 0) {
      retries--;
      window.setTimeout(function() {
         legacyCallBackTimer(legacy, callBack, retries)
      }, allhomes.legacy.frequency);
   }
}
