/*
 * EGHRD
 */

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Utility Functions
 */

// From: http://stackoverflow.com/questions/5524045/jquery-non-ajax-post
function nonAjaxSubmit(action, method, input) {
  "use strict";
  var form;
  form = $('<form />', {
      action: action,
      method: method,
      style: 'display: none;'
  });
  if (input !== undefined) {
      $.each(input, function (name, value) {
          $('<input />', {
              type: 'hidden',
              name: name,
              value: value
          }).appendTo(form);
      });
  }
  form.appendTo('body').submit();
}

 /**
  * make part of a selector for jQuery (i.e. assemble and escape dots)
  */
function makePart(v1, v2, v3) {
  var str = v1;
  if (typeof v2 != 'undefined') {
    str += v2;
  }
  if (typeof v3 != 'undefined') {
    str += v3;
  }

  return escapeDot(str, false);
}

/**
 * make part of a selector for jQuery (i.e. assemble and escape dots)
 * Spring ID version for when accessing ids generated by <sf:input/> etc
 * when using array/ list indicies like aVar[1] where spring does not use the []
 */
function makePartS(v1, v2, v3) {
 var str = v1;
 if (typeof v2 != 'undefined') {
   str += v2;
 }
 if (typeof v3 != 'undefined') {
   str += v3;
 }

 return escapeDot(str, true);
}

/**
 * shorthand for the common case of making an ID selector for jQuery
 */
function makeId(v1, v2, v3) {
  return '#' + makePart(v1, v2, v3);
}

/**
 * Spring ID version, @see makePartS
 * shorthand for the common case of making an ID selector for jQuery
 */
function makeIdS(v1, v2, v3) {
  return '#' + makePartS(v1, v2, v3);
}

/*
 * shorthand for the common case of making an class selector for jQuery
 */
function makeClass(v1, v2, v3) {
  return '.' + makePart(v1, v2, v3);
}

/*
 * A dot (.) in a jQuery selector has special meaning.
 * When dealing with spring dotted bean names as IDs we will usually
 * need to escape the dots. also need to to escape other characters
 * which have meaning in selectors. currently this is [] for spring array binding.
 * additionally when building ids spring removes [], so may need to handle that too
 */
function escapeDot(str, isSpringId) {
  if (isSpringId) { str = str.replace(/[\[\]]/g, ""); } // if spring id remove []
  str = str.replace(/([\.\[\]])/g, "\\$1"); // escape any .[]
  return str;
}

/**
 * Display a nice dialog for confirmation messages, alerts etc
 * If cancel label is blank the display a songle confirm button.
 */
function confirmOrCancelAction(messageText, confirmLabel, cancelLabel, confirmCallback) {
  $('#confirm-dialog p').html(messageText);

  $('#confirm-dialog').dialog({
    buttons:
      [{
        text: cancelLabel,
        "class": 'formButton buttonSecondary floatLeft',
        click: function() {
          $(this).dialog( "close" );
        }
      },
      {
        text: confirmLabel,
        "class": 'formButton buttonPrimary floatRight',
        click: function() {
          $(this).dialog( "close" );
          confirmCallback();
        }
      }],
    title: "Confirmation"
  });

  $('#confirm-dialog').dialog("open");
}

function showMessageDialog(selector, confirmCallback) {
  dialogElement = $(selector)

  dialogElement.dialog({
    autoOpen: false,
    draggable: false,
    resizable: false,
    modal: true,
    buttons:
      [{
        text: "Ok",
        "class": 'formButton buttonPrimary floatRight',
        click: function() {
          $(this).dialog( "close" );
          confirmCallback();
        }
      }]
  });

  dialogElement.dialog("open");
}


/*
 * Sets all the inputs in a form to blank. Note: This is different from form.reset() as that will restore the form
 * to it's original value, not clear it.
 * 
 * Taken from: http://www.javascript-coder.com/javascript-form/javascript-reset-form.phtml
 */

function clearForm(form) {
  frm_elements = form.elements;
  for (i = 0; i < frm_elements.length; i++)
  {
      field_type = frm_elements[i].type.toLowerCase();
      switch (field_type)
      {
      case "text":
      case "password":
      case "textarea":
      case "hidden":
          frm_elements[i].value = "";
          break;
      case "radio":
      case "checkbox":
          if (frm_elements[i].checked)
          {
              frm_elements[i].checked = false;
          }
          break;
      case "select-one":
      case "select-multi":
          frm_elements[i].selectedIndex = -1;
          break;
      default:
          break;
      }
  }
}

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * jQuery extension Functions
 */
;(function($) {
/**
 * Check if the given string is an empty string.
 */
$.emptyString = function(s) {
  if (s == null || typeof s == 'undefined') {
    return true;
  } else if (typeof s == 'string') {
    return $.trim(s) == "";
  } else {
    return false;
  }
};

/**
 * check if our value is blank/empty
 */
$.fn.valBlank = function() {
  return $.emptyString(this.val());
};

/**
 * Check if the given var is a positive number (suitable for a database ID)
 */
$.positiveNumber = function(v) {
  if (v == null || typeof v == 'undefined') {
    return false;
  }
  var n = parseInt(v);
  return n >= 1;
};

/**
 * check if our value is a valid ID
 */
$.fn.valIsId = function() {
  return $.positiveNumber(this.val());
};

/** all controls matching the jquery selector will be disabled for enter key form submit */
$.fn.preventEnterKey = function() {
  this.keypress(function(event) {
      if (event.keyCode == 13) {
          event.preventDefault();
          return false;
      }
  });
}

/** clear the control when it loses focus */
$.fn.clearOnLoseFocus = function() {
  var jqo = this;
  this.focusout(function() {
    jqo.val('');
  });
}

})(jQuery);


/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Address control Functions
 */

// define read only constants and handy methods for address type (module pattern)
var ADDRESS_TYPE = (function() {
    var private = {'PHYSICAL': 'true','RELOCATABLE': 'false','ANY': ''};    
    return {
       get: function(name) { return private[name];},
       isPhysical: function(name) { return (name===this.get('PHYSICAL')); },
       isRelocatable: function(name) { return (name===this.get('RELOCATABLE')); },
       isAny: function(name) { return (name===this.get('ANY')); } 
    };
})();


/**
 * Do all init and function binding required by the address control
 */
function initAddressControl(acbName, addressUrl, relocatableUrl) {
  // executing JS so JS is active, mark in form so controller will know
  $(makeId(acbName, '.jsActive')).val('true');

  // set up tab select handlers, copy radio state and select correct tab
  $("#dynAddresstypeP").click(function () { selectAddressTab(acbName, ADDRESS_TYPE.get('PHYSICAL')); } );
  $("#dynAddresstypeR").click(function () { selectAddressTab(acbName, ADDRESS_TYPE.get('RELOCATABLE')); } );
  $("#dynAddresstypeA").click(function () { selectAddressTab(acbName, ADDRESS_TYPE.get('ANY')); } );
  // find address type option user has selected
  var selectedAddressType = $('input:radio[name='  + makePart(acbName, '.physical') + ']:checked').val();
  if ($.emptyString(selectedAddressType)){
	selectedAddressType =  ADDRESS_TYPE.get('ANY');
  }
  $('#dynAddresstypeP').prop('checked', ADDRESS_TYPE.isPhysical(selectedAddressType));
  $('#dynAddresstypeR').prop('checked', ADDRESS_TYPE.isRelocatable(selectedAddressType));
  $('#dynAddresstypeA').prop('checked', ADDRESS_TYPE.isAny(selectedAddressType));  
  selectAddressTab(acbName, selectedAddressType);

  // PAF binding for Address
  $('#pafAddressSearch').autocomplete({
    minLength: 2,
    delay : 700,
    source: function(request, response) {
        $.ajax({
            url: addressUrl,
            dataType: "json",
            cache: false,
            type: "get",
            data: { term: request.term }
        }).done(function(data) {
            response(data);
        });
    },
    select: function(event, data) { pafAddressSelected(acbName, data.item, $('#pafAddressSearch').val()); }
  });
  $('#pafAddressSearch').preventEnterKey();

  // PAF binding for RelocatableAddress
  $('#pafRelocatableAddressSearch').autocomplete({
    minLength: 2,
    delay : 700,
    source: relocatableUrl,
    select: function(event, data) { pafRelocatableAddressSelected(acbName, data.item); }
  });
  $('#pafRelocatableAddressSearch').preventEnterKey();
  $('#pafRelocatableAddressSearch').clearOnLoseFocus();

  // populate data to non-bound fields
  generateAddressDisplayText(acbName);
  $('#relocatableSearchDisplayValue').text($(makeId(acbName, '.pafRelocatableAddress.value')).val());
  $('#pafRelocatableAddressSearch').val($(makeId(acbName, '.pafRelocatableAddress.value')).val());

  // manual/PAF display mode
  // search/edit, manual or read-only display mode for addresses
  var hasAddressId = $(makeId(acbName, '.pafAddress.address.id')).valIsId();
  var hasPafId = $(makeId(acbName, '.pafAddress.pafId')).valIsId();
  var hasManualAddressFieldData = !$(makeId(acbName, '.pafAddress.address.addressLine1')).valBlank()
    || !$(makeId(acbName, '.pafAddress.address.addressLine1')).valBlank()
    || !$(makeId(acbName, '.pafAddress.address.addressLine2')).valBlank()
    || !$(makeId(acbName, '.addressLine1And2')).valBlank()
    || !$(makeId(acbName, '.pafAddress.address.city')).valBlank()
    || !$(makeId(acbName, '.pafAddress.address.postcode')).valBlank();
  if (hasAddressId || hasPafId) {
    addressEdit(acbName, false);
  } else if (hasManualAddressFieldData) {
    addressEdit(acbName, false);
  } else {
    addressEdit(acbName, true);
  }

  // search/edit, manual or read-only display mode for relocatable
  if ($(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.id')).valIsId()) {
    relocatableEdit(acbName, false);
  } else if (!$(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.description')).valBlank()) {
    relocatableManual(acbName, true);
  } else {
    relocatableEdit(acbName, true);
  }
}


/**
 * Handle when auto-complete selects a physical address
 */
function pafAddressSelected(acbName, selectedAddress, enteredPafAddressString) {
  // special case, if special id -1 is selected the go into manual mode
  if (selectedAddress.pafId == -1 && selectedAddress.address.id == -1) {
    addressManual(acbName, true);
    if (!$.emptyString(enteredPafAddressString)){
      // populate form item with text entered by user if the NO ADDRESS FOUND entry selected from PAF result set  
      $(makeId(acbName, '.pafAddress.address.addressLine1')).val(enteredPafAddressString); // This will get populated if addressLine1And2 does not exist
      $(makeId(acbName, '.addressLine1And2')).val(enteredPafAddressString);
    }
  } else {
    // propagate data to form fields
    $(makeId(acbName, '.pafAddress.value')).val(selectedAddress.value);
    $(makeId(acbName, '.pafAddress.address.id')).val(selectedAddress.address.id);
    $(makeId(acbName, '.pafAddress.pafId')).val(selectedAddress.pafId);
    $(makeId(acbName, '.pafAddress.address.addressLine1')).val(selectedAddress.address.addressLine1);
    $(makeId(acbName, '.pafAddress.address.addressLine2')).val(selectedAddress.address.addressLine2);
    $(makeId(acbName, '.addressLine1And2')).val(selectedAddress.address.addressLine1); // This is probably the best compromise
    $(makeId(acbName, '.pafAddress.address.city')).val(selectedAddress.address.city);
    $(makeId(acbName, '.pafAddress.address.postcode')).val(selectedAddress.address.postcode);
    generateAddressDisplayText(acbName);
    // change to read-only display view
    addressEdit(acbName, false);
  }
}

/**
 * Handle when auto-complete selects a relocatable address
 */
function pafRelocatableAddressSelected(acbName, selectedRelocatableAddress) {
  // special case, if special id -1 is selected the go into manual mode
  if (selectedRelocatableAddress.relocatableAddress.id == -1 && selectedRelocatableAddress.relocatableAddress.type.id == -1) {
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.type.id')).val('');
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.description')).val('');
    relocatableManual(acbName, true);
  } else {
    // propagate to read-only field and hidden
    $('#relocatableSearchDisplayValue').text(selectedRelocatableAddress.value);
    $(makeId(acbName, '.pafRelocatableAddress.value')).val(selectedRelocatableAddress.value);
    // propagate data to form fields
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.id')).val(selectedRelocatableAddress.relocatableAddress.id);
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.type.id')).val(selectedRelocatableAddress.relocatableAddress.type.id);
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.description')).val(selectedRelocatableAddress.relocatableAddress.description);
    // change to read-only display view
    relocatableEdit(acbName, false);
  }
}

/**
 * Select the 'physical', 'relocatable' or 'any' address options 
 */
function selectAddressTab(acbName, selectedAddressType) {
  // propagate to other radio
  $(makeId(acbName, '.physical1')).prop('checked', ADDRESS_TYPE.isPhysical(selectedAddressType));
  $(makeId(acbName, '.physical2')).prop('checked', ADDRESS_TYPE.isRelocatable(selectedAddressType));
  $(makeId(acbName, '.physical3')).prop('checked', ADDRESS_TYPE.isAny(selectedAddressType));

  // show/hide the tabs
  if (ADDRESS_TYPE.isPhysical(selectedAddressType)){
    $('#relocatableAddress').hide();
    $('#anyAddress').hide();
    $('#physicalAddress').show();
    $('#relocatableAddressRadio').removeClass("selected");
    $('#anyAddressRadio').removeClass("selected");
    $('#physicalAddressRadio').addClass("selected");
  }else if (ADDRESS_TYPE.isRelocatable(selectedAddressType)){
    $('#physicalAddress').hide();
    $('#anyAddress').hide();    
    $('#relocatableAddress').show();
    $('#physicalAddressRadio').removeClass("selected");
    $('#anyAddressRadio').removeClass("selected");    
    $('#relocatableAddressRadio').addClass("selected");
  } else{  // Any
	$('#anyAddress').show();	  
	$('#relocatableAddress').hide();
	$('#physicalAddress').hide();
	$('#relocatableAddressRadio').removeClass("selected");
	$('#physicalAddressRadio').removeClass("selected");
    $('#anyAddressRadio').addClass("selected");	
  }
  moveCommonFields(selectedAddressType);  
}

/**
 * move the 2 common address fields installation control point and address description to applicable page position either the physical or relocatable address TAB
 */
function moveCommonFields(selectedAddressType) {	
  if (ADDRESS_TYPE.isPhysical(selectedAddressType)) {
     $("#physicalAddress").append($('div.commonAddressFields'));
	 $("#physicalAddress").show();	  
  }else if (ADDRESS_TYPE.isRelocatable(selectedAddressType)) {
	 $("#relocatableAddress").append($('div.commonAddressFields'));
	 $("#relocatableAddress").show(); 
  }else if (ADDRESS_TYPE.isAny(selectedAddressType)) {
	 $("#anyAddress").append($('div.commonAddressFields'));
     $("#anyAddress").show(); 	  
  }
  if (isSearchMyRecordsDisplayed()){
    if (isSearchMyRecordsSet()){
      makeSearchMyRecordsCriteriaVisible(true);
    }
  }else{
	  makeSearchMyRecordsCriteriaVisible(true);	  
  }
}

/* if searchMyRecords & searchAllRecords radiobuttons present on page show/hide specific criteria fields based on button selected*/
function setSearchMyRecords(){
  if ($('#searchMyRecordsRadioContainer').length){
    makeSearchMyRecordsCriteriaVisible($("input[name=searchMyRecords]:checked").val()==="true");
  }
}

function makeSearchMyRecordsCriteriaVisible(on){
  if (on){
    $("#workCertificationDate").show();
    $('div.commonAddressFields').show();
    $('#anyAddressRadio').show();
  }else{
    $("#workCertificationDate").hide();
    $('div.commonAddressFields').hide();
    // hide the 'Any Address' radio option Note: this is present for logged-in external users and sysAdmin only    
    // user has selected "Search All Records" but the "Any Address" radio button is currently selected which is not an allowed state
    // so select "Physical Address" and then hide "Any Address" option
    if ( $("input:radio[name='dynAddresstype']:checked").val()==='any'){
      $("#dynAddresstypeP").trigger("click");
    }
    $("#anyAddressRadio").hide();
    $("#anyAddress").hide();
  }
}

function isSearchMyRecordsDisplayed(){
  return ($('#searchMyRecordsRadioContainer').length);
}

function isSearchMyRecordsSet(){
  return ($('#searchMyRecordsRadioContainer').length && $("input[name=searchMyRecords]:checked").val()==="true");
}

/**
 * switch between manual and PAF relocatable config
 */
function relocatableManual(acbName, isManual) {
  if (isManual) {
    // entering manual mode, clear the id
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.id')).val('');
    $('.relocatableSearchInput').hide();
    $('#relocatableSearchDisplay').hide();
    $('.relocatableManualInput').show();
    $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.description')).focus();
  } else {
    $('#relocatableSearchDisplay').hide();
    $('.relocatableManualInput').hide();
    $('.relocatableSearchInput').show();
    $('#pafRelocatableAddressSearch').focus();
  }
}

/**
 * switch between manual and PAF address config
 */
function addressManual(acbName, isManual) {
  if (isManual) {
    // entering manual mode, clear the ids
    $(makeId(acbName, '.pafAddress.address.id')).val('');
    $(makeId(acbName, '.pafAddress.pafId')).val('');
    $(makeId(acbName, '.pafAddress.value')).val('');
    $('.addressSearchInput').hide();
    $('#addressSearchDisplay').hide();
    $('.addressManualInput').show();
    $(makeId(acbName, '.pafAddress.address.addressLine1')).focus(); // This will get focus if addressLine1And2 does not exist
    $(makeId(acbName, '.addressLine1And2')).focus();
  } else {
    $('#addressSearchDisplay').hide();
    $('.addressManualInput').hide();
    $('.addressSearchInput').show();
    $('#pafAddressSearch').focus();
  }
}

function generateAddressDisplayText(acbName) {
  fullAddress = "";
  if($(makeId(acbName, '.pafAddress.value')).val()) {
    fullAddress = $(makeId(acbName, '.pafAddress.value')).val(); 
  } else {
    addressLine = $(makeId(acbName, '.addressLine1And2')).length > 0 ? 
      $(makeId(acbName, '.addressLine1And2')).val() : 
      $(makeId(acbName, '.pafAddress.address.addressLine1')).val() + " " + $(makeId(acbName, '.pafAddress.address.addressLine2')).val(); 
    fullAddress = addressLine + " " +
      $(makeId(acbName, '.pafAddress.address.city')).val() + " " +
      $(makeId(acbName, '.pafAddress.address.postcode')).val();
    }
  $('#addressSearchDisplayValue').text(fullAddress);
}

function addressManualAccept(acbName) {
  generateAddressDisplayText(acbName);
  addressEdit(acbName, false);
}

/** */
function relocatableNonManualClear(acbName) {
  relocatableManual(acbName, false);
  relocatableClear(acbName);
}

/** clear the search, results, ids etc */
function relocatableClear(acbName) {
  $('#relocatableSearchDisplayValue').text('');
  $('#pafRelocatableAddressSearch').val('');
  $(makeId(acbName, '.pafRelocatableAddress.value')).val('');
  $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.id')).val('');
  $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.type.id')).val('');
  $(makeId(acbName, '.pafRelocatableAddress.relocatableAddress.description')).val('');
  relocatableEdit(acbName, true);
}

/**
 * set relocatable address controls into search (edit) or read-only mode
 */
function relocatableEdit(acbName, isEdit) {
  $('.relocatableManualInput').hide();
  if (isEdit) {
    $('#relocatableSearchDisplay').hide();
    $('.relocatableSearchInput').show();
    $('#pafRelocatableAddressSearch').focus();
  } else {
    $('.relocatableSearchInput').hide();
    $('#relocatableSearchDisplay').show();
  }
}

/** */
function addressNonManualClear(acbName) {
  addressManual(acbName, false);
  addressClear(acbName);
}

/** */
function addressClear(acbName) {
  $('#addressSearchDisplayValue').text('');
  $('#pafAddressSearch').val('');
  $(makeId(acbName, '.pafAddress.value')).val('');
  $(makeId(acbName, '.pafAddress.address.id')).val('');
  $(makeId(acbName, '.pafAddress.pafId')).val('');
  $(makeId(acbName, '.pafAddress.address.addressLine1')).val('');
  $(makeId(acbName, '.pafAddress.address.addressLine2')).val('');
  $(makeId(acbName, '.addressLine1And2')).val('');
  $(makeId(acbName, '.pafAddress.address.city')).val('');
  $(makeId(acbName, '.pafAddress.address.postcode')).val('');
  addressEdit(acbName, true);
}

/**
 * set address controls into search (edit) or read-only mode
 */
function addressEdit(acbName, isEdit) {
  $('.addressManualInput').hide();
  if (isEdit) {
    $('#addressSearchDisplay').hide();
    $('.addressSearchInput').show();
    $('#pafAddressSearch').focus();
  } else {
    $('.addressSearchInput').hide();
    $('#addressSearchDisplay').show();
  }
}


/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Gas Appliance control functions
 */
function initGasApplianceControl(gbName, gasdUrl) {
  // PAF binding for Address
  $(makeId(gbName, '.gasdSearchInput')).autocomplete({ // explicitly NOT makeIdS
    minLength: 2,
    delay : 700,
    source: gasdUrl,
    select: function(event, data) { gasdSelected(gbName, data.item); }
  });
  $(makeId(gbName, '.gasdSearchInput')).preventEnterKey();
  $(makeId(gbName, '.gasdSearchInput')).clearOnLoseFocus();

  // populate data to non-bound fields
  gasdPropagate(gbName);

  if (!$(makeIdS(gbName, '.gasdId')).valBlank()) {
    gasdReadOnly(gbName);
  } else if (!$(makeIdS(gbName, '.make')).valBlank() || !$(makeIdS(gbName, '.model')).valBlank()) {
    gasdManualWithoutFocus(gbName);
  } else {
    gasdEditWithoutFocus(gbName);
  }
}

/** */
function gasdPropagate(gbName) {
  var compositeName = $(makeIdS(gbName, '.make')).val() + ' ' + $(makeIdS(gbName, '.model')).val();
  compositeName = $.trim(compositeName);
  $(makeId(gbName, '.gasdSearchDisplayValue')).text(compositeName);
}

function gasdEditWithoutFocus(gbName) {
  $(makeClass(gbName, '.gasdManual')).hide();
  $(makeId(gbName, '.gasdSearchDisplayContainer')).hide();
  // clear all data, display and search fields
  $(makeIdS(gbName, '.gasdId')).val('');               
  $(makeIdS(gbName, '.make')).val('');
  $(makeIdS(gbName, '.model')).val('');
  $(makeId(gbName, '.gasdSearchInput')).val('');
  $(makeId(gbName, '.gasdSearchDisplayValue')).text('');
  $(makeId(gbName, '.gasdSearchInputContainer')).show();

}

/**
 * set gasd control into search (edit)
 */
function gasdEdit(gbName) {
  gasdEditWithoutFocus(gbName);
  $(makeId(gbName, '.gasdSearchInput')).focus();
}


/**
 * set gasd control into read-only mode
 */
function gasdReadOnly(gbName) {
  $(makeClass(gbName, '.gasdManual')).hide();
  $(makeId(gbName, '.gasdSearchInputContainer')).hide();
  $(makeId(gbName, '.gasdSearchDisplayContainer')).show()

}

function gasdManualWithoutFocus(gbName) {
  // entering manual, ensure gasdId is cleared
  $(makeIdS(gbName, '.gasdId')).val('');
  $(makeId(gbName, '.gasdSearchDisplayContainer')).hide();
  $(makeId(gbName, '.gasdSearchInputContainer')).hide();
  $(makeClass(gbName, '.gasdManual')).show();
}

/**
 * set gasd control into manual mode
 */
function gasdManual(gbName) {
  gasdManualWithoutFocus(gbName);
  $(makeIdS(gbName, '.make')).focus();
}

/**
 * Handle when auto-complete selects a relocatable address
 */
function gasdSelected(gbName, selectedGasAppliance) {
  // special case, if special id -1 is selected the go into manual mode
  if (selectedGasAppliance.gasAppliance.id == -1 && selectedGasAppliance.gasAppliance.gasdId == -1) {
    gasdManual(gbName);
  } else {
    // propagate data to form fields
    $(makeIdS(gbName, '.gasdId')).val(selectedGasAppliance.gasAppliance.gasdId);
    $(makeIdS(gbName, '.make')).val(selectedGasAppliance.gasAppliance.make);
    $(makeIdS(gbName, '.model')).val(selectedGasAppliance.gasAppliance.model);

    // propagate to read-only field
    gasdPropagate(gbName);

    // change to read-only display view
    gasdReadOnly(gbName);
  }
}

/**
 * logical delete of an entry in a gasd group, hides and clears all data fields
 */
function gasdGroupDelete(gbName) {
  gasdEdit(gbName);                                    // revert to edit mode
  $(makeId(gbName, '.main')).hide();                   // hide top level container
}

/**
 * Add a new appliance to the gas group list.
 * intimately tied to the gasApplianceGroupTag and will do nothing if we
 * are at max appliances (currently 5).
 */
function gasdGroupAdd(gasApplianceListName) {
  if($('.gasdMainContainer:hidden').length > 0) {
    applianceToAdd = $('.gasdMainContainer:hidden:first');
    if($('.gasdMainContainer:last')[0] != applianceToAdd[0]) {
      $('.gasdMainContainer:last').after(applianceToAdd); // Move to the end of the list
    }
    applianceToAdd.show();
  } else {
    showMessageDialog("#maxGasAppliancesDialog", function(){})
  }
}

/** init the gas appliance group */
function hideIfEmpty(gbName) {
  if ($(makeIdS(gbName, '.gasdId')).valBlank()
    && $(makeIdS(gbName, '.make')).valBlank()
    && $(makeIdS(gbName, '.model')).valBlank()) {
    $(makeId(gbName, '.main')).hide();
  }
}

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Help popup functions
 */

function initHelpPopups() {
  // Help popups relate to the element directly before them. We handle each
  // possible previous element (span, textarea, etc) differently.

  $('.appFieldHelp').prev('.ihelp').click(function(event) {
    popup = $(this).next('.appFieldHelp');
    $('.appFieldHelp').not(popup).hide(); // Hide all other popups
    popup.toggle();
    positionPopup(popup, this);
    event.preventDefault(); // Stops triggering focus when inside label elements. Prevents the date picker from showing
  });

  $('.appFieldHelp').prev('.ihelp').hover(function(event) {
    popup = $(this).next('.appFieldHelp');
    $('.appFieldHelp').not(popup).hide(); // Hide all other popups
    popup.toggle();
    positionPopup(popup, this);
    event.preventDefault(); // Stops triggering focus when inside label elements. Prevents the date picker from showing
  });

  $('.appFieldHelp').prev('textarea, input').focus(function() {
    // We use nextAll().first() because jquery dynamically inserts elements
    // around <input> elements
    popup = $(this).nextAll('.appFieldHelp').first();
    $('.appFieldHelp').not(popup).hide(); // Hide all other popups
    popup.show();
    positionPopup(popup, this);
  });

  $('.appFieldHelp').prev('textarea, input').blur(function() {
    popup = $(this).nextAll('.appFieldHelp').first();
    popup.hide();
  });

  $(".appFieldHelpClose").click(function() {
    popup = $(this).parent().parent();
    popup.hide();
  });

  function positionPopup(popup, parent) {
    popup.position({
      my : "left+10 top-3",
      at : "right top",
      of : parent,
      collision : "none"
    });
  }
}

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * User Roles
 */

function removeRole(roleName) {
  $(makeId(roleName, '.main')).removeClass('userRoleApplied');
  $(makeId(roleName, '.main')).addClass('userRole');
  $(makeId(roleName, '.removeLink')).hide();
  $(makeId(roleName, '.enableLink')).show();
  $(makeIdS(roleName, '.enabled')).val('false');
  $(makeIdS(roleName, '.sectionOpen')).val('false');

  var roleProps = $(makeId(roleName, ".roleProps"));
  if (roleProps) {
    $(makeId(roleName, '.regoLabel')).hide();
    $(makeId(roleName, '.regoValue')).hide();
    $(makeId(roleName, '.updatedDate')).hide();
    roleProps.hide();
  }
}

function addRole(roleName) {
  $(makeId(roleName, '.main')).removeClass('userRole');
  $(makeId(roleName, '.main')).addClass('userRoleApplied');
  $(makeId(roleName, '.removeLink')).show();
  $(makeId(roleName, '.enableLink')).hide();
  $(makeIdS(roleName, '.enabled')).val('true');
  $(makeIdS(roleName, '.sectionOpen')).val('true');

  var roleProps = $(makeId(roleName, ".roleProps"));
  if (roleProps) {
    roleProps.show();
  }
}

function hideRoleProps(roleName) {
  var roleProps = $(makeId(roleName, ".roleProps"));
  if (roleProps && $(makeIdS(roleName, '.sectionOpen')).val() == 'false') {
    roleProps.hide();
  }
}

function initRole(roleName, confirmMessage, confirmLabel, cancelLabel) {
  hideRoleProps(roleName);

  var removeLink = $(makeId(roleName, ".removeLink"));
  var enableLink = $(makeId(roleName, ".enableLink"));

  if ($(makeIdS(roleName, ".enabled")).val() == "true") {
    enableLink.hide();
  } else {
    removeLink.hide();
  }

  removeLink.click(function() {
      confirmOrCancelAction(
        confirmMessage,
        confirmLabel,
        cancelLabel,
        function() {removeRole(roleName);});
  });
  enableLink.click(function() {
    addRole(roleName);
  });
}

function initRadioRoles() {
  $('input[name=roleSelectionRadio]').change(function() {
    $('input[name=roleSelectionRadio]:not(:checked)').each(function() {
      var roleName = $(this).attr('id').replace('.radio', '');
      $(makeIdS(roleName, '.enabled')).val('false');
      $(makeIdS(roleName, '.sectionOpen')).val('false');
      $(makeId(roleName, '.main')).removeClass("active");

      var roleProps = $(makeId(roleName, ".roleProps"));
      if (roleProps) {
        roleProps.hide();
      }
    });

    var roleName = $('input[name=roleSelectionRadio]:checked').attr('id').replace('.radio', '');
    $(makeIdS(roleName, '.enabled')).val('true');
    $(makeIdS(roleName, '.sectionOpen')).val('true');
    $(makeId(roleName, '.main')).addClass("active");
    var roleProps = $(makeId(roleName, ".roleProps"));
    if (roleProps) {
      roleProps.show();
    }
  });
}


/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Lightbox
 */

function initLightboxes() {
  $('.lightbox').colorbox({width: '500px'});
}

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Confirm dialogs
 */

function initConfirmDialogs() {
  $('#confirm-dialog').dialog({
    autoOpen: false,
    draggable: false,
    resizable: false,
    modal: true
  });
}

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * Startup
 */

$(document).ready(function() {
  initHelpPopups();
  initLightboxes();
  initConfirmDialogs();
});

/* ----------------------------------------------------------------------------
 * ----------------------------------------------------------------------------
 * END
 */