// Global JavaScript Document For MyFedLoan

/*jslint white: true, onevar: true, browser: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, indent: 2 */

/*global window, PHEAA, ActiveXObject, jQuery, $ */

var myFedLoan = (function () {
	
  // Set Array.prototype.forEach method
  if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (fnCallback, oOptional) {
      var i, iLength;
      
      if (typeof fnCallback !== "function") {
        throw new TypeError();
      }

      for (i = 0, iLength = this.length; i < iLength; i += 1) {
        if (i in this) { // Skip over any holes in the array;
          fnCallback.apply(oOptional || this, [this[i], i, this]);
        }
      }

    };
  }
  
  // Set String.prototype.trim method
  if (!String.prototype.trim) {
    String.prototype.trim = function () {
      var re = /^\s+|\s+$/g;
      return this.replace(re, "");
    };
  }

  var fnShow = function () {
    var oSource = $(this);
    
    if (oSource.data("oTarget")) {
      $(oSource.data("oTarget")).removeClass("hide").find("a").attr("tabindex", 0).end();
      oSource.addClass("activeLink").blur();
    }
    
  },
  
  fnHide = function () {
    var oSource = $(this);
    
    if (oSource.data("oTarget")) {
      $(oSource.data("oTarget")).addClass("hide").find("a").attr("tabindex", -1).end();
      oSource.removeClass("activeLink").blur();
    }
    
  },
  
  fnToggle = function () {
    var oSource = $(this);
    
    if (oSource.data("oTarget")) {
      if (oSource.hasClass("activeLink")) {
        $(oSource.data("oTarget")).addClass("hide").find("a").attr("tabindex", -1).end();
        oSource.removeClass("activeLink");
      } else {
        $(oSource.data("oTarget")).removeClass("hide").find("a").attr("tabindex", 0).end();
        oSource.addClass("activeLink");
      }    
    }
  }, 
  
  // Changes link text between Hide and View
  fnChangeViewTitle = function () {
    var iTitleIndex = this.innerHTML.indexOf("View"),
    sTitleText,
    sReturnText = "";
    
    if (iTitleIndex !== -1) {
      sTitleText = "Hide";
    } else if ((iTitleIndex = this.innerHTML.indexOf("Hide")) !== -1) {
      sTitleText = "View";
    } else {
      return;
    }
    
    if (iTitleIndex > 0) {
      sReturnText += this.innerHTML.slice(0, iTitleIndex);
    }
    
    sReturnText += sTitleText;
    
    if (iTitleIndex + 4 < this.innerHTML.length) {
      sReturnText += this.innerHTML.slice(iTitleIndex + 4);
    }
    
    this.innerHTML = sReturnText;
    
  },
  
  fnCreate = function (oObj) { // Method to create new dom elements;
    // Instantiate variables;
    var i, 
    // Build requested element;
    oElem = document.createElement(oObj.elem);
     
    // Add attributes, if present;
    if (oObj.attributes) {
      for (i in oObj.attributes) {
        if (oObj.attributes.hasOwnProperty(i)) {
          oElem[i] = oObj.attributes[i];
        }
      }
    }
    
    // Set style declarations, if present;
    if (oObj.style) {
      for (i in oObj.style) {
        if (oObj.style.hasOwnProperty(i)) {
          oElem.style[i] = oObj.style[i];
        }
      }
    }
    
    // Append Children, if present;
    if (oObj.children) {
      for (i = 0; i < oObj.children.length; i += 1) {
        oElem.appendChild(oObj.children[i]);
      }
    }
    
    // Return new element;
    return oElem;
  }, 
        
  // Method to open external links in new windows;
  fnTargetBlank = function () {

    // Instantiate loop variables;
    var i, iLength,  
    // Collect all links on the page;
    cLinks = document.getElementsByTagName("a"), 
    
    // Method to open a new window;
    fnOpenWindow = function () {
      
      // Instantiate variables;
      var wChild, 
      // Test to see if this is a contact form link;
      bContactForm = this.getAttribute("rel") === "contact_form", 
      // Build optional window arguments;
      sArguments = bContactForm ?
        "scrollbars" : "", 
      // Test to see if there are existing querystring variables;
      sModifier = this.getAttribute("href").indexOf("?") !== -1 ? 
        "&" : "?", 
      dNow = new Date();
          
      // Attempt to open a new window;
      if (bContactForm) {
        wChild = window.open(this.getAttribute("href") + sModifier + "javascriptEnabled=true", this.getAttribute("rel") + dNow.getMilliseconds(), sArguments);
      } else {
        wChild = window.open(this.getAttribute("href"), this.getAttribute("rel") + dNow.getMilliseconds(), sArguments);
      }
        
      return !wChild ? 
        true : // failed to open so follow link;
        false; // success, open new browser window;
    };
    
    // Attach new window method to appropriate links;
    for (i = 0, iLength = cLinks.length; i < iLength; i += 1) {
      if (cLinks[i].getAttribute("rel") && 
          (cLinks[i].getAttribute("rel") === "external" ||
           cLinks[i].getAttribute("rel") === "generic" ||
           cLinks[i].getAttribute("rel") === "pdf" || 
           cLinks[i].getAttribute("rel") === "excel" ||
           cLinks[i].getAttribute("rel") === "word" ||
           cLinks[i].getAttribute("rel") === "ppt" ||
           cLinks[i].getAttribute("rel") === "accountaccess" || 
           cLinks[i].getAttribute("rel") === "contact_form")) {
        cLinks[i].onclick = fnOpenWindow;
      }
    }
  },  
  
  // Method to clone search functionality into footer;
  fnSetSearchBox = function () {
    // Instantiate variables;
    var sSearchDefaultText = "Enter Search Term...",
    // Array of search forms;
    oSearchForm = $("#search"),
    // Array of text search fields;
    oTextField = $("#sp-q");
    
    oTextField.focus(function () {
      if (this.value.trim() === sSearchDefaultText) {
        this.value = "";
        $(this).removeClass("default");
      }
    }).blur(function () {
      if (this.value.trim() === "") {
        this.value = sSearchDefaultText;
        $(this).addClass("default");
      }
    });
    
    oSearchForm.submit(function () {
      if (oTextField.val().trim() === sSearchDefaultText || oTextField.val().trim() === "") {
        return false;
      }
    });
    
  },
  
  // General method to enable hide/show functionality;
  fnSetHideShow = function () {
    // Initialize variables;
    var i, iLength,  
    reHide = /\bhide\b/, // Reg Exp to add/remove hide class from elements;
    reText = /(View|Hide)/, // Reg Exp to change text in target elements;
    reEnabled = /\bhsTarget\b/, // Reg Exp to change class on targets;
    
    // Sections to activate hide/show method within;
    aParents = myFedLoan.getElementsByClassName("hsParent"), 
    
    // Method to hide/show elements;
    fnHideShow = function () {
      // Make sure referring object has target and result arrays;
      if (typeof this.aResults !== "object" || 
          this.aResults.constructor !== Array || 
          typeof this.aTargets !== "object" || 
          this.aTargets.constructor !== Array) {
        return true;
      }
      
      // Initialize variables;
      var sMethod;
      
      // Show/hide elements;
      this.aResults.forEach(function (oElem) {
        if (oElem.className.match(reHide)) {
          oElem.className = oElem.className.replace(reHide, "").trim();
        } else {
          oElem.className += " hide";
        }
      });
      
      // Adjust text of target elements;
      this.aTargets.forEach(function (oElem) {
        if (oElem.innerHTML.match(reText)) {
          sMethod = RegExp.$1 === "View" ? 
            "Hide" : "View";
          oElem.innerHTML = oElem.innerHTML.replace(reText, sMethod);
          oElem.style.backgroundPosition = RegExp.$1 === "View" ? 
            "0px -58px" : "0px 0px";
        }
      });
    }, 
    
    // Method to cancel default action on targets;
    fnCancelDefault = function (e) {
      // Cancel method if parent element isn't registered;
      if (typeof this.hsParent === "undefined") {
        return true;
      }
      
      // Normalize event for IE;
      var evt = e || window.event;
      
      // Fire hide/show against parent element;
      fnHideShow.call(this.hsParent);
      
      // Prevent default action of link;
      if (evt && evt.preventDefault) {
        evt.preventDefault();
      }
      evt.returnValue = false; 
    };
    
    // Iterate through parent sections;
    aParents.forEach(function (oElem) { 
      // Collect all target elements;
      var aTargets = myFedLoan.getElementsByClassName("hsTarget", oElem), 
      // Collect all hide/show elements;
      aResults = myFedLoan.getElementsByClassName("hsResults", oElem);
      
      // If both targets and results are found...;
      if (aResults.length > 0 && aTargets.length > 0) {
        // If this is IE, set zoom style to force hasLayout;
        if (document.all && !window.opera) {
          oElem.style.zoom = "1";
        }
        // Iterate through target elements;
        for (i = 0, iLength = aTargets.length; i < iLength; i += 1) {
          // Bind method to cancel default action;
          aTargets[i].onclick = fnCancelDefault;
          // Save reference to parent element;
          aTargets[i].hsParent = oElem;
          // Change Class Name;
          aTargets[i].className = aTargets[i].className.replace(reEnabled, "hsTargetEnabled");
        }
        
        // Save reference to all results in section;
        oElem.aResults = aResults;
        // Save reference to all targets in section;
        oElem.aTargets = aTargets;
        // Initialize section;
        fnHideShow.call(oElem);
      }
    });
  }, 
  
  // Method to initialize hide/show tab behavior;
  fnSetFormTabs = function (oFormSet) {
    // Test that jQuery has been instantiated;
    if (typeof jQuery === "undefined") {
      return false;
    }
    
    // Instantiate array to hold header values;
    var aHeaders = [], 
    // Instantiate jQuery object to hold formSet element;
    oSet = $(oFormSet), 
    
    // Method to hide/show formDetail tabs;
    fnShowHideTab = function (e) {
      // Get index of selected value;
      var iSelected = e && e.target && typeof e.target.innerHTML === "string" ? 
        jQuery.inArray(e.target.innerHTML, aHeaders) : 0;
      
      // Cancel method if index is less that 0;
      if (iSelected < 0 || !e.target || e.target.nodeName.toLowerCase() !== "li") {
        return false;
      }
      
      // Mark target tab as enabled;
      $(this).find("li").removeClass("tabSelected").get(iSelected).className = "tabSelected";
      // Show selected content;
      $(oSet.find(".formDetail").addClass("hide").get(iSelected)).removeClass("hide");
      
      // Prevent default action;
      if (e && e.preventDefault) {
        e.preventDefault();
      }
      return false;
    };
    
    // Process applicable formSet element;
    oSet.find(".formDetail").each(function () {
      // Function to extract header text;
      
      // Make "this" into a jQuery object;
      var oThis = $(this);
      
      // Add 1st header element text to header array;
      aHeaders.push($(oThis.find(":header").get(0)).addClass("hide").text());
      
      // If nothing is extracted, make a generic header text;
      if (aHeaders[aHeaders.length - 1] === "") {
        aHeaders[aHeaders.length - 1]  = "Section " + aHeaders.length;
      }
    // Hide all but first content detail element;
    }).addClass("tabEnabled").not(":first").addClass("hide").end().end()
    // Insert tab navigation menu;
    .before(
      $("<ul>").click(fnShowHideTab).addClass("tabMenu").append(function () {
        var sReturn = "";
      
        // Iteration to create string of LI elements;
        aHeaders.forEach(function (sText, i) {
          sReturn += (i === 0 ? "<li class=\"tabSelected\">" : "<li>") + sText + "<\/li>";
        });
      
        return sReturn;
      })
    );
  }, 
  
  // Method to create dropdown list;
  fnCreateDropdown = function () {
    $("#topForms").each(function () {
      var oThis = $(this).clone().find("a").attr("tabindex", -1).end();
      
      $(this).replaceWith( 
        $(document.createElement("div")).attr({
          className : "quickLink"
        }).append($(document.createElement("a")).attr({
            className : "quickLinkButton",
            href : "#"
          }).append($(document.createElement("img")).attr({
              alt : "Select and Go To...",
              src : "/images/quickLink/formBox.gif"
            })
          )
        ).append($(document.createElement("div")).attr({
            className : "quickLinkWrapper hide"
          }).append($(oThis).removeAttr("id"))        
        )
      );
      
      $(".quickLinkButton").toggle(fnToggle, fnToggle).data("oTarget", $(".quickLinkWrapper"));
      
      $("body").focusin(function () {        
        if ($(":focus").parents(".quickLink").length < 1) {
          $(".quickLinkWrapper").addClass("hide").find("a").attr("tabindex", -1).end();
          $(".quickLinkButton").removeClass("activeLink");
        }
      });
      
    });
    
    
  }, 
  
  // Method to create header dropdown menu;
  fnCreateHeaderDropdown = function () {
    var aListElements = myFedLoan.getElementsByClassName("headerDropdown"), 
    oTarget = document.getElementById("headerLinks"),
    
    // Reg Exp to remove hide class;
    reHide = /\s*hide\b/g, 
    
    oNewElement = fnCreate({
      elem : "li",
      attributes : {
        id : "dropdownMenuContainer"
      },
      children : [
        fnCreate({
          elem : "a",
          attributes : {
            href : "#",
            innerHTML : "Sign In or Create Account"
          }
        }),
        fnCreate({
          elem : "ul",
          attributes : {
            id : "dropdownMenu",
            className : "hide"
          }
        })
      ]
    });
    oTarget.appendChild(oNewElement);
    
    oDest = document.getElementById("dropdownMenu");
    aListElements.forEach(function (oElem) {
      oDest.appendChild(oElem);
    });
    
    oFocusElement = oTarget.lastChild.childNodes[0];
    
    $("#dropdownMenuContainer a").focus(function () {
      $("#dropdownMenu").removeClass("hide");
    }).blur(function () {
      $("#dropdownMenu").addClass("hide");
    }).click(function (e) {
       e.preventDefault();
      $("#dropdownMenu").removeClass("hide");
    });
  }, 
  
  // Method to read query string;
  fnQueryString = function (sQuery) {
    var aVars = [], i, aHash, 
    aHashes = sQuery ? 
      sQuery.slice(sQuery.indexOf("?") + 1).split("&") : 
      window.location.href.slice(window.location.href.indexOf("?") + 1).split("&");
    
    for(i = 0; i < aHashes.length; i++) {
      aHash = aHashes[i].split("=");
      aVars.push(aHash[0]);
      aVars[aHash[0]] = aHash[1];
    }
    
    if (sQuery) {
      return sQuery.slice(sQuery.indexOf("?") + 1).split("&");
    } else {
      return aVars;
    }
    
  },
  
  // Method to call specific query string variable;
  fnQueryStringVar = function (v) {
    return fnQueryString()[v];
  }

  return {
    
    cookies: (function () {
      return {
        createCookie: function (sName, sValue, oParams) {
          
          var dDate, iFutureDays, 
          sCookieString = "",  
          sExpires = "", 
          sPath = oParams && oParams.hasOwnProperty("sPath") ? 
            "; path=" + oParams.sPath : "; path=/", 
          sDomain = oParams && oParams.hasOwnProperty("sDomain") ?
            "; domain=" + oParams.sDomain : "";
      
          if (oParams && oParams.hasOwnProperty("iDays")) {
            dDate = new Date();
            iFutureDays = oParams.iDays * 24 * 60 * 60 * 1000;
            dDate.setTime(dDate.getTime() + iFutureDays);
            sExpires = "; expires=" + dDate.toGMTString();
          }

          sCookieString += sName + "=" + encodeURIComponent(sValue);
          sCookieString += sExpires + sPath + sDomain;
          document.cookie = sCookieString;
          
        }, 

        eraseCookie: function (sName, sType) {

          var i, iLength, aHashArray, // Instantiate variables;
          sThisType = sType ? sType : "single", // Set type of cookie to erase;
          
          /* 
            Initialize Regular Expression looking for given value at 
            the start of an entry;
          */
          reValue = new RegExp("^" + sName), 
          
          // Split string into array;
          aCookieArray = document.cookie.split(";"); 
  
          if (aCookieArray.length > 0) { // Loop through Cookie Array;
            for (i = 0, iLength = aCookieArray.length; i < iLength; i += 1) {
              // Split value into name|value pairs;
              aHashArray = aCookieArray[i].split("="); 
  
              /* 
                Reset the value to null if either the type is 'single' 
                (one cookie) and the cookie name matches the string given 
                (index) requested, or the type is 'class' (multiple cookies) 
                and the cookie's name starts with the string given (index)
              */
  
              aHashArray[0] = aHashArray[0].trim();
              if ((aHashArray[0] === sName && sThisType === "single") || 
                  (aHashArray[0].match(reValue) && sThisType === "class")) {
                PHEAA.util.cookies.createCookie(aHashArray[0], "", {iDays: -1});
              }
            }
          }
        }, 
        
        readCookie: function (sName) {

          var i, iLength, sCookie, 
          sValue = false, 
          sNameEQ = sName.trim() + "=", // Append "=" to cookie name;
          
          // Create array of cookie name/values;
          aCookieArray = document.cookie.split(';'); 
      
          // Iterate through array;
          for (i = 0, iLength = aCookieArray.length; i < iLength; i += 1) { 
            sCookie = aCookieArray[i].trim(); // Save individual entry;
            
            // Compare value to desired cookie;
            if (sCookie.indexOf(sNameEQ) === 0) { 
              // Extract cookie if match;
              sValue =  decodeURIComponent(sCookie.substring(sNameEQ.length, sCookie.length)); 
            }
          }
       
          if (sValue && sValue.length > 0) {
            return sValue; // Return cookie value;      
          } else {
            return null; // Cookie not found, return no value;
          }
          
        }
      };
    }()),
    
    getElementsByClassName: function (sClassName, vElm, sTag) {

      var i, iLength, n, nLength, cElements, reNodeName, 
      sNamespace, sNameResolver, aElements, oNode, bMatch, 
      sClassesToCheck = "", 
      oElm = vElm && vElm.constructor === String ? // Normalize oElm;
        document.getElementById(vElm) || document : 
        vElm || document, 
      aClasses = sClassName.split(" "), // Create array of class names;
      aClassesToCheck = [], // Array for document.evaluate method;
      aReturnElements = []; // Returned array of elements;

      // If browser has a native document.getElementsByClassName method...;
      if (document.getElementsByClassName) {
        // Get collection of elements;
        cElements = oElm.getElementsByClassName(sClassName);
        // Build RegExp to filter by node name;
        reNodeName = sTag ? new RegExp("\\b" + sTag + "\\b", "i") : null;
        
        // Iterate through returned elements;
        for (i = 0, iLength = cElements.length; i < iLength; i += 1) {
          if (!reNodeName || reNodeName.test(cElements[i].nodeName)) {
            aReturnElements.push(cElements[i]);
          }
        }
      } else if (document.evaluate) {
        sTag = sTag || "*";
        sNamespace = "http://www.w3.org/1999/xhtml";
        sNameResolver = document.documentElement.namespaceURI === sNamespace ? 
          sNamespace : null;
      
        for (i = 0, iLength = aClasses.length; i < iLength; i += 1) {
          sClassesToCheck += "[contains(concat(' ', @class, ' '), ' " +
            aClasses[i] + " ')]";
        }
      
        try  {
          aElements = document.evaluate(".//" + sTag + sClassesToCheck, oElm, sNameResolver, 0, null);
        }
        catch (e) {
          aElements = document.evaluate(".//" + sTag + sClassesToCheck, oElm, null, 0, null);
        }
      
        while ((oNode = aElements.iterateNext()) !== null) {
          aReturnElements.push(oNode);
        }
      } else {
        sTag = sTag || "*";
      
        cElements = sTag === "*" && oElm.all ? 
          oElm.all : oElm.getElementsByTagName(sTag);
      
        aClasses.forEach(function (oElement) { 
          aClassesToCheck.push(new RegExp("(^|\\s)" + oElement + "(\\s|$)"));
        });
        
        for (i = 0, iLength = cElements.length; i < iLength; i += 1) {
          bMatch = false;
  
          for (n = 0, nLength = aClassesToCheck.length; n < nLength; n += 1) {
            bMatch = aClassesToCheck[n].test(cElements[i].className);
            if (!bMatch) {
              break;
            }
          }
  
          if (bMatch) {
            aReturnElements.push(cElements[i]);
          }
        }
      }
      
      return aReturnElements;

    }, 
    
    init: function () {
      // Instantiate variables;
      var cFormLinks, oFormsParent, oFooterChild,   
      sStartLocation = window.location.pathname + window.location.search + window.location.hash, 
      aFormSets = myFedLoan.getElementsByClassName("formSet"), 
      oSearchForm = document.getElementById("searchForm");
      
      
      // Report load of page to Urchin;
      if (typeof PHEAA.Urchin !== "undefined") {
        PHEAA.Urchin.callUrchin(sStartLocation, "Page_Load");
      }
   
      // Initialize search form;
      if (document.getElementById("sp-q")) {
        fnSetSearchBox();
      }
    
      // Test Your Knowledge Script;
      $(".detailsBox,.answerBox").each(function () {
        var sCaption = "View " + this.className.replace(/(details|answer)Box/, function (a, b) {
          return b.charAt(0).toUpperCase() + b.slice(1);
        });
        
        $("<p class=\"detailLink\"><a href=\"#\">" + sCaption + "<\/a><\/p>").find("a").toggle(fnShow, fnHide).data("oTarget", this).click(fnChangeViewTitle).end().insertBefore(this);
        
      }).addClass("hide");

      // Set up external links to open in new windows;
      fnTargetBlank();
      
      // Activate dropdown;
      fnCreateDropdown();
      
      // Activate general hide/show behavior;
      fnSetHideShow();
      
      // Create header dropdown menu for login;
      fnCreateHeaderDropdown();
    
    
      // Tab Table Script
      if (aFormSets.length > 0) {
        aFormSets.forEach(fnSetFormTabs);
      }
    
    }
  };
}());

document.open();
document.write('<script type="text/javascript" src="/scripts/jquery-1.4.2.min.js"><\/script>');
document.close();

if (window.addEventListener) { // w3c method;
  window.addEventListener("load", myFedLoan.init, false);
} else if (window.attachEvent) { // IE method;
  window.attachEvent("onload", myFedLoan.init);
}

