/*jslint white: true, devel: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, indent: 2 */

// Poll JavaScript Document For AES

/*global window, PHEAA */

var fnPoll = (function () {  
  if (!String.prototype.trim) {
    String.prototype.trim = function () {
  
      var re = /^\s+|\s+$/g;
      return this.replace(re, "");

    };
  }
    
  // Method to build poll onto a page
  var iPollCount = 1, 
  
  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")) {
              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;
        }
          
      }
    };
  }()),
      
  // Method to create new dom elements;
  fnCreate = function (oObj) { 
    // 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 insert elements into the DOM;
  fnInsertIntoDOM = function (oNewElem, oLandmark, sDirection) {
    // Insert in DOM;
    if (sDirection === "before") { // If inserting before landmark object;
      oLandmark.parentNode.insertBefore(oNewElem, oLandmark);    
    } else if (sDirection === "after") {
      if (oLandmark.parentNode.lastChild === oLandmark) { // If inserting after landmark object;
        oLandmark.parentNode.appendChild(oNewElem);
      } else { 
        oLandmark.parentNode.insertBefore(oNewElem, oLandmark.nextSibling);
      }
    } else if (sDirection === "replace") { // Replace landmark element;
      oLandmark.parentNode.replaceChild(oNewElem, oLandmark);
    } else { // If inserting into landmark object;
      oLandmark.appendChild(oNewElem);
    }	  
  }, 
  
  // Method to display poll thank you messages;
  fnThankYou = function (oObj) {
    /*
      Check to make sure browser has proper namespace and
      supports required w3c methods;
    */
    if (!document.getElementById || 
        !document.createElement || 
        !oObj || 
        typeof oObj !== "object" || 
        !oObj.hasOwnProperty("landmark") || 
        !oObj.hasOwnProperty("direction")) {
      return false;
    }

    // Initialize header and gratitude values;
    var sHeaderTag = oObj.hasOwnProperty("headerLevel") ? "h" + oObj.headerLevel : "h2", 
    sGratitude = oObj.hasOwnProperty("gratitude") ? oObj.gratitude : "Thank You for Voting!", 
    
    // Build thank you DOM element;
    oThankYou = fnCreate({
      elem : "div",
      attributes : {
        className : oObj.hasOwnProperty("className") ? oObj.className : ""
      },
      children : [
        fnCreate({
          elem : sHeaderTag,
          attributes : {
            innerHTML : sGratitude
          }
        })
      ]
    }), 
    // Find element to insert poll before, after, or into;
    oLandmark = typeof oObj.landmark === "string" ? document.getElementById(oObj.landmark) : oObj.landmark;
    
    // End method if no landmark is found;
    if (!oLandmark) {
      return false;
    }
    
    // Build optional poll explanation and insert before form element;
    if (oObj.hasOwnProperty("gratitudeExplanation") && oObj.gratitudeExplanation) {
      oThankYou.appendChild(fnCreate({
        elem : "p", 
        attributes : {
          innerHTML : oObj.gratitudeExplanation
        }
      }));
    }
    
    // Insert thank you element into DOM;
    fnInsertIntoDOM(oThankYou, oLandmark, oObj.direction);
  }, 
  
  // Method to construct a poll on a page;
  fnBuildPoll = function (oObj) {
    /*
      Check to make sure browser has proper namespace and
      supports required w3c methods;
    */
    if (!document.getElementById || 
        !document.createElement || 
        typeof PHEAA === "undefined" || 
        typeof PHEAA.Urchin === "undefined" || 
        !oObj || 
        typeof oObj !== "object" || 
        !oObj.hasOwnProperty("urchinName") || 
        !oObj.hasOwnProperty("question") || 
        !oObj.hasOwnProperty("answers") || 
        !oObj.hasOwnProperty("landmark") || 
        !oObj.hasOwnProperty("direction") || 
        !document.getElementById(oObj.landmark)) {
      return false;
    }
    
    // Instantiate Placeholder Variables;
    var oForm, oSubmit, 
    
    // Strings to use in DOM creation;
    iHeader = oObj.hasOwnProperty("headerLevel") ? 
      oObj.headerLevel : 2, 
    sHeaderTag = "h" + iHeader, 
    sGratitude = oObj.hasOwnProperty("gratitude") ? 
      oObj.gratitude : "Thank You for Voting!", 
    sThankYouMessage = oObj.hasOwnProperty("gratitudeExplanation") ? 
      oObj.gratitudeExplanation : null, 
    sClassName = oObj.hasOwnProperty("className") ? 
      oObj.className : "", 
          
    // Create DOM elements;
    oPollDiv = fnCreate({
      elem : "div",
      attributes : {
        id : "poll" + iPollCount,
        className : sClassName
      },
      children : [
        fnCreate({
          elem : sHeaderTag,
          attributes : {
            innerHTML : oObj.question
          }
        }),
        // Create form element;
        oForm = fnCreate({
          elem : "form",
          attributes : {
            name : oObj.urchinName,
            method : "POST",
            action : "#"
          },
          // Anonymous function to return an array of form elements;
          children : (function (oOptions) {
            // Instantiate temporary variables;
            var n, oThisSpan, 
            
            // Loop variable;
            i = 1, 
            
            // Return array element;
            aReturnElements = [], 
            
            // Seed elements to clone during loop;
            oSeedSpan = fnCreate({
              elem: "span"
            });
            
            // Iterate through options;
            for (n in oOptions) {
              // If option attribute was explicitly set...;
              if (oOptions.hasOwnProperty(n)) {
                // Clone span element;
                oThisSpan = oSeedSpan.cloneNode(true);
                
                oThisSpan.innerHTML = "<input name=\"rdPollQuestion" + iPollCount + "\" type=\"radio\" id=\"rdPollQuestion" + iPollCount + "_" + i + "\" value=\"" + n + "\" \/><label for=\"rdPollQuestion" + iPollCount + "_" + i + "\" title=\"" + oOptions[n].title + "\">" + oOptions[n].label + "<\/label>";
                 
                // Add span to return array;
                aReturnElements.push(oThisSpan);
                i += 1;
              }
            }
            
            // Create submit button and add to return array;
            aReturnElements.push(oSubmit = fnCreate({
              elem : "input", 
              attributes : {
                className : "submitDisabled", 
                disabled : true, 
                name : "pollSubmit" + iPollCount, 
                type : "submit", 
                value : "Vote Now!"
              }
            }));
             
            // Return array of elements;
            return aReturnElements;
          }(oObj.answers))
        })
      ]
    }), 
    // Find element to insert poll before, after, or into;
    oLandmark = document.getElementById(oObj.landmark),
    
    // Method to submit poll through Urchin;
    fnSubmitPoll = function (e) {
      var i,
      oTempInput,
      sReturnValue = null,
      // Normalize Event;
      evt = e || window.event, 
      
      // Create thank you object;
      oThankYou = {
        "landmark" : oPollDiv, 
        "direction" : "replace", 
        "gratitude" : sGratitude, 
        "gratitudeExplanation" : sThankYouMessage, 
        "headerLevel" : iHeader, 
        "className" : sClassName
      };

      // Stop propagation of event;
      if (evt.stopPropagation) { // Test for w3c;
        evt.stopPropagation();
      }
      evt.cancelBubble = true; // Set IE version;
      
      // Prevent default action of event;
      if (evt.preventDefault) { // Test for w3c;
        evt.preventDefault();
      }
      evt.returnValue = false; // Set IE version;
      
      // Write value into PHEAA.Urchin logs;
      for (i = oForm.elements.length - 1; i >= 0; i -= 1) {
        oTempInput = oForm.elements[i];
        if (oTempInput.type === "radio" && oTempInput.checked) {
          sReturnValue = oTempInput.value;
          break;
        }
      }
      
      if (sReturnValue) {
        PHEAA.Urchin.callUrchin(sReturnValue, oForm.name);
        // Write cookie to remember that user has voted;
        cookies.createCookie(oForm.name, sReturnValue, {
          "iDays" : 120
        });
      
        // Display Thank You Message;
        fnThankYou(oThankYou);
      }
    }, 
    
    fnActivateSubmit = function (e) {
      // Normalize event object and target;
      var evt = e || window.event,
      evtTarget = evt.target || evt.srcElement;
      
      // If target is a radio button...;
      if (evtTarget.nodeName.toLowerCase() === "input" && 
          evtTarget.type === "radio") {
        // Enable submit button;
        oSubmit.className = oSubmit.className.replace(/submitDisabled/, "");
        oSubmit.disabled = false;
        
        // Remove binding of method from form element;
        if (oForm.removeEventListener) { // w3c method;
          oForm.removeEventListener("click", fnActivateSubmit, false);
        } else if (oForm.detachEvent) { // IE method;
          oForm.detachEvent("onclick", fnActivateSubmit);
        }
      }
    };
    
    // Build optional poll explanation and insert before form element;
    if (oObj.hasOwnProperty("explanation")) {
      oPollDiv.insertBefore(fnCreate({
        elem : "p", 
        attributes : {
          innerHTML : oObj.explanation
        }
      }), oForm);
    }
    
    // Bind Event;
    if (oForm.addEventListener) { // w3c method
      oForm.addEventListener("submit", fnSubmitPoll, false);
      oForm.addEventListener("click", fnActivateSubmit, false);
    } else if (oForm.attachEvent) { // IE method
      oForm.attachEvent("onsubmit", fnSubmitPoll);
      oForm.attachEvent("onclick", fnActivateSubmit);
    }
    
    // Insert element into DOM;
    fnInsertIntoDOM(oPollDiv, oLandmark, oObj.direction);
        
    // Advance private poll counter;
    iPollCount += 1;
  };
  
  // Return initialization method;
  return function () {
    /*
      Below is a sample object to pass into the poll building method and thank you method;
      
      oPoll = {
        "urchinName" : "fruitPoll", // String, name of poll in urchin statistics (Required when building polls)
        "question" : "What fruit do you wish to eat?", // String (Required when building polls)
        "answers" : {  // Value passed : Label Displayed - Strings in Object (Required when building polls)
          "apple" : "Red Apples", 
          "orange" : "Florida Oranges", 
          "banana" : "Plantains", 
          "kiwi" : "Fuzzy Kiwi"
        }, 
        "landmark" : "twoColBox", // String, ID of element used as DOM landmark
        "direction" : "before", // String, "before", "after", "replace", or "into"
        "explanation" : "Please select the most appetizing fruit from below", // String (optional)
        "gratitude" : "Thank You for Voting!", // String (optional)
        "gratitudeExplanation" : "Thank you for participating in our poll. Sorry, but only one vote per user.", // String (optional)
        "headerLevel" : 2, // Integer (optional - defaults to "2" for an H2 element)
        "className" : "sampleClass" // String (optional)
      };
    */
    
    // Instantiate poll object;
    var oPoll = {
      "urchinName" : "mascotPoll", 
      "question" : "What should my name be?", 
      "answers" : {
        "Linc" : {
          "label" : "Linc", 
          "title" : "Linc&mdash;Connects you to the benefits of Account Access"
        }, 
        "Scout" : {
          "label" : "Scout", 
          "title" : "Scout&mdash;Guides you through online loan management"
        }, 
        "Coach" : {
          "label" : "Coach", 
          "title" : "Coach&mdash;Encourages you to succeed in online repayment"
        }, 
        "Mylo" : {
          "label" : "Mylo", 
          "title" : "Mylo&mdash;Provides options for repaying &#34;my lo&#34;ans"
        },
        "SAM" : {
          "label" : "SAM (Simple Account Management)", 
          "title" : "SAM&mdash;Helps you simplify your account management"
        }
      }, 
      "landmark" : "threeColBox",
      "direction" : "before",
      "headerLevel" : 2,
      "className" : "pollStyle", 
      "gratitude" : "I got your vote!", 
      "gratitudeExplanation" : "Thanks for your help in naming me. I will reveal my winning identity in a few weeks. Be sure to check back!"
    }, 
    // Instantiate alternate thank you object;
    oThankYou = {
      "landmark" : "threeColBox", 
      "direction" : "before", 
      "headerLevel" : 2, 
      "className" : "pollStyle", 
      "gratitude" : "I got your vote!", 
      "gratitudeExplanation" : "Thanks for your help in naming me. I will reveal my winning identity in a few weeks. Be sure to check back!"
    };
    
    if (!cookies.readCookie(oPoll.urchinName)) {
      // Build poll into page;
      fnBuildPoll(oPoll);
    } else {
      // Write thank you note;
      fnThankYou(oThankYou);
    }
  };
}());

// Bind fnPoll to window.onload event;
if (window.addEventListener) {
  window.addEventListener("load", fnPoll, false);	
} else if (window.attachEvent) {
  window.attachEvent("onload", fnPoll);
}
