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

/**
 * 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 isActOrNsw;
      var isUserLoggedIn;
      var localityState;

      // The user is logged in
      if (userState.myAllHomesUserEmail != null) {
         isUserLoggedIn = true;
         // Set the state that we're interested in to the My allhomes user's registered state.
         localityState = userState.stateAbbreviation;
      }      // The user is not logged in
      else {
         isUserLoggedIn = false;
         // Set the state that we're interested in to the value of the state picker drop down.
         localityState = allhomes.stateDropDown.activeState;
      }

      if (localityState != null) {
         // Convert the state abbreviation to lowercase to use in URLs
         localityState = localityState.toLowerCase();

         // Store whether the state is ACT or NSW as functionality of the My allhomes navigation links
         // is different for ACT and NSW users
         if (localityState == "act" || localityState == "nsw") {
            isActOrNsw = true;
         }
         else {
            isActOrNsw = false;
         }        
      }

      // User is logged in
      if (isUserLoggedIn) {

         // Set the login links appropriately
         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>';

         // My allhomes users from the ACT or NSW can access the OLD EmailDirect+
         if (isActOrNsw) {
            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>';
         }
         // My allhomes users not from the ACT or NSW (TAS atm) can only access NEW EmailDirect
         else {
            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/email-direct/about.ade">EmailDirect</a>' + 
                '</span></li></ol>';
         }
      }
      // User is not logged in
      else {

         // Set the login links appropriately.
         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>';

         // Public users from the ACT or NSW can access OLD EmailDirect
         if (isActOrNsw) {
            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>';
         }
         // Public users not from the ACT or NSW can access NEW EmailDirect
         else {
            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/about.ade">EmailDirect</a>' +
                '</span></li></ol>';
         }

      }

      document.fire("allhomes:userstatus", {isUserLoggedIn: isUserLoggedIn});
   }
}

 /**
  * Generate the State Drop Down.  It uses JSON to configure it, which is injected as a global allhomes.stateDropDown variable.
  * @return
  */
function generateStateDropDown() {
   var states = $H(allhomes.stateDropDown.otherStates);
   var curState = allhomes.stateDropDown.activeState;

   // Show the allclassifieds/capital jobs link if we are in ACT or NSW
   if (curState == 'ACT' || curState == 'NSW'){
      $('capitalJobsLink').show();
      $('allclassifiedsLink').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);
   });   
   
   // Save the current State to the Cookie.
   setStateCookie(allhomes.stateDropDown.activeState);
}

function handleSelectorClick(event) {
   $('stateDropDown').hide();
   
   // We only want to save the Cookie again if the click came from a child (which will only be an <a> tag) of the stateDropDown div.
   var element = event.findElement();
   var parentNode = element.parentNode;
   if (parentNode != undefined && parentNode.id == 'stateDropDown'){
       setStateCookie(element.innerHTML);
   }
   // Unregister the click handler as we don't need to accept clicks anymore.
   document.stopObserving('click', handleSelectorClick);
}

/**
 * Set the given State in a cookie. Which is used when there is no State in personalisation.
 */
function setStateCookie(state) {
    // Expire the cookie in 1 year.
    var days = 365;
    var today = new Date();
    var expires = days * 86400000;
    expires = ';expires=' + new Date(today.getTime() + expires);
    // Write the cookie to the browser.
    document.cookie = allhomes.stateCookieName + '=' + encodeURIComponent(state) + ';path=/' + expires;
}

/*
 * 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');
      }
   }
}

/**
 * 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);
   }
}

