/*jslint white: true, onevar: true, browser: true, undef: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, indent: 2 */

/*global window, _ugifpath, _udn, _resetUDN */

/*
methods in this file:
 - init
 - callUrchin
 - getLocation
*/

var PHEAA, urchinTracker, $A; 

if (typeof PHEAA === "undefined") {
  PHEAA = {};	
}

if (!String.prototype.stripTags) {
  String.prototype.stripTags = function () { //strip out all HTML tags;

    /*
      u003C = < in Unicode, u003E = > in Unicode;
      Non-capturing, non-greedy;
    */
    return this.replace(/\u003C(?:\/?[^\u003E]+?)\u003E/g, ""); 

  }; 
}

if (typeof $A === "undefined") {
  $A = function (vCollection) {
    var i, iLength, // Instantiate loop variables;
    aResults = []; // Create new, empty array;
  
    // If nothing is passed in...;
    if (!vCollection) { 
      // Return empty array;
      return aResults; 
  
    // If a string is passed in...;
    } else if (typeof vCollection === "string") { 
      // Split string into an array of charcters and return;
      return vCollection.split(""); 
  
    // If an array or object is passed in...;
    } else if (vCollection.length) {
      // Iterate through array/object;
      for (i = 0, iLength = vCollection.length; i < iLength; i += 1) {
        // Push results into new array;
        aResults.push(vCollection[i]);
      }
    }
  
    // Return new array;
    return aResults;
  };
}

PHEAA.Urchin = (function () {
  // Declare private variables;
  var i, iLength, sThisLocation, 
  bUDNCheck = false, 
  aScriptArray = $A(document.getElementsByTagName("script")),  // Find any existing script tags on page;
  
  // Declare private methods;
  fnCallUrchinMethod = function (e) {
    e = e || window.event;

    var i, iLength, 
    evt = e || window.event, 
    evtTarget = evt.target || evt.srcElement, // Instantiate loop variables;
    sType = typeof evtTarget.sBind === "string" ? 
      evtTarget.sBind : "Unknown_Event";
    
    // Test to make sure aUrchinStrings array is present;
    if (typeof evtTarget.aUrchinStrings !== "undefined" && evtTarget.aUrchinStrings.constructor === Array) {
      // Iterate through aUrchinStrings values;
      for (i = 0, iLength = evtTarget.aUrchinStrings.length; i < iLength; i += 1) {
        if (evtTarget.aUrchinStrings[i].constructor === String) { // If entry is a string;
          PHEAA.Urchin.callUrchin(evtTarget.aUrchinStrings[i], sType); // Send string to Urchin;
        }
      }
    }
  }, 
  
  fnReturnBindMethod = function (oElem) { 
    /* 
      This method returns the default binding event of a given element;

      Hook in HTML: none;
      Variables: oElem HTML Element to bind against;
      Referenced in: PHEAA.Modal.initIntercede method;
      Activated when: when binding fnIntercede method to elements;
    */
      
    var aMethod = ["click", "change", "blur", false], 
    iSelectedMethod = 0;
    
    switch (oElem.nodeName.toLowerCase()) {

    case "select":
      iSelectedMethod = 1;
      break;
        
    case "input":
      if (oElem.type === "text" || oElem.type === "textarea") {
        iSelectedMethod = 2;
      } else if (oElem.type === "hidden") {
        iSelectedMethod = 3;
      }
      break;
       
    } // End switch; 
    
    return aMethod[iSelectedMethod];
  };
  
  for (i = 0, iLength = aScriptArray.length; i < iLength; i += 1) { // Iterate through script elements;
    if (aScriptArray[i].src && aScriptArray[i].src.indexOf("PHEAA.Urchin.js") !== -1) { // If script is the PHEAA.Urchin.js script...;
      // sThisLocation = aScriptArray[i].src.replace(/PHEAA\.Urchin\.js$/, ""); // Save path to urchin.js file;
      sThisLocation = aScriptArray[i].getAttribute("src").replace(/PHEAA\.Urchin\.js$/, ""); // Save path to urchin.js file;
      break;
    } else if (aScriptArray[i].src && aScriptArray[i].src.indexOf("PHEAA.js") !== -1) {
      // sThisLocation = aScriptArray[i].src.replace(/PHEAA\.js$/, "modules/Urchin/"); // Save path to urchin.js file;
      sThisLocation = aScriptArray[i].getAttribute("src").replace(/PHEAA\.js$/, "modules/Urchin/"); // Save path to urchin.js file;
      break;
    }
  }
  
  // Dynamically add call to load Urchin script;
  document.open();
  document.writeln("");
  document.writeln('<script type="text/javascript" src="' + sThisLocation + 'urchin.js"></script>');
  document.close();
  
  return {
    /*****************************************************************************************************************/
    /*****************************************************************************************************************/
    /**
      * @function PHEAA.Urchin.init
      * @param {HTMLElement/String} vElem Element of ID of Element to initialize (Optional)
      * @return {Array} aUrchinLinks Array of Initialized Urchin-tracked Links
      * @describe <p>Method to automatically configure links to record onclick actions to server logs via Google's Urchin</p>
      * @example
// Record the href of a link to the server logs:
&lt;a href="#" class="urchin"&gt;Link Text&lt;/a&gt;

// Record a custom message to the server logs:
&lt;a href="#" class="urchin[Custom_Message]"&gt;Link Text&lt;/a&gt;
    */
    //<source>
    init: function (vElem) {
      _ugifpath = PHEAA.Urchin.getLocation() + "__utm.gif";

      // Instantiate varaibles;
      var i, iLength,  
      aUrchinLinks = [], // Array to store references to formatted elements;
      // Regular Expression to test for Urchin in element class names;
      reUrchin = /\burchin(?:Load)?(?:\[([^\[\]]*?)\])?/,
      // Set parent element to initialize objects within;
      oElem = (function (vElm) {
        var oObj;
      
        // Test to see if element is an event object;
        if (typeof vElm === "undefined" || 
            typeof vElm.eventPhase !== "undefined" || 
            (vElm.constructor !== String && typeof vElm.nodeName === "undefined" )) {
          oObj = document.body;
        // Else normalize object to a dom object;
        } else {
          oObj = vElm.constructor === String ? 
            document.getElementById(vElm) : vElm;
        }
      
        return oObj;
      }(vElem)), 
        
      // Get all elements within parent element;
      aLinks = $A(oElem.getElementsByTagName("*"));
      
      // Iterate through collection of elements;
      for (i = 0, iLength = aLinks.length; i < iLength; i += 1) {
        if (aLinks[i].className && reUrchin.test(aLinks[i].className)) {
          if (typeof aLinks[i].aUrchinStrings === "undefined") {
            aLinks[i].aUrchinStrings = [];
          }
          
          // Continue loop if link has been initialized;
          if (aLinks[i].bUrchin) {
            continue;          
          }
          
          // Iterate through different class names;
          if (RegExp.$1.length > 0) { // If urchin class contains a string;
            // Push string value into aUrchinStrings array;
            aLinks[i].aUrchinStrings.push(RegExp.$1);
          } else if (typeof aLinks[i].value !== "undefined") {
            // Else push value (for form inputs) into aUrchinStrings array;
            aLinks[i].aUrchinStrings.push(aLinks[i].value); 
          } else if (typeof aLinks[i].href !== "undefined") {
            // Else push href into aUrchinStrings array;
            aLinks[i].aUrchinStrings.push(aLinks[i].href); 
          } else {
            // Else push innerHTML into aUrchinStrings array;
            aLinks[i].aUrchinStrings.push(aLinks[i].innerHTML.stripTags()); 
          }
	
          // If this is an "urchinText" element;
          if (aLinks[i].className.indexOf("urchinLoad") !== -1) {
            // Write text into Urchin immediately;
            PHEAA.Urchin.callUrchin(aLinks[i].aUrchinStrings[aLinks[i].aUrchinStrings.length - 1], "load");

          } else {
	
            aLinks[i].sBind = fnReturnBindMethod(aLinks[i]);
	
            if (aLinks[i].sBind) {
              // Attach onclick event;
              if (window.addEventListener) { // w3c method;
                aLinks[i].addEventListener(aLinks[i].sBind, fnCallUrchinMethod, false);
              } else if (window.attachEvent) { // IE method;
                aLinks[i].attachEvent("on" + aLinks[i].sBind, fnCallUrchinMethod);
              }
              // Save reference to the formatted element;
              aUrchinLinks.push(aLinks[i]);
            }
          }
                    
          // Mark that link has been processed;
          aLinks[i].bUrchin = true;
        }
      }
      
      // Return formatted elements array;
      return aUrchinLinks;
    }, 
    //</source>
    
    /*****************************************************************************************************************/
    /*****************************************************************************************************************/
    /**
      * @function PHEAA.Urchin.callUrchin
      * @param {String} sMessage Message to store in Urchin Logs
      * @param {String} sType (Optional) Type of message to report
      * @return {Boolean} urchinCall True/False value on whether Urchin call was made
      * @describe <p>Method to dynamically record an entry onto a server log using Google's Urchin.</p>
      * @example
callUrchin("Message to record on server", "debug");
    */
    //<source>
    callUrchin: function (sMessage, sType) {
      var reUDN, oTimeout, 
      sMessageType = typeof sType !== "undefined" ?
        sType : "Message", 
        
      fnDeferCall = function () {
        // Ensure timeout is cleared;
        clearTimeout(oTimeout);

        // Pass string into urchinTracker method;
        urchinTracker("/" + sMessageType + ":" + sMessage); 
      };
        
      // Check to see if a UDN confirmation check has been run...;
      if (!bUDNCheck) {
        reUDN = /\.(?:com|net|org|gov)/; // Instantiate Reg. Expression to test location.hostname;
        
        // If a _resetUDN global variable was set...
        if (typeof _resetUDN === "string") {
          // Set domain to new variable;
          _udn = _resetUDN;
	
        // Else if location is not a full host name; 
        } else if (typeof _udn !== "undefined" && 
                   !reUDN.test(window.location.hostname)) {
          _udn = "none";
        }
        
        // Mark UDN Check as true;
        bUDNCheck = true;
      }
        
      // Test for existance of urchinTracker method;
      if (typeof urchinTracker !== "undefined" && 
          urchinTracker.constructor === Function && 
          typeof sMessage === "string") {
        // Replace spaces in message with "_";
        sMessage = sMessage.replace(/\s/g, "_");
        // Insert urchin call into execution stack;
        oTimeout = setTimeout(fnDeferCall, 500); 
        return true; // Return method as successful;
      }
      return false; // Return method as unsucessful;
    }, 
    //</source>
    
    /*****************************************************************************************************************/
    /*****************************************************************************************************************/
    /**
      * @function PHEAA.Urchin.getLocation
      * @param {None}
      * @return {String} sThisLocation Global path to PHEAA.Urchin.js script;
      * @describe <p>Method to get private Global path to PHEAA.Urchin.js file location.</p>
      * @example
var sPath = PHEAA.Urchin.getLocation();
    */
    //<source>
    getLocation: function () {
      return sThisLocation;
    }
    //</source>
  };
}());

// Attach PHEAA.Urchin.init method to window's onload event;
if (window.addEventListener) { // w3c method;
  window.addEventListener("load", PHEAA.Urchin.init, false);
} else if (window.attachEvent) { // IE method;
  window.attachEvent("onload", PHEAA.Urchin.init);
}
