/****
 *  Common
 *      Contains JavaScript functions common to many pages
 */
if (typeof LADDERS == 'undefined') {
    LADDERS = {};
}

if (typeof console == 'undefined') {
    console = {
        log: function(){},
        debug: function(){},
        info: function(){},
        warn: function(){},
        error: function(){},
        assert: function(){},
        dir: function(){},
        dirxml: function(){},
        trace: function(){},
        group: function(){},
        groupCollapsed: function(){},
        groupEnd: function(){},
        time: function(){},
        timeEnd: function(){},
        profile: function(){},
        profileEnd: function(){},
        count: function(){}
    };
}

/****
 * $() - Cheap and easy way to getElementById
 * @param {String} anId - id of element to be referenced
 */
function $(anId){
    return document.getElementById(anId);
}

/****
 * equalColumns - Sets n elements to have equal CSS style heights
 * @param {Array} columnArray 
 */
function equalColumns(columnArray) {
    var maxHeight = 0;
    var columnRegionArray = new Array();
    //1st pass -- find the tallest column
    for (var i = 0; i < columnArray.length; i++) {
        columnArray[i].style.minHeight = '';
        columnRegionArray[i] = YAHOO.util.Dom.getRegion(columnArray[i]);
        if (columnRegionArray[i].height > maxHeight) {
            maxHeight = columnRegionArray[i].height;
        }
    }
    //2nd pass -- set everything to that height, minus padding
    for (var i = 0; i < columnArray.length; i++) {
        var col = columnArray[i];
        if (columnRegionArray[i].height != maxHeight) {
            var topPadding = YAHOO.util.Dom.getStyle(col, 'paddingTop');
            var btmPadding = YAHOO.util.Dom.getStyle(col, 'paddingBottom');
            topPadding = topPadding ? Number(topPadding.replace(/px/, '')) : 0;
            btmPadding = btmPadding ? Number(btmPadding.replace(/px/, '')) : 0; 
            YAHOO.util.Dom.setStyle(col, 'minHeight', (maxHeight - topPadding - btmPadding) + "px");
        }
    }
}

/****
 * Returns x coordinate of a mouse event
 * @param {Event} e Mouse event
 */  
function retX(e){
    if(!e) var e = window.event;
    return YAHOO.util.Dom.getX(YAHOO.util.Event.getTarget(e));
}


/****
 * Returns y coordinate of a mouse event
 * @param {Event} e Mouse event
 */ 
function retY(e){
    if(!e) var e = window.event;
    return YAHOO.util.Dom.getY(YAHOO.util.Event.getTarget(e));
}

/****
 * Removes leading whitespaces
 */
function lTrim( value ) {
    
    var re = /\s*((\S+\s*)*)/;
    return value.replace(re, "$1");
    
}

/****
 * Removes ending whitespaces
 */
function rTrim(value){
    
    var re = /((\s*\S+)*)\s*/;
    return value.replace(re, "$1");
    
}

/****
 * Removes leading and ending whitespaces
 */
function trim(value) {
    return lTrim(rTrim(value));
}

function stripTags(str) {
  return str.replace(/<\/?[^>]+>/gi, '');
}

function ajaxFailure(/*Object*/ response) {
    if (response.status > 0) {
        alert('There was an error performing the specified action:\n\n' + response.statusText + '(' + response.status + ')');
    }
}

function escapeHTML(str) {
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}

function unescapeHTML(str) {
    var div = document.createElement('div');
    div.innerHTML = stripTags(str);
    return div.childNodes[0] ? (div.childNodes.length > 1 ? $A(div.childNodes).inject('',function(memo,node){ return memo+node.nodeValue }) : div.childNodes[0].nodeValue) : '';
}

function formElementPopulated(el) {
    if (!el) {
        // no element found, return true, just to be safe    
        return true;
    }
    else if (el.type === "text" || el.type === "textarea" || el.type === "password") {
        var defaultText = el.getAttribute("defaultText");
        return el.value !== "" && (!defaultText || defaultText === "" || el.value !== defaultText);
    }
    else if (el.type === "select-one") {
        return (el.options.selectedIndex > 0);
    }
    else {
        return true;
    }
}

function isEmpty(o) {
    var i, v;
    if (typeof o === 'object') {
        for (i in o) {
            v = o[i];
            if (v !== undefined && typeof v !== 'function') {
                return false;
            }
        }
    }
    return true;
}

/**
 * Opens the RL Terms & Conditions in a popup window, or focus on the window if already open
 */
var viewTermsWindow = null;
function viewTerms() {
    //If pop-up was never created or closed, created new one, otherwise just set focus to the already created pop-up
    if (viewTermsWindow == null || viewTermsWindow.closed) {
        viewTermsWindow = window.open('/register/viewTerms', 'RLTerms', 'height=650,width=550,resizable=false,menubar=no,location=no,toolbar=no,statusbar=false,scrollbars=yes');
    }
    viewTermsWindow.focus();
}

/**
 * the following 3 functions, and addDefaultTextListeners() in yui_extensions, allow any text input element to be decorated
 * width a defaultText attribute, and, optionally, a defaultStyle attribute.  This value will show in the element until 
 * a user adds their own.
 */

function clearDefaultText(event, input) {
    if (input.value == input.getAttribute('defaultText')) {
        input.style.cssText = '';
        input.value = '';
    }
}

function restoreDefaultText(event, input) {
    if (input.getAttribute('defaultText') != '' && (input.value == '' || input.value == input.getAttribute('defaultText'))) {
        var defaultStyle = input.getAttribute('defaultStyle');
        input.style.cssText = defaultStyle && defaultStyle != '' ? defaultStyle : 'color: #AAAAAA;';
        input.value = input.getAttribute('defaultText');
    }
}

function defaultTextFormEventMassAction(event, args) {
    var theForm = args[0];
    var defaultTextAction = args[1];
    for (var i = 0; i < theForm.elements.length; i++) {
        if (theForm.elements[i].getAttribute('defaultText') != null && theForm.elements[i].getAttribute('defaultText') != '') {
            defaultTextAction(null, theForm.elements[i]);
        }
    }
}

function modifyFields(root, attributeName, attributeValue) {
    var fieldNames = ['INPUT', 'SELECT', 'TEXTAREA'];
    for (var i = 0; i < fieldNames.length; i++) {
        var fields = root.getElementsByTagName(fieldNames[i]);
        for (var j = 0; j < fields.length; j++) {
            fields[j][attributeName] = attributeValue;
        }
    }
}

function arrayIndexOf(anArray, element) {
    for (var i = 0, ii = anArray.length; i < ii; i++) {
       if (element == anArray[i]) {
            return i;
        }
    }
    return -1;
}

function objectFind(object, propertyKey, propertyValue) {
    for (var objectKey in object) {
        if (object.hasOwnProperty(objectKey) && object[objectKey][propertyKey] == propertyValue) {
            return object[objectKey];
        }
    }
    return null;
}

//since IE doesn't recognize NodeList as a valid object
function isNodeList(el) {
    if (typeof NodeList !== 'undefined') {
        return el instanceof NodeList;
    }
    else {
        return el.length >= 0 && !el.nodeName;
    }
}

function printPage() {
    var hashedURL = window.location.toString().split("#");
    var printURL = hashedURL[0];
    printURL += printURL.indexOf('?') == -1 ? '?' : '&';
    printURL += 'print=true';
    if (hashedURL[1]) {
        printURL = printURL + '#' + hashedURL[1];
    }
    var printWindow = window.open(printURL, 'printWindow', 'width=910,height=700,location=no,status=no,scrollbars=yes');
}

function runScriptTags(/*Array*/ scriptTags) {
    for (var i = 0, ii = scriptTags.length; i < ii; i++) {
        if (scriptTags[i].innerHTML) {
            if (window.execScript) {
                window.execScript(scriptTags[i].innerHTML);
            }
            else {
                window.eval(scriptTags[i].innerHTML);
            }
        }
    }
}

function disableLink(el) {
    if (el && el.nodeName === 'A' && !el.backup) {
        var disabledLink = document.createElement('A');
        if (el.id) {
            disabledLink.id = el.id;
        }
        disabledLink.innerHTML = el.innerHTML;
        if (disabledLink.className.indexOf('disabled') == -1) {
        	disabledLink.title = el.title;
            disabledLink.className = el.className + ' disabled';
        }
        disabledLink.href = '#';
        disabledLink.onclick = function() {
            return false;
        };
        disabledLink.backup = el;
        el.parentNode.replaceChild(disabledLink, el);
    }
}

function enableLink(el) {
    if (el && el.nodeName === 'A' && el.backup) {
        el.parentNode.replaceChild(el.backup, el);
    }
}

//given a widget's set of <link> tags and inline style block being returned from an AJAX call, promote them to <head> so they don't die with further ajax calls
function promoteAJAXStyles(styleTags, styleBlock) {
    var styleTagHrefPattern = /href=['"]([\S]*)['"]/g;
    var styleTagHrefMatch;
    if (document.createStyleSheet) { //IE
        while (styleTagHrefMatch = styleTagHrefPattern.exec(styleTags)) {
            document.createStyleSheet(styleTagHrefMatch[1], document.styleSheets.length - 1);
        }
        //find the bottom-most non-volatile stylesheet
        for (var i = document.styleSheets.length - 1; i >= 0; i--) {
            var styleSheet = document.styleSheets[i]; 
            if (styleSheet.owningElement.nodeName == 'STYLE' && styleSheet.owningElement.parentNode.nodeName == 'HEAD') {
                styleSheet.cssText += styleBlock;
                break;
            }
        }
    }
    else { //everyone else
        while (styleTagHrefMatch = styleTagHrefPattern.exec(styleTags)) {
            var styles = "@import url('" + styleTagHrefMatch[1] + "');";
            var newSS = document.createElement('link');
            newSS.rel = 'stylesheet';
            newSS.href = 'data:text/css, ' + escape(styles);
            document.getElementsByTagName("head")[0].insertBefore(newSS, document.getElementsByTagName('STYLE')[0]);
        }
        try { //firefox supports this, & it's faster
            document.getElementsByTagName('STYLE')[0].innerHTML += styleBlock;
        }
        catch (e) { //but Webkit-based browsers think those tags are unmodifiable, and need to have rules inserted
            var styleRules = styleBlock.split('}');
            for (var i = 0, ii = styleRules.length; i < ii; i++) {
                if (trim(styleRules[i]) != '') {
                    document.styleSheets[document.styleSheets.length - 1].insertRule(styleRules[i] + '}');
                }
            }
        }
    }
}

/**
 * JSONFormPopulator: Have some JSON?  Need to populate a form?  Use this!
 * Accepts "deep" JSON objects that replicates Spring FormBackingObject hierarchy,
 * including child objects
 * 
 * @constructor
 * @param form
 * @return the populator
 * @type JSONFormPopulator
 */
function JSONFormPopulator(form) {
    this.form = form;
    return this;
};
JSONFormPopulator.prototype.form = null;
/**
 * @member JSONFormPopulator
 * @param JSON {Object}
 * @param updateOnly {Boolean} (optional) Only replace those values present in the JSON. Default: false 
 * @param nestedPath {String} (optional) Point in the tree from which to begin population.
 */
JSONFormPopulator.prototype.populate = function(/*Object*/ JSON, /*Boolean*/ updateOnly, /*String*/ nestedPath) {
    if (this.form) {
        //console.dir(JSON);
        // {'some':{'key': ['array', 'of', 'values']}}
        if (updateOnly === true) {
            //only update those values present in the JSON
            //console.log("nestedPath: " + nestedPath);
            this.jsonDescend(nestedPath, JSON);
        }
        else {
            //replace values of all present form fields, blanking out those missing from the JSON object
            if (nestedPath) {
                var nestedJSON = {};
                nestedJSON[nestedPath] = JSON;
                JSON = nestedJSON;
            }
            for (var i = 0; i < this.form.elements.length; i++) {
                var formElement = this.form.elements[i];
                var evaluatedJSONPath = [];
                try {
                    evaluatedJSONPath = eval('JSON.' + formElement.name);
                    if (evaluatedJSONPath === undefined || evaluatedJSONPath === null) {
                        evaluatedJSONPath = [];
                    }
                }
                catch(e) {
                    //missing; that's ok.
                }
                this.populateElement(formElement, evaluatedJSONPath); 
            }
        }
    }
    return this.form;
};

JSONFormPopulator.prototype.populateElement = function(formElement, formJSONValues) {
    if (!formElement || formJSONValues === null) {
        return;
    }
    else if (isNodeList(formElement)) { //NodeList -- bunch of checkboxes, etc
        //console.group("NODE LIST");
        for (var i = 0, ii = formElement.length; i < ii; i++) {
            this.populateElement(formElement[i], formJSONValues);
        }
        //console.groupEnd();
    }
    else if (!formElement.name || formElement.name.indexOf('_') == 0) {
        //obviously ignore form elements that don't exist, but ALSO Spring fields
        return;
    }
    else {
        if (!(formJSONValues instanceof Array)) {   //YUI's form-to-JSON (from Dialog) doesn't create arrays for text, just single-value objects
            formJSONValues = [formJSONValues];      //So we fake it by stuffing a lone value into an array
        }
        for (var i = 0; i < formJSONValues.length; i++) { 
            if (formJSONValues[i] instanceof Object && formJSONValues[i].id !== null) {
                //stand-in for Spring binding/PropertyEditor -- if the field is supposed to map to an object, assume we use id
                var id = formJSONValues[i].id;
                formJSONValues[i] = id;
            }
            //since we're comparing to strings... convert to strings
            formJSONValues[i] = formJSONValues[i] + "";
        }
        //console.info(formJSONValues);
        if (formElement.type == 'select-one') {
            for (var j = 0; j < formElement.options.length; j++) {
                if (formElement.options[j].value == formJSONValues[0]) {
                    formElement.selectedIndex = j;
                    break;
                }
            } 
        }
        else if ((formElement.type == 'text' || formElement.type == 'textarea' || formElement.type == 'hidden')) {
            formElement.value = formJSONValues[0] || '';
        }
        else if (formElement.type == 'radio') {
            formElement.checked = (formElement.value == formJSONValues[0]);
        }
        else if (formElement.type == 'checkbox') {
            formElement.checked = (arrayIndexOf(formJSONValues, formElement.value) != -1);
        }
    }
};

JSONFormPopulator.prototype.jsonDescend = function(collapsedObjectName, jsonObject) {
    for (var childName in jsonObject) {
        var childObject = jsonObject[childName];
        var collapsedChildName;
        if (!collapsedObjectName || collapsedObjectName === '') {
            collapsedChildName = childName;
        }
        else {
            collapsedChildName = collapsedObjectName + '.' + childName;
        }
        //console.group(collapsedChildName);
        if (this.form.elements[collapsedChildName]) { //we have a match for the collapsed name
            //console.info('match for ' + collapsedChildName);
            var nameMatchedElements = this.form.elements[collapsedChildName];
            this.populateElement(nameMatchedElements, childObject);
        }
        else if (childObject instanceof Array) {
            //console.warn("ARRAY");
            for (var i = 0; i < childObject.length; i++) {
                this.jsonDescend(collapsedChildName + '[' + i + ']', childObject[i]);
            }
        }
        else if (childObject instanceof Object) {
            this.jsonDescend(collapsedChildName, childObject);
        }
        //console.groupEnd();
    }
};

/****
 * selectRecruiterFunction - Called when recruiter function drop down is changed
 * On the following pages:
 *  - register/createRegistrationNoemail.jsp
 *  - myaccount/addRecruiterAccount.jsp
 *  - myaccount/editRecruiterAccount.jsp
 *  - profilewizard/step2.jsp
 *  - register/freemium/account.jsp
 * 
 */
function selectRecruiterFunction() {
    $('recruiterLevel-hr').style.display = 'none';
    $('recruiterLevel-agency').style.display = 'none';
    $('recruiterLevel-raa').style.display = 'none';
    $('recruiterLevel-others').style.display = 'none';
    $('recruiterLevel-hr-select').disabled = true;
    $('recruiterLevel-agency-select').disabled = true;
    $('recruiterLevel-raa-select').disabled = true;
    $('recruiterLevel-others-select').disabled = true;
    
    if ($('recruiterFunction').selectedIndex < 2) {
      $('recruiterLevel-hr').style.display = '';
      $('recruiterLevel-hr-select').disabled = false;
    }
    else if ($('recruiterFunction').selectedIndex == 2) {
      $('recruiterLevel-agency').style.display = '';
      $('recruiterLevel-agency-select').disabled = false;
    }
    else if ($('recruiterFunction').selectedIndex == 3) {
      $('recruiterLevel-raa').style.display = '';
      $('recruiterLevel-raa-select').disabled = false;
    }
    else if ($('recruiterFunction').selectedIndex > 3) {
      $('recruiterLevel-others').style.display = '';
      $('recruiterLevel-others-select').disabled=false;
    }
}

LADDERS.User = LADDERS.User || {};
LADDERS.User.personalizeConnections = null;
