/* Behold.  The CNU Namespace */
var CNU = {};

/* * * CNU config * * */
CNU.config = {};
CNU.config.cluster = '';
CNU.config.brand = '';
CNU.config.country = '';
CNU.config.language = '';

/* Assistant Debug Switch */
CNU.config.DEBUG_ASSISTANT = false;

/* General Console Debug Switch */
CNU.config.DEBUG = false;

/* ON/OFF switch for Form Submit Validation */
CNU.config.VALIDATE_FORMS = true;

/* ON/OFF switch for entire Validator Assistant */
CNU.config.VALIDATE = true;

/* regex's */
CNU.config.regex = {};
CNU.config.regex.email_address = /^[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,4}$/i;

/* Utility Functions */
CNU.util = {};
CNU.ev = {};
CNU.dom = {};

// check for visibility through DOM ancestors
CNU.dom.is_visible = function (element) {
  var el, ancestors;

  if (typeof element.ancestors === undefined) { 
    el = $(element);
  } else { 
    el = element;
  }

  // IE complains about ancestors without $ function
  try {
    ancestors = el.ancestors();
  } catch(err) {
    ancestors = $(el).ancestors();
  }

  for (var i = 0; i < ancestors.length; i++ ) {
    if ((! ancestors[i].visible()) || (ancestors[i].style.visibility == 'hidden')) { return false; }
  }
  return true;
};

CNU.dom.hideByClass = function (searchClass,node,tag) {
  var elements = CNU.dom.getElementsByClass(searchClass, node, tag);
  var elsLen = elements.length;
  for (var i = 0; i < elsLen; i++) {
    elements[i].style.display = 'none';
  }
};

/* Chains event functions to window.onload */
CNU.ev.addLoadEvent = function (func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      /* REFACTOR 4036: this if () is always true, due to typeof check above */
      if (oldonload) {
        oldonload();
      }
      func();
    };
  }
};
CNU.util.is_active = function () { document.getElementsByTagName('body')[0].addClassName('js'); };


/* addEvent attachment */
CNU.ev.addEvent = function ( obj, type, fn ) {
  if (obj.addEventListener) {
    obj.addEventListener( type, fn, false );
    CNU.ev.EventCache.add(obj, type, fn);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() { obj["e"+type+fn]( window.event ); };
    obj.attachEvent( "on"+type, obj[type+fn] );
    CNU.ev.EventCache.add(obj, type, fn);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
};

CNU.ev.EventCache = function () {
  var listEvents = [];
  return {
    listEvents : listEvents,
    add : function(node, sEventName, fHandler){
      listEvents.push(arguments);
    },
    flush : function(){
      var i, item;
      for(i = listEvents.length - 1; i >= 0; i = i - 1){
        item = listEvents[i];
        if(item[0].removeEventListener){
          item[0].removeEventListener(item[1], item[2], item[3]);
        }
        if(item[1].substring(0, 2) != "on"){
          item[1] = "on" + item[1];
        }
        if(item[0].detachEvent){
          item[0].detachEvent(item[1], item[2]);
        }
        item[0][item[1]] = null;
      }
    }
  };
}();
CNU.ev.addEvent(window,'unload',CNU.ev.EventCache.flush);

/* thank you, quirksmode */
CNU.ev.getTarget = function (e) { 
  var targ;
  if (!e) { e = window.event; }
  if (e.target) { targ = e.target; }
  else if (e.srcElement) { targ = e.srcElement; }
  if (targ.nodeType == 3) { targ = targ.parentNode; }
  return targ;
};

// returns first form element found of a specific class
// this is useful because it stays within the given form
// not the whole document.
CNU.dom.getChildElementByClass = function (class_name, form) {
  var el = form;
  var elements = $(form).immediateDescendants();
  for (var i = elements.length-1; i > 0; i--) {
    if ($(elements[i]).hasClassName(class_name)) {
      el = elements[i];
      i = 0;
    } else {
    }
  }
  return el;
};

// returns first form element found of a specific class
// this is useful because it stays within the given form
// not the whole document.
CNU.dom.getDescendantElementByClass = function (class_name, form) {
  var el = null;
  var desc = $(form).descendants();
  for (var i = desc.length-1; i > 0; i--) {
    if ($(desc[i]).hasClassName(class_name)) {
      el = desc[i];
      i = 0;
    }
  }
  return el;
};


/* grab Elements from the DOM by className */
CNU.dom.getElementsByClass = function (searchClass,node,tag) {
  var i = 0, j = 0, classElements = [];
  node = node || document;
  tag = tag || '*';
  var els = node.getElementsByTagName(tag);
  var elsLen = els.length;
  var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
      classElements[j] = els[i];
      j++;
    }
  }
  return classElements;
};

CNU.dom.insertAfter = function (parent, node, referenceNode) { parent.insertBefore(node, referenceNode.nextSibling); };

/* utilities for returning all form tags from the document */
CNU.dom.get_forms = function () { return document.getElementsByTagName('form'); };
CNU.dom.get_inputs = function (form) { return form.getElementsByTagName('input'); };
CNU.dom.get_selects = function (form) { return form.getElementsByTagName('select'); };
CNU.dom.get_textareas = function (form) { return form.getElementsByTagName('textarea'); };

/* Extend certain portions of the built-in dom */
CNU.dom.extend_string = function () {

  if (!String.prototype.contains) {
    String.prototype.contains = function (t) { return this.indexOf(t) >= 0 ? true : false; };
  }
  if (!String.prototype.trim) {
    String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };
  }

};


/* Build Assistant */
CNU.Assistant = function () {

  // Validator takes an object.
  // Validator validates that object
  function Validator (element, initialize) {

    this.initialize = initialize || true;
    this.o = element;

    this.value = null;
    this.name = this.o.name;
    this.id = this.o.id;
    this.classes = this.o.className;
    this.result = true;
    this.message = this.MESSAGES['default_'+CNU.config.language];
    this.msgElement = this.get_error_element();

    if (this.initialize) { this.init(); }

  }

  Validator.prototype.init = function () {
    if (this.needs_validator(this.o)) { 
      switch (this.o.nodeName) {

        // find all class names, validate against classnames
        case 'TEXTAREA':  this.value = this.o.value;
                          this.result = this.is_valid();
                          break;
  
        // find all class names, validate against classnames
        case 'INPUT':     if (this.o.getAttribute('type') != 'hidden') {
                            this.value = this.o.value;
                            this.result = this.is_valid();
                          }
                          break;
  
        // find all class names, validate against classnames
        case 'SELECT':    this.value = this.o.options[this.o.selectedIndex].value;
                          this.result = this.is_valid();
                          break;
        
        // find all forms, validate each form
        case '#document': this.forms();
                          break;
  
        // find all form elements, validate each element
        case 'FORM':      this.inputs(this.o);
                          break;
  
      
        // can't do jack anything
        default:          break;
      }
    }
  };

  Validator.prototype.MESSAGES = { 
    'is_required_en' : "This field is required.", 
    'matches_syntax_en' : "Improper Format.", 
    'default_en' : "There is an error in this field",
    'form_en' : "There is an error in this form",

    'is_required_es' : "Este campo es obligatorio",
    'matches_syntax_es' : "Formato inadecuado.",
    'default_es' : "There is an error in this field",
    'form_es' : "Hay un error en este formulario"
  };

  Validator.prototype.empty_message_container = function () {
    var container = document.createElement('div');
    container.className = 'error_message';
    container.setAttribute('id', 'error_message_'+this.id);
    return container;
  };

  Validator.prototype.HASCALENDAR_STRING = 'hasCalendar';
  Validator.prototype.DATE_STRING = 'date';
  Validator.prototype.CALENDAR_STRING = 'calendar';
  Validator.prototype.REQUIRED_STRING = 'required';
  Validator.prototype.ERROR_STRING = 'error';
  Validator.prototype.MARITAL_STATUS_STRING = 'marital_status_cd';

  Validator.prototype.is_checkbox = function () { 
    var r = false;
    try { r = (this.o.getAttribute('type') == 'checkbox'); }
    catch (err) { /* do nothing -- object doesn't support this method, which is no big deal.  */ }
    return r;
  };

  Validator.prototype.is_checked = function () {
    var r = false;
    try { r = (this.o.checked); }
    catch (err) { /* do nothing -- object doesn't support this method, which is no big deal.  */ }
    return r;
  };
    

  Validator.prototype.is_required = function () { return this.classes.contains(this.REQUIRED_STRING); };

  Validator.prototype.is_present = function () { 
    if (this.is_checkbox()) { return this.is_checked(); }
    if (this.o.nodeName == 'SELECT') { 

      // start with the current select tag's value
      var result = ((this.value !== null) && (this.value !== ''));

      // loop through the rest of the selects, if there are any.
      var selects = $(this.o.parentNode).getElementsByTagName('select');
      for (var i = 0; i < selects.length; i++) {
        var select_value = selects[i].options[selects[i].selectedIndex].value;
        result = result && ((select_value !== null) && (select_value !== ''));
      }
      return result;
      
    }
    return ((this.value !== null) && (this.value.trim() !== '')); 
  };

  Validator.prototype.has_syntax_rules = function () {
    var r = this.get_syntax_name();
    return (r !== false);
  };

  Validator.prototype.is_valid = function () { 
    var r = true;
    if (this.is_required()) {
      if (! this.has_syntax_rules()) { 
        r = this.is_present();
        if (! r) { this.message = this.MESSAGES['is_required_'+CNU.config.language]; }
      } else {
        r = this.is_present();
        if (! r) {
          this.message = this.MESSAGES['is_required_'+CNU.config.language];
        } else {
          r = this.matches_syntax();
          if (! r) { this.message = this.MESSAGES['matches_syntax_'+CNU.config.language]; }
        }
      }
    } else {
      if (this.has_syntax_rules() && this.is_present()) {
        r = this.matches_syntax();
        if (! r) { this.message = this.MESSAGES['matches_syntax_'+CNU.config.language]; }
      }
    }
    return r;
  };

  Validator.prototype.prepare_value = function () {
    var str = this.o.value;
    str = str.replace(/(^\s+|\s+$)/g, '');
    str = str.replace(/\s\s+/g, ' ');
    return str;
  };

  Validator.prototype.matches_syntax = function () {
    var v = this.prepare_value(), s, syntax, validation_case;
    this.MESSAGES.matches_syntax = 'Improper Format';
    syntax = this.get_syntax(); // Here we got collection of validation cases
    if (syntax) {
      for (validation_case in syntax.validation_cases){ // for each validation case
        if(syntax.validation_cases[validation_case]){ // If validation case is defined
          s = syntax.validation_cases[validation_case]; // get validation case
          if (s.mask instanceof RegExp) { // If validation case is regular expression
            // All previous checks should be valid AND this check should be valid
            if(!s.mask.test(v)){ // If not then
              if(s.error_message){ // If custom error message is defined
                this.MESSAGES.matches_syntax=s.error_message; // Set up Error message for this validator
              }
              return false; // And return false (Input is not valid)
            }
          }
        }
      }
    }
    return true; // By default input is valid
  };

  Validator.prototype.get_syntax = function () { 
    var s_name = this.get_syntax_name();
    var r = CNU.config.regex[s_name]; 
    return r;
  };

  Validator.prototype.get_syntax_name = function () {
    var syntax_name = this.classes;
    var reserved_words = [  new RegExp(this.CALENDAR_STRING), 
                            new RegExp(this.DATE_STRING), 
                            new RegExp(this.HASCALENDAR_STRING),
                            new RegExp(this.REQUIRED_STRING), 
                            new RegExp(this.ERROR_STRING) ];
    $A(reserved_words).each(function (reserved_word) { syntax_name = syntax_name.replace(reserved_word, ''); });
    syntax_name = syntax_name.trim();
    return syntax_name || false;
  };

  Validator.prototype.needs_validator = function (element) { 
    if (element.nodeName == '#document') { element = document.getElementsByTagName('body')[0]; }
    if (element.id.match('customer___person___ssn')) { return true; }
    if (element.id.match('last4')) { return false; }
    if (element.id.match('ssn')) { return false; }
    if (! CNU.dom.is_visible(element)) { return false; }
    return (! $(element).hasClassName('valid')); 
  };
  
  Validator.prototype.button_click = function () { var validation = new Validator(this); return validation.result; };
  Validator.prototype.add_button_click = function () {
    var validation = new Validator(this.form);
    if (validation.result === true) {
      if (this.oldonclick) { this.oldonclick(); }
    }
  };

  Validator.prototype.form_submit = function () { 
    if (typeof CNU.config.submit == 'function') { CNU.config.submit(); }
    var validation = new Validator(this);

    if (validation.result) { validation.unset_form_error(this); }
    else { validation.set_form_error(this); }

    /* Check to see if form submition validation is turned on */
    if (CNU.config.VALIDATE_FORMS === true) { return validation.result; }
    else { return true; }
  };

  Validator.prototype.forms = function () {
    var f = null, all_forms = CNU.dom.get_forms(), i, btn;
    for (i = 0; i < all_forms.length; i++) {
      f = all_forms.item(i);
      if (this.needs_validator(f)) {
        if (this.has_submit_once(f)) {
          btn = this.get_submit_once(f);
          btn.oldonclick = btn.onclick || "";
          btn.onclick = this.add_button_click;
        }
        f.onsubmit = this.form_submit;

        this.enable_form_events(f);
      }
    }
  };

  Validator.prototype.unset_form_error = function (f) {
    // get all 'form_message' className
    var form_error = CNU.dom.getDescendantElementByClass('form_error', f);
    if (form_error) { x = $(form_error).remove(); }
  };

  Validator.prototype.set_form_error = function (f) { 
    this.unset_form_error(f);
    // generate message
    var msgNode = document.createElement('div');
    msgNode.innerHTML = this.MESSAGES['form_'+CNU.config.language]; 
    $(msgNode).addClassName('form_error');

    // get actions fieldset
    var fieldset = CNU.dom.getChildElementByClass('actions', f);

    // append message
    try {
      fieldset.appendChild(msgNode);
    } catch (err) { 
      f.appendChild(msgNode); 
    }
    f.addClassName('f_error');
  };

  Validator.prototype.has_submit_once = function (form) {
    var r = false;
    r = CNU.dom.getElementsByClass('submit_once', form)[1];
    return r;
  };

  Validator.prototype.get_submit_once = function (form) { return CNU.dom.getElementsByClass('submit_once', form)[1]; };

  Validator.prototype.inputs = function (form) {
    var inputs = CNU.dom.get_inputs(form);
    this.check_elements(inputs);

    var selects = CNU.dom.get_selects(form);
    this.check_elements(selects);

    var textareas = CNU.dom.get_textareas(form);
    this.check_elements(textareas);
  };

  Validator.prototype.check_elements = function (elements) {
    var type = null;
    for (var i = 0; i < elements.length; i++) {
      try { type = elements.item(i).getAttribute('type'); }
      catch (err) { type = 'generic'; }
      if ((type != 'hidden') && (type != 'button') && (type != 'image') && (type != 'reset') && (type != 'submit')) { 

          var element = new Validator(elements.item(i));
          if (element.result === true) { element.unset_error(); }
          else { element.set_error(); }
          this.result = this.result && element.result;

      }
    }
  };

  Validator.prototype.enable_form_events = function (form) {
    var inputs = CNU.dom.get_inputs(form);
    this.enable_element_events(inputs);

    var selects = CNU.dom.get_selects(form);
    this.enable_element_events(selects);

    var textareas = CNU.dom.get_textareas(form);
    this.enable_element_events(textareas);
  };

  Validator.prototype.enable_focus = function () { 
    CNU.Assistant.blurred_input = false;
    var validate = new Validator(this);
    if (validate.has_error()) { validate.unset_error(); }
    validate.set_focus();
  };

  Validator.prototype.enable_keydown = function (evt) { 
    var keyCode = false;

    if ("which" in evt) {
      keyCode=evt.which;
    } else if ("keyCode" in evt) {
      keyCode=evt.keyCode;
    } else if ("keyCode" in window.event) {
      keyCode=window.event.keyCode;
    } else if ("which" in window.event) {
      keyCode=evt.which;
    } else { 
    }

    if (keyCode == 9) { CNU.Assistant.tabbed = true; }
    else { CNU.Assistant.tabbed = false; }
  };

  Validator.prototype.enable_button_focus = function (e) { 
    if (! CNU.Assistant.tabbed) {
      var target = CNU.ev.getTarget(e);
      if (CNU.Assistant.blurred_input) { target.click(); }
      CNU.Assistant.blurred_input = false;
    }
  };

  Validator.prototype.enable_blur = function (e) {
    var validate = new Validator(this);
    validate.unset_focus();
    if (validate.result) { validate.unset_error(); }
    else { validate.set_error(); }

    CNU.Assistant.blurred_input = CNU.ev.getTarget(e);
  };

  Validator.prototype.enable_element_events = function (elements) {

    var type = null;
    for (var i = 0; i < elements.length; i++) {
      try { type = elements.item(i).getAttribute('type'); }
      catch (err) { type = 'generic'; }
      if ((type != 'submit') && (type != 'hidden') && (type != 'reset')) {
        CNU.ev.addEvent(elements.item(i), 'blur', this.enable_blur);
        CNU.ev.addEvent(elements.item(i), 'focus', this.enable_focus);
        CNU.ev.addEvent(elements.item(i), 'keydown', this.enable_keydown);
      }

      /* special case: submit_once tags need click invoked after blurs. */
      if ((type == 'submit') || (type == 'reset') || (type == 'button')) {
        //if ($(elements.item(i)).hasClassName('submit_once')) { 
          CNU.ev.addEvent(elements.item(i), 'focus', this.enable_button_focus);
        //}
      }
    }

  };

  Validator.prototype.has_class = function (class_name) { 
    return this.o.parentNode.hasClassName(class_name);
  };

  Validator.prototype.set_class = function (class_name) {
    $(this.o.parentNode).addClassName(class_name);
    if (class_name == 'error') { 
      $(this.o).addClassName(class_name); 
      if (this.o.nodeName == 'SELECT') { 
        var selects = $(this.o.parentNode).getElementsByTagName('select');
        for (var i = 0; i < selects.length; i++) { $(selects[i]).addClassName(class_name); }
      }
    }
  };

  Validator.prototype.unset_class = function (class_name) {
    $(this.o.parentNode).removeClassName(class_name);
    if (class_name == 'error') { 
      $(this.o).removeClassName(class_name); 
      if ((this.o.nodeName == 'SELECT') || (this.o.hasClassName('hasDatepicker'))) { 
        var selects = $(this.o.parentNode).getElementsByTagName('select');
        for (var i = 0; i < selects.length; i++) { $(selects[i]).removeClassName(class_name); }
      }
    }
  };

  Validator.prototype.has_error_message = function () { return (this.message !== null); };

  Validator.prototype.set_error_message = function () {
    this.msgElement.innerHTML = this.message;
    this.o.parentNode.appendChild(this.msgElement);
  };

  Validator.prototype.has_error_element = function () {
    if (this.o.nodeName == '#document') { return false; }
    return (CNU.dom.getElementsByClass('error_message', $(this.o.parentNode)).size() == 1);
  };

  Validator.prototype.get_error_element = function () {
    var r = false;
    if (this.has_error_element()) {
      r = CNU.dom.getElementsByClass('error_message', $(this.o.parentNode))[0];
      if (! r) { r = $('error_message_'+this.id+'___hidden'); }
    }
    return r;
  };

  Validator.prototype.unset_error_message = function () { 
    var errNode = this.get_error_element();
    try {
      $(this.o.parentNode).removeChild(errNode); 
    } catch (err) {
      try {
        $('error_message_'+this.id).remove();
      } catch (err2) {
      }
    }
  };

  Validator.prototype.set_error = function () {
    if (! this.message) { this.message = this.MESSAGES['default_'+CNU.config.language]; }
    if (! this.msgElement) { this.msgElement = this.empty_message_container(); }
    if (! this.has_class('error')) {
      this.set_class('error');
      this.set_error_message();
    }
  };

  Validator.prototype.unset_error = function () {
    if (this.message !== null) { this.message = null; }
    if (this.has_class('error')) {
      this.unset_class('error');
      this.unset_error_message();
    }
  };

  Validator.prototype.has_error = function () { return this.has_class('error'); };
  Validator.prototype.has_focus = function () { return this.has_class('focus'); };

  Validator.prototype.set_focus = function () {
    if (! this.has_class('focus')) {
      this.set_class('focus');
    }
    this.show_tip();
  };
  Validator.prototype.unset_focus = function () {
    this.unset_class('focus');
    this.hide_tip();
  };

  Validator.prototype.get_tip = function () { 
    return CNU.dom.getElementsByClass('tooltip', $(this.o.parentNode))[0];
  };
  Validator.prototype.show_tip = function () { 
    var tip = this.get_tip(); 
    if (tip) {
      if (this.needs_tip_moved()) { this.move_tip(tip); }
      tip.style.display = 'block'; 
    }
  };
  Validator.prototype.hide_tip = function () { 
    var tip = this.get_tip(); 
    if (tip) { tip.style.display = 'none'; }
  };

  Validator.prototype.needs_tip_moved = function () {
    if (this.o.nodeName == 'SELECT') { return true; }
    // if (this.o.hasClassName('date')) return true;
    return false;
  };

  Validator.prototype.move_tip = function (tip) { 
    var label = false;
    try { label = $(this.o.parentNode).getElementsByTagName('label')[0]; }
    catch (err) { /* parent node issue again, most likely. */ }
    if (label) { this.o.parentNode.insertBefore(tip, label); }
  };

  
  // public hash
  return {

    // a public method for initializing the Assistant
    init: function () {
      CNU.ev.addLoadEvent(function () {
        var validations;
        if (CNU.config.VALIDATE === true) {
          CNU.dom.extend_string();
          CNU.dom.hideByClass('tooltip', document);
          CNU.Assistant.setup_errors();
          validations = new Validator(document);
        }
      });
    },

    validate: function (element) {
      var validation = new Validator(element);
      if (validation.result) { validation.unset_error(); }
      else { validation.set_error(); }
      return validation.result;
    },

    enable: function (element) {
      var validation = new Validator(element);  
      validation.enable_form_events(element);
    },

    set_focus: function (element) {
      var validation = new Validator(element);  
      validation.set_focus();
    },

    unset_focus: function (element) {
      var validation = new Validator(element);
      validation.unset_focus();
    },

    unset_errors: function (element) {
      var errors = CNU.dom.getElementsByClass('error');
      for (var i = 0; i < errors.length; i++) {
        if ((errors[i].nodeName == 'INPUT') ||
            (errors[i].nodeName == 'SELECT') ||
            (errors[i].nodeName == 'TEXTAREA')) {
          if ($(errors[i].parentNode).hasClassName('error')) {
            validation = new Validator(errors[i]);
            validation.unset_error();
          }
        }
      }
    },

    setup_errors: function () {
      var errors = CNU.dom.getElementsByClass('error'), i;
      for (i = 0; i < errors.length; i++) {
        if ((errors[i].nodeName == 'INPUT') ||
            (errors[i].nodeName == 'SELECT') ||
            (errors[i].nodeName == 'TEXTAREA')) {
          if (! $(errors[i].parentNode).hasClassName('error')) {
            $(errors[i].parentNode).addClassName('error');
          }
        }
      }
    },

    blurred_input: false,
    tabbed: null

  }; // Assistant return publich hash

}(); // Assistant
CNU.Assistant.init();


// hide all faq's
// add navigation to page
CNU.faq = {};
CNU.faq.init = function () {

  CNU.faq.hide_all();
  CNU.faq.init_nav();

};

// activate behaviors for categories and questions
// add close/open navigation to each question as
// well as the entire page.
CNU.faq.init_nav = function () {

  $$('.faq_category').each(function (c) { CNU.faq.add_events(c); });
  $$('.faq_question').each(function (q) { CNU.faq.add_events(q); });
  $$('.faq_answer').each(function (a) { CNU.faq.add_nav(a); });
  $$('.questions').each(function (ql) { CNU.faq.add_global_nav(ql); });
  
};

// Basic show and hide functionality
CNU.faq.hide = function (e) { Effect.BlindUp(e, { duration: 0.1, fps: 24 }); };
CNU.faq.show = function (e) { Effect.BlindDown(e, { duration: 0.1, fps: 24 }); };

// Global show and hide functionality
CNU.faq.hide_all = function () { 
  $$('.faq').each(function (e) { 
    if (e.tagName != 'BODY') { CNU.faq.hide(e); } 
  });
};

CNU.faq.show_all = function () { 
  $$('.faq').each(function (e) { 
    if (e.tagName != 'BODY') { CNU.faq.show(e); } 
  });
};

// adds onclick event to element
// to show next sibling that has className "faq"
CNU.faq.add_events = function (e) { 
  e.onclick = function () { CNU.faq.toggle_sibling(e); };
  e.onmouseover = function () { e.style.cursor = 'pointer'; };
};

// Toggle the appropriate sibling, if it exists.
CNU.faq.toggle_sibling = function (e) {
  var sibling = CNU.faq.get_sibling(e);
  if (sibling !== false) { CNU.faq.toggle(sibling); }
};

// Toggle the given element
CNU.faq.toggle = function (e) { Effect.toggle(e, 'blind', { duration: 0.1, fps: 24 }); };

// returns next closest sibling which has the classname 'faq'
// otherwise returns false
CNU.faq.get_sibling = function (e) {

  var siblings = e.nextSiblings(), sibling = false, i;

  for (i = 0; i < siblings.length; i++) {
    if ($(siblings[i]).hasClassName('faq')) {
      sibling = siblings[i];
      i = siblings.length;
    }
  }

  return sibling;

};


CNU.faq.add_nav = function (e) { 

  var nav = document.createElement('div');
  var close = document.createElement('a');

  close.setAttribute('href', '#');
  close.onclick = function () { CNU.faq.toggle(e); return false; };
  close.onmouseover = function () { close.style.cursor = 'pointer'; };
  close.appendChild(document.createTextNode('Close'));
  
  $(nav).addClassName('nav');
  $(nav).appendChild(close);
  e.appendChild(nav);

};


CNU.faq.add_global_nav = function (e) { 

  var nav = document.createElement('p');
  var close = document.createElement('a');
  var open = document.createElement('a');

  close.setAttribute('href', '#');
  $(close).addClassName('close');
  close.onclick = function () { CNU.faq.hide_all(); return false; };
  close.onmouseover = function () { close.style.cursor = 'pointer'; };
  close.appendChild(document.createTextNode('Collapse All'));

  $(open).addClassName('open');
  open.onclick = function () { CNU.faq.show_all(); return false; };
  open.onmouseover = function () { open.style.cursor = 'pointer'; };
  open.appendChild(document.createTextNode('Expand All'));

  $(nav).addClassName('nav');
  nav.appendChild(open);
  nav.appendChild(document.createTextNode(" | "));
  nav.appendChild(close);
  
  e.parentNode.insertBefore(nav, e);

};


CNU.sms = {};

// disable the promotional_sms_flg checkbox 
//   if the account_sms_flg checkbox is not checked
CNU.sms.init = function () {
  CNU.ev.addEvent($('customer___sms_preference___account_sms_flg'), 'click', CNU.sms.toggle_sms_checkbox_conditions);
  CNU.ev.addEvent($('customer___sms_preference___terms_sms_flg'), 'click', CNU.sms.toggle_sms_checkbox_conditions);
  CNU.sms.toggle_sms_checkbox_conditions();
};

// Whenever account_sms_flg is checked
//  - mobile phone should be given a 'required' class
//  - promotional_sms_flg should be enabled
CNU.sms.toggle_sms_checkbox_conditions = function () {
  var terms_sms_flg = $('customer___sms_preference___terms_sms_flg');
  var account_sms_flg = $('customer___sms_preference___account_sms_flg');
  var promotional_sms_flg = $('customer___sms_preference___promotional_sms_flg');
  var mobile_phone = $('customer___person___mobile_phone');
  if (terms_sms_flg.checked) {
    account_sms_flg.enable();
  } else {
    account_sms_flg.checked = false;
    account_sms_flg.disable();
  }
  
  if (account_sms_flg.checked) {
    promotional_sms_flg.enable();

    $(mobile_phone).addClassName('required');
    var requiredNode = document.createElement('span');
    requiredNode.innerHTML = '*';
    $(requiredNode).addClassName('required');
    requiredNode.setAttribute('id', 'mobile_required');
    mobile_label = mobile_phone.parentNode.firstChild;
    mobile_phone.parentNode.insertBefore(requiredNode, mobile_label.nextSibling);

  } else {
    promotional_sms_flg.checked = false;
    promotional_sms_flg.disable();
    $(mobile_phone).removeClassName('required');
    $(mobile_phone).removeClassName('error');

    CNU.Assistant.validate(mobile_phone);
    if ($('mobile_required')) { $('mobile_required').remove(); }
  }
};

CNU.selectExtend = { 
  init: function() { 
    CNU.ev.addLoadEvent(function() { 
      $$('select').each(function (e) { 
        CNU.ev.addEvent(e, 'mousedown', function() { $(e).addClassName('dynamic'); }); 
        CNU.ev.addEvent(e, 'blur', function() { $(e).removeClassName('dynamic'); }); 
        CNU.ev.addEvent(e, 'change', function() { $(e).removeClassName('dynamic'); }); 
      }); 
    }); 
  } 
};  
CNU.selectExtend.init();

// Code for Read More functionality provided on index.html
CNU.more_information = {};
CNU.more_information.init = function () {
  
  // The div block concerned 
  var id = '#more_information';

  // We essentially do two things:
  // Create the link for 'Read More' and Hide the Content by default
  CNU.more_information.create_link(id);
  CNU.more_information.hide_content(id);
   
};

CNU.more_information.create_link = function (id) {
  var ele = document.createElement('a');
  ele.setAttribute('href', '#');
  ele.setAttribute('style', 'font-weight: bold; font-size: 1.5em;');
  ele.onclick = function () { CNU.more_information.hide_show(id); return false; };
  ele.onmouseover = function () { ele.style.cursor = 'pointer'; };
  ele.appendChild(document.createTextNode("Read More"));
  $$('.more_information_c').each(function (rl) { rl.parentNode.insertBefore(ele, rl); });
};

CNU.more_information.hide_show = function (id) {
  $j(id).toggle(400);
};

CNU.more_information.hide_content = function (id) {
  // Do a quick hide
  $j(id).hide();  
};

CNU.ev.addLoadEvent(function () {
  $$('.dynamic_label').each(function(wrapper) {
    var target = wrapper.select('input')[0];

    CNU.ev.addEvent(target, 'focus', function() { wrapper.addClassName('active'); });

    function checkInput() {
      if(target.value == '') {
        wrapper.removeClassName('nonempty');
      } else {
        wrapper.addClassName('nonempty');
      }
    }

    CNU.ev.addEvent(target, 'blur', function() {
      wrapper.removeClassName('active');
      checkInput();
    });

    checkInput();
  });
});

CNU.inline_editing = function () { 

  function enable_inline_edit(field) { 
    var enabled = false;

    field.select("*[name]")
      .each(function (el) { 
        if (el.type != "hidden") el.style.display = "inline";
        enabled = true;
      })
      .first().focus();

    if (enabled == true) {
      field.select("span.value").each(function (el) { el.hide(); });
      field.select(".ui-datepicker-trigger").each(function (el) { el.style.display = "inline"; });
    }
  }

  /* When the document is ready, find and enable all inline edit fields. */
  CNU.ev.addLoadEvent(function () { 
    $$(".field.inline").each(function (el) {

      /* event delegation */
      el.onclick = function (ev) { 

        /* find what was clicked */
        var target = $(CNU.ev.getTarget(ev));
        
        /* only do what we want to do based on the target */
        switch (target.nodeName) {
          case 'SPAN':  if (target.hasClassName("value")) enable_inline_edit(el);
                        break;
        }
        
        /* stop the default action */
        return false;
      };
    });

    $$(".field.inline *[name]").each(function (el) { el.hide(); });
  });

  /* public */
  return { enable: function (field) { enable_inline_edit($(field)); } }
  
}();

CNU.paydates = {};
CNU.paydates.original_values = {};
CNU.paydates.dialog = {};
CNU.paydates.ajax_url = CNU.paydates.ajax_url || "/secure/customer_paydates/edit";
CNU.paydates.init = function () { 

  $j("ul.paydates *[name]").each(function () { CNU.paydates.original_values[this.name] = this.value; });

  /* limit this functionality to new_extension page */
  $j("body#loans.new_extension #edit_paydates").click(function(ev) { 
    ev.preventDefault();
    $j("#dialog").dialog("open");
  });

};

CNU.paydates.dialog.open = function () { 
  $j('html, body').animate({scrollTop:0}, 'fast');
  $j('.ui-dialog-titlebar-close').hide();
  $this = $j(this);
  $j.ajax({
    url: CNU.paydates.ajax_url, 
    success: function (data) { 
      var holder = document.createElement("div");
      holder.innerHTML = data;
      $j("#dialog").html($j(holder).find("#content_main form"));
      CNU.Assistant.enable($j("#dialog form").get(0));
      CNU.Assistant.unset_errors($j("#dialog form").get(0));
      CNU.calendar.init();
      $j("#customer_paydates_save_paydates_submit").click(function (ev) { 
        ev.preventDefault(); 
        CNU.paydates.validate();
      });
    }
  });
};

CNU.paydates.dialog.close = function () { 
  $this = $j(this);
  $this.html("<img src='/images/ajax-loader.gif' alt='Loading...' />");
  $this.trigger('update_totals');
};

CNU.paydates.stop_loading = function () { 
  $j("#customer_paydates_save_paydates_spinner").hide();
  $j("#customer_paydates_save_paydates_submit").show();
};

CNU.paydates.start_loading = function () { 
  $j("#customer_paydates_save_paydates_spinner").show();
  $j("#customer_paydates_save_paydates_submit").hide();
};

/* compare_values, deprecated -- not needed */
CNU.paydates.compare_values = function () { 
  var result = true;
  $j("#dialog fieldset.paydates *[name]").each(function () { 
    if ((CNU.paydates.original_values[this.name]) && (this.value != CNU.paydates.original_values[this.name])) { 
      result = false;
      CNU.paydates.validate();
      return false;
    }
  });
  return result;
};

CNU.paydates.validate = function () {
  var valid = true;
  CNU.paydates.start_loading();
  $j("#dialog fieldset.paydates select").each(function () { 
    valid = valid && CNU.Assistant.validate(this);
  });

  if (valid) { CNU.paydates.verify(); }
  else CNU.paydates.stop_loading();
};

CNU.paydates.verify = function () { 
  var new_paydates = { response: "json" };
  $j("#dialog fieldset.paydates *[name]").each(function () { new_paydates[this.name] = this.value; });

  $j.ajax({ 
    url: CNU.paydates.ajax_url,
    dataType: 'json',
    type: 'post',
    data: new_paydates, 
    error: CNU.paydates.error,
    success: CNU.paydates.success,
    complete: CNU.paydates.stop_loading
  });

}; /* END verify */

CNU.paydates.success = function (data, status) {

  if (data.valid != true) {
    CNU.paydates.populate_error_messages(data.errors);
  } else {

    /* done editing paydates */
    $j("#dialog").dialog("close");
    CNU.paydates.populate_success_values(data.values);

    /* Populate additional returned values into fields */
    $j.each(data.values, function (key, value) { 
      if (key == 'loans') CNU.extension.populate_values(value);
    });
  }

}

CNU.paydates.populate_error_messages = function (errors) { 
  $j.each(errors, function (key, value) { 
    $j("#dialog fieldset.paydates *[name="+key+"]").each(function () { CNU.shared.populate_error_message(this, value); });
  });
};

CNU.paydates.populate_success_message = function (success_message) { /* console.log("success_message", success_message); */ };

CNU.paydates.populate_success_values = function (paydates) { 
  $j.each(paydates, function (key, value) { 
    $j("#create_extension fieldset.paydates #customer___customer_paydate___"+key+"_value").html(value);
  });
};

CNU.paydates.populate_values = function (paydates) { 
  $j.each(paydates, function (key, value) { 
    $j("#dialog fieldset.paydates *[name=customer___customer_paydate\["+key+"\]]").val(value);
  });
};
CNU.paydates.error = function () { /* console.log("error"); */ };



CNU.extension = {};
CNU.extension.ajax_url = CNU.extension.ajax_url || location.pathname;
CNU.extension.init = function () { 

  $j("body").addClass("js");

  $j('<span class="partial_payment_link"><a href="#">Add a partial payment</a><span class="tip-trigger partial_payment_tip">?</span></span>').insertAfter(".has_hidden_partial_payment div.total");
  $j('<span class="partial_payment_close"><a href="#">X</a></span>').insertAfter(".partial_payment dd .loading-spinner");

  CNU.extension.hide_partial_payments();
  CNU.extension.reattach_events();
  if (CNU.shared.collapse_payments == true) CNU.extension.hide_partial_payment_step();

  $j("body").bind('update_totals', function () { CNU.extension.update_totals(this); });
  $j("body").bind('update_loans', function () { CNU.extension.populate_values(CNU.shared.loans); });
  $j("body").bind('attach_events', function () { CNU.extension.reattach_events(); });

  CNU.end_action_cd.init();

};
CNU.extension.hide_partial_payment_step = function () { 
  $j('h4.number.four').addClass('three').removeClass('four');
  $j('.partial_payment_information')
    .removeClass('separator')
    .addClass('toggle-content')
    .hide();
  $j('.partial_payment_information>h4').removeClass('number three');
  $a = $j("<div class='toggle-trigger'><a href='#'>"+CNU.shared.collapse_trigger_msg+"</a></div>")
  $a
    .click(function (ev) { 
      ev.preventDefault();
      if (ev.target.nodeName == 'A') {
        $this = $j(this);
        $j('.partial_payment_information').toggle(); 
        if ($this.hasClass('open')) $this.removeClass('open');
        else $this.addClass('open');
      }
    })
    .insertBefore(".partial_payment_information");
};
CNU.extension.reattach_events = function () { 
  $j('.partial_payment_link').unbind('click');
  $j('.partial_payment_link').click(function (ev) {
    if ($j(ev.target).hasClass("tip-trigger")) { 
      ev.stopPropagation();
      if ((CNU.shared.tip_msg != "") && (CNU.shared.showing_tip != true)) {
        $j("<div class='tip'><span class='tip-close'>X</span>"+CNU.shared.tip_msg+"</div>").appendTo(this);
        CNU.shared.showing_tip = true;
        $j('.tip-close').unbind("click");
        $j('.tip-close').click(function (ev, el) { 
          ev.stopPropagation();
          $this = $j(this);
          $this.parent().remove();
          CNU.shared.showing_tip = false;
        });
      }
    }
    if (ev.target.tagName == "A") { 
      var $this = $j(this);
      $this.parent().children(".partial_payment").css("display", "block");
      $this.hide();
    }
    ev.preventDefault();
  });

  $j('.partial_payment_close').unbind('click');
  $j('.partial_payment_close').click(function (ev) { 
    ev.preventDefault();
    var original_value = $j(this).siblings('.field').children('select').val();
    $j(this).siblings('.field').children('select').val('0');
    if (original_value != 0) { $j(this).trigger("update_totals"); }
    $j(this).parent().parent().hide();
    $j(this).parent().parent().parent().children('.partial_payment_link').show();
  });
  
  $j('.partial_payment .field *[name]').unbind('change');
  $j('.partial_payment .field *[name]').change(function (ev) {
    $j(this).trigger("update_totals");
  });
};

CNU.extension.update_totals = function (el) { 
  var data = { response: "json", update: { partial_payment: "Update total" } };

  $j('form#create_extension *[name]').each(function () {
    data[this.name] = this.value;
  });
  
  $j.ajax({
    url: CNU.extension.ajax_url,
    dataType: 'json',
    type: 'post',
    data: data,
    beforeSend: CNU.extension.before_send,
    error: CNU.extension.error,
    success: CNU.extension.success,
    complete: CNU.extension.complete
  });
};

CNU.extension.before_send = function () { $j(".partial_payment span.loading-spinner").show(); $j(".partial_payment_close").hide(); };
CNU.extension.complete = function () { $j(".partial_payment span.loading-spinner").hide(); $j(".partial_payment_close").show(); };

CNU.extension.populate_values = function (loans) { 
  var options = "";
  $j.each(loans, function (key, value) { 
    $j.each(value, function (field_name, amount) { 
      if (field_name == 'partial_payment_amounts') {
        $j(amount).each(function (k, v) {
          options += "<option value='"+v[0]+"'>"+v[0]+"</option>";
        });
        $j("#"+key+"___end_partial_payment_amount")
          .html(options)
          .val(value["end_partial_payment_amount"])
          .each(function () { CNU.shared.clear_error_message(this); });
        options = "";
      }
      CNU.shared.loans[key][field_name] = amount;
      $j("."+key+" ."+field_name).html(amount);
    });
  });
};

CNU.extension.success = function (data, status) {

  if (data.valid != true) {
    CNU.extension.populate_error_messages(data.errors);
  } else {
    CNU.extension.clear_error_messages();
  }

  if (data.values) {
    $j.each(data.values, function (key, value) { 
      if (key == 'loans') CNU.extension.populate_values(value);
    });
  }

};

CNU.extension.error = function () { /* console.log("error"); */ };

CNU.extension.hide_partial_payments = function () { 
  $j(".payment .partial_payment [name]").each(function () {
    $this = $j(this);
    if (($this.val() != '') && ($this.val() != '0')) {
      $this.parent().parent().parent().css("display", "block");
      $this.parent().parent().parent().parent().children(".partial_payment_link").hide();
    }
  });
  $j(".update_partial_payment").remove();
  $j(".partial_payment span.loading-spinner").hide().html(CNU.shared.spinner_img)
};

CNU.extension.populate_error_messages = function (errors) { 
  $j.each(errors, function (key, value) { 
    $j(".payment *[name="+key+"]").each(function () { CNU.shared.populate_error_message(this, value); });
  });
};

CNU.extension.clear_error_messages = function () { 
  $j(".payment *[name]").each(function () { CNU.shared.clear_error_message(this); });
};

CNU.shared = {};
CNU.shared.loans = {};
CNU.shared.tip_msg = "";
CNU.shared.spinner_img = "<img class='loading-spinner' src='/images/spin.gif' alt='loading...' />";
CNU.shared.num_extensions_remaining = 0;
CNU.shared.clear_error_message = function (el) { 
  $el = $j(el);
  $el
    .parent().removeClass("error")
    .children().filter("*[name]").removeClass("error");

  $el.siblings(".error_message").remove();
};

CNU.shared.populate_error_message = function (el, value) { 
  $el = $j(el);
  $el
    .parent().addClass("error")
    .children().filter("*[name]").addClass("error");
  
  if ($el.parent().filter(":has(.error_message)").length == 0) {
    $el.parent().append("<div class='error_message' id='error_message_"+el.id+"___hidden'>"+value+"</div>");
  } else {
    $el.filter(".error_message").html(value);
  }
};

CNU.end_action_cd = {};
CNU.end_action_cd.loans = {};
CNU.end_action_cd.saved_payment = "";
CNU.end_action_cd.init = function () {
  $j(".select_end_action_information li.loading-spinner").html(CNU.shared.spinner_img).hide();
  $j(".select_end_action_information ul.single li .radio_submit").remove();
  $j(".select_end_action_information ul.single li."+$j("input[name=loan[end_action_cd]]").val()).show();
  $j(".select_end_action_information ul.single").append("<li class='slider'><div id='end_action_cd_slider'></div></li>");
  var val = CNU.end_action_cd.selected();
  $j("#end_action_cd_slider").slider({
    range: "min",
    value: val,
    min: 0,
    max: 100,
    stop: CNU.end_action_cd.stop
  });
  CNU.end_action_cd.update_payments($j("#end_action_cd_slider").slider("value"), true);
};
CNU.end_action_cd.selected = function () { 
  if ($j("input[name=loan[end_action_cd]]").val() == "partial_payment") return 96;
  return 50;
};
CNU.end_action_cd.stop = function (event, ui) { 
  $this = $j(this);
  if (ui.value <= 70) $this.slider("value", 50);
  else $this.slider("value", 96);
  $j(".select_end_action_information ul.single li."+$j("input[name=loan[end_action_cd]]").val()).hide();
  CNU.end_action_cd.update_payments($this.slider("value"));
  $j(".select_end_action_information ul.single li."+$j("input[name=loan[end_action_cd]]").val()).show();
};
CNU.end_action_cd.update_payments = function (value, force) { 
  force = force || false;
  switch (value) { 
    case 50:  CNU.end_action_cd.update("pay_in_full", force);
              break;
    case 96:  CNU.end_action_cd.update("partial_payment", force);
              break;
  }
};
CNU.end_action_cd.update = function (value, force) {
  if ((value != "partial_payment") && (value != "pay_in_full")) return false;

  $j("li.loading-spinner").show();
  force = force || false;
  $end_action_cd = $j("input[name=loan[end_action_cd]]");
  if (($end_action_cd.val() != value) || force) {
    $end_action_cd.val(value);

    if (value == "partial_payment") { 
      if ((CNU.shared.num_extensions_remaining > 0) && !force) CNU.shared.num_extensions_remaining = CNU.shared.num_extensions_remaining - 1;
  
      if (CNU.shared.num_extensions_remaining == 0) $j(".extensions_count").html("");
      else $j(".extensions_count").html(CNU.shared.extensions_messages[1]);
  
      if (CNU.end_action_cd.saved_payment != "") {
        $j(".partial_payment_information .loan.info").addClass("extension").removeClass("loan")
        $j('.partial_payment_information .current_loan.info').after(CNU.end_action_cd.saved_payment);
        CNU.end_action_cd.saved_payment = "";
      }
      $j(".partial_payment_information .loan.info").trigger("update_loans").trigger("attach_events");
    }

    if (value == "pay_in_full") {
      if (!force) CNU.shared.num_extensions_remaining = CNU.shared.num_extensions_remaining + 1;
  
      $j(".extensions_count").html(CNU.shared.extensions_messages[0]);
  
      CNU.end_action_cd.saved_payment = $j(".partial_payment_information .loan.info").remove();
      $j(".partial_payment_information .extension.info").addClass("loan").removeClass("extension").trigger("update_loans");
    }

    $j(".num_extensions_remaining").html(CNU.shared.num_extensions_remaining);
    if (CNU.shared.num_extensions_remaining == 1) $j(".num_extensions_remaining_plural").hide();
    else $j(".num_extensions_remaining_plural").show();
  
  }
  $j("li.loading-spinner").hide();
};
CNU.extension.replace_urls = function () { 
  var new_url = "/secure/loans/request_extension";
  if (typeof $j != "undefined") {
    $j("a[href$='/secure/loans/new_extension']").attr("href", new_url)
    $j("form[action$='/secure/loans/new_extension']").attr("action", new_url)
  } else {
    $$("a[href$='/secure/loans/new_extension']").each(function (el) { el.href = new_url; });
    $$("form[action$='/secure/loans/new_extension']").each(function (el) { el.action = new_url; });
  }
  return true;
};
CNU.ev.addLoadEvent(CNU.extension.replace_urls);
