/*
Used by tenancy-related forms to disable/enable fields related to
writtenNtqRequired.
*/
function ntqRequiredChanged()
{
  var element = document.getElementById('writtenNtqRequired');
  if (element != null)
  {
    var b           = element.checked;
    var wnrDisabled = element.disabled; // If the writtentNtqRequired field is disabled
                                        // then always disable the dependent fields
    
    var wnrCheckbox = document.getElementById('writtenNtqReceived');
    wnrCheckbox.disabled = !b || wnrDisabled;
    // Note - the checkbox has to be made disabled. Making it readOnly does not
    // seem to have any effect.
    
    setDateDisabled('writtenNtqReceivedDate', !b || wnrDisabled);
  }
}

/**
 * Sets the disabled/enabled state of a date field.
 * Only works correctly for richfaces date pickers.
 * @param dateFieldId The id of the date field to be enabled/disabled 
 * @param disabled A boolean value indicating the desired state
 */
function setDateDisabled(dateFieldId, disabled)
{
  var popupButton = document.getElementById(dateFieldId + 'PopupButton');
  var inputField = document.getElementById(dateFieldId + 'InputDate');

  // First make the input field read only
  // Note - the input field has to be made readOnly. Making it disabled causes
  // a problem as it's value is then not submitted. This causes bugs if the value
  // is changed and then it's subsequently "disabled" before the enclosing form is
  // submitted.
  inputField.readOnly = disabled;

  // Now hide the popup button for the calendar
  if (popupButton != null)
  {
    popupButton.style.display = (disabled ? 'none' : '');
  }
}

/**
 * Returns the date object value for a date input field.
 * The current implementation works for jquery datepicker input fields
 * @param dateFieldId the id of the date field for which to return the value
 * @return the Date object value of the field or null if the field is blank
 */
function getDateValue(dateFieldId)
{
  var d = jQuery("#" + dateFieldId + "InputDate").datepicker("getDate");
  return d;
}

/**
 * Sets the state of a checkbox field.
 * @param checkboxFieldId The id of the ehckbox field to set
 * @param checked A boolena value indiciating whether the checkbox should be on or off
 */
function setCheckbox(checkboxFieldId, checked)
{
  var checkboxElem = document.getElementById(checkboxFieldId);
  checkboxElem.checked = checked;
}

/**
 * Used to set the default button in forms.
 */
function setDefaultButton(buttonId)
{
  if (buttonId && buttonId != '' && buttonId != 'noDefaultCommand')
  {
    var defaultButton = document.getElementById(buttonId);
    defaultButton.style.fontWeight = 'bold';
  }
}


function checkForInnerTextFeature()
{
  var obj = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false;

  return obj;
}


/**
 * Used to change the text content of a specified element.
 */
function changeText(elem,changeVal)
{
  if(!checkForInnerTextFeature())
  {
    elem.textContent = changeVal;
  }
  else
  {
    elem.innerText = changeVal;
  }
}

/**
 * Trims whitespace from the beginning and end of a string - returns the
 * modified string.
 */
function trim(s)
{
  s = s.replace(/^\s*/,''); // trim whitespace at the beginning
  s = s.replace(/\s*$/,''); // trim whitespace at the end
  return s;
}

/**
 * Indicates whether the specified string is null or empty.
 */
function isBlank(s)
{
  return s == null || s == '';
}

/**
 * Indicates whether the specified character is a lowercase letter.
 */
function isCharLowercase(c)
{
  return isCharLetter(c) && c == c.toLowerCase();
}

/**
 * Indicates whether the specified character is an uppercase letter.
 */
function isCharUppercase(c)
{
  return isCharLetter(c) && c == c.toUpperCase();
}

/**
 * Indicates whether the specified character is a letter.
 */
function isCharLetter(c)
{
  var alphaExp = /^[a-zA-Z]+$/;
  return c.match(alphaExp);  
}

/**
 * Indicates whether the specified character is a numeric.
 */
function isCharNumeric(c)
{
  return !isNaN(c);
}

/**
 * Closes the current dialog when the esc key is pressed. This function should
 * be registered as follows:
 *   <ui:param name="keyHandler" value="closeDialogOnEsc(event, 'expCancelCommand');" />
 * **Note**: This does not work reliably so don't use it yet!
 * @param event the key press event
 * @param buttonId the id of the cancel button to click when the ESC key is pressed.
 */
function closeDialogOnEsc(event, buttonId)
{
  var key = (!event.which) ? (event.keyCode) : (event.which);
  if (key === 27)
  {
    var cancelButton = document.getElementById(buttonId);
    cancelButton.click();
  }
}

/**
 * Used on the location dialog to default the location code if it does not
 * already have a value.
 */
function setDefaultLocationCode()
{
  var locationCodeElem = document.getElementById('locationCode');
  var locationCode = locationCodeElem.value;

  if (locationCode == null || locationCode == '')
  {
    var addressLine1Elem = document.getElementById('addressLine1');
    var addressLine2Elem = document.getElementById('addressLine2');
    var addressLine1 = addressLine1Elem.value;
    var addressLine2 = addressLine2Elem.value;
    
    locationCode = addressLine1;
    if (addressLine2 != null && addressLine2 != '')
      locationCode += ', ' + addressLine2;
    
    if (locationCode.length > 90)
      locationCode = locationCode.substring(0, 85) + "...";
    
    locationCodeElem.value = locationCode;
  }
}

/**
 * Used on management item dialogs to default the display name if it does not
 * already have a value.
 */
function setDefaultManagementItemName()
{
  var nameElem = document.getElementById('name');
  var name     = nameElem.value;
  var typeElem = document.getElementById('type');

  if (typeElem != null && (name == null || name == ''))
  {
    var validToDateElem = document.getElementById('validToDateInputDate');
    var type            = typeElem.value;
    var validToDate     = validToDateElem.value;
    
    name = type + ", valid to " + validToDate;
    
    if (name.length > 90)
      name = name.substring(0, 85) + "...";
    
    nameElem.value = name;
  }
}

/**
 * Used on the expenditure template dialog to default the name if it does not
 * already have a value.
 */
function setDefaultExpenditureTemplateName()
{
  var nameElem = document.getElementById('name');
  var name = nameElem.value;

  if (name == null || name == '')
  {
    var location   = getSelectLabel('location');
    var supplier   = getSelectLabel('supplier');
    var amount     = document.getElementById('transactionValue').value;
    var n          = document.getElementById('repeatFrequencyUnit').value;
    var repeatFreq = getSelectLabel('repeatFrequency');

    // Remove leading spaces from the location
    location = trim(location);
    
    // Format the amount correctly
    if (!isBlank(amount))
    {
      amount = parseFloat(amount).toFixed(2);
    }
    
    if (location.length > 35)
      location = location.substring(0, 35) + "...";
    if (supplier.length > 35)
      supplier = supplier.substring(0, 35) + "...";
    
    if (!isBlank(location) && !isBlank(supplier) && !isBlank(amount) && !isBlank(n) && !isBlank(repeatFreq))
    {
      name = location + " - " + supplier + ", " + amount + " repeat each " + n + " " + repeatFreq;
      nameElem.value = name;
    }
  }
}

/**
 * The following functions support the update of the preview field when creating
 * multiple sub-units with a new location.
 */

/**
 * Called when one of the sub-unit definition fields is changed. Updates the
 * preview field to show what sub-units will be created.
 */
var digitScheme = new Array();
digitScheme[0] = '1';digitScheme[1] = '2';digitScheme[2] = '3';
digitScheme[3] = '4';digitScheme[4] = '5';digitScheme[5] = '6';
digitScheme[6] = '7';digitScheme[7] = '8';digitScheme[8] = '9';
digitScheme[9] = '10';
var letterScheme = new Array();
letterScheme[0] = 'A';letterScheme[1] = 'B';letterScheme[2] = 'C';
letterScheme[3] = 'D';letterScheme[4] = 'E';letterScheme[5] = 'F';
letterScheme[6] = 'G';letterScheme[7] = 'H';letterScheme[8] = 'I';
letterScheme[9] = 'J';

function updateSubUnitPreview()
{
  var previewText = '';
  
  var locationCodeElem = document.getElementById('locationCode');
  var numSubUnitsElem  = document.getElementById('numSubUnits');
  var labelElem        = document.getElementById('subUnitLabels');
  var numSchemeElem    = document.getElementById('subUnitNumberingScheme');

  if (numSubUnitsElem != null && labelElem != null && numSchemeElem != null)
  {
    var numSubUnits     = numSubUnitsElem.value;
    var label           = labelElem.value;
    var locationCode    = locationCodeElem.value;
    var numberingScheme = (numSchemeElem.selectedIndex == 0) 
                        ? (digitScheme)
                        : (letterScheme);
    
    if (numSubUnits !== null &&
        label !== null && label != '' &&
        locationCode != '')
    {
      var first = true;
      for (var i=0; i < numSubUnits; i++)
      {
        if (!first)
        {
          previewText += ', ';
        }
        previewText += '[' + label + ' ' + numberingScheme[i] + ', ' + locationCode + ']';
        first = false;
      }
      
      if (previewText.length > 150)
      {
        previewText = previewText.substring(0, 150) + " ...";
      }
    }
  }
  
  var previewElem = document.getElementById('subUnitPreview');
  if (typeof previewElem != 'undefined' && previewElem !== null)
    changeText(previewElem, previewText);
}

/**
 * Effectively an override of the standard trinidad event handler for number
 * spin-boxes. We intercept the event handler in order to update the preview
 * field. 
 */
function extendedSpinboxRepeat(id, increment, stepSize, min, max)
{
  vanillaEventHandler(id, increment, stepSize, min, max);
  updateSubUnitPreview();
}

/**
 * The function which replaces the standard event handler for number spinboxes
 * with the interceptor method. 
 */
var vanillaEventHandler = null;
function interceptSpinboxEventHandler()
{
  vanillaEventHandler = _spinboxRepeat;
  _spinboxRepeat = extendedSpinboxRepeat;
}

/**
 * Sets the message string for a trinidad created field.
 * @param fieldId The id of the field for which to set the message.
 * @param message The message to be set.
 * @return void.
 */
function setFieldMessage(fieldId, message)
{
  var msgElem = document.getElementById(fieldId + '::msg');
  changeText(msgElem, message);
  
  setElementShown(fieldId + '::msg', !isBlank(message));
}

/**
 * Creates a popup window.
 * @param url The url to navigate to in the popup window.
 * @param windowName The name to assign to the new window.
 */
function showPopup(url, windowName)
{
  var options = 'height=600,width=600,menubar=no,toolbar=yes,location=no,directories=no,scrollbars=yes';
  var newWindow = window.open(url, windowName, options);
  if (window.focus)
  {
    newWindow.focus();
  }
}

/**
 * Displays a help topic.
 */
function showHelp(appUrl, topic, subtopic)
{
  var url = appUrl + "/public/doc/" + topic + ".html#" + subtopic;
  showPopup(url, "tnHelp");
}

/**
 * Handles the expenditure category changing in the expenditure dialog.
 */
var lastAutoSetTaxCategoryValue = null;
function setTaxCategory(expCategoryElem)
{
  var taxCategoryElem = document.getElementById('taxCategory');
  
  if (taxCategoryElem.value         == ''                         ||
      lastAutoSetTaxCategoryValue   == null                       ||
      taxCategoryElem.selectedIndex == lastAutoSetTaxCategoryValue)
  {
    var expCategory = expCategoryElem.options[expCategoryElem.selectedIndex].text;
    var taxCategory = categoryMap[expCategory];
    
    if (taxCategory != null)
    {
      for (var i=0; i < taxCategoryElem.options.length; i++)
      {
        if (taxCategoryElem.options[i].text == taxCategory)
        {
          taxCategoryElem.selectedIndex = i;
          lastAutoSetTaxCategoryValue   = i;
          break;
        }
      }
    }
  }
}

function createAdvert(id, rendered, enabled, componentType, opportunityRef, clientRef, options)
{
  if (rendered && enabled)
  {
    if (componentType == 'miniNotifier')
    {
      if (typeof SimpleMiniNotifier == 'undefined')
        return;
        
      new SimpleMiniNotifier(id, opportunityRef, clientRef, options);
    }
    else if (componentType == 'inlineAdvertList')
    {
      if (typeof SimpleInlineAdvertList == 'undefined')
        return;

      new SimpleInlineAdvertList(id, opportunityRef, clientRef, options);
    }
    else
    {
      alert('Error in externalAd component: Unrecognized componentType: ' + componentType);
    }
  }
}

function getWindowTitle(w)
{
  var title = "";
  try
  {
    if (w != null && w.document != null && w.document.title != null)
      title = w.document.title;
  }
  catch (e)
  {
    // probably caused by permission error going across to selenium frame
    title = "Selenium Remote Control";
  }

  return title;
}

function getTopWindow()
{
  var w = window;
  while (w.parent != null && w.parent != w)
  {
    // When running tests, don't consider the Selenium containing frame.
    // SPM-976: Unfortunately, this code fails when cross-domain security kicks
    // in, which will be the case when one is http and the other is https.
    // Hence, the introduction of the goLogin.html page which forces the
    // navigation to the top window before navigating to the login page.
    var parentTitle = getWindowTitle(w.parent);
    
    if (parentTitle.indexOf('Selenium Remote Control') == 0)
    {
      break;
    }
    w = w.parent;
  }
  
  return w;
}

function sendTopWindowHere()
{
  // Find the top-most window
  var topWindow = getTopWindow();
  
  // Determine whether we are in top-level window or in an embedded frame
  // If we are not in the top window then set the top window location to the
  // current window location
  if (window != topWindow)
  {
    topWindow.location = window.location;
  }
}

/**
 * Sets the enabled state of a primefaces tab.
 * Call it as follows:
 *   YAHOO.util.Event.onContentReady('tabViewWidgetVar', function(){
 *          setTabEnabled(locationDialogTabViewVar, 1, false);
 *          });
 * where locationDialogTabView is the widgetVar set on the primefaces tab view component.
 */
function setTabEnabled(tabVar, tabSequence, enabled)
{
  tabVar.getTab(tabSequence).set('disabled', !enabled);
}

/**
 * Returns the label for the currently selected value of a select control.
 * @param selectElementId The id of the select control/
 */
function getSelectLabel(selectElementId)
{
  var selectElem = document.getElementById(selectElementId);

  return selectElem.options[selectElem.selectedIndex].text;
}

/**
 * Correctly handle PNG transparency in Win IE 5.5 & 6. 
 */
function correctPNG()
{
  var arVersion = navigator.appVersion.split("MSIE")
  var version = parseFloat(arVersion[1])
  if ((version >= 5.5) && (document.body.filters)) 
  {
    for(var i=0; i<document.images.length; i++){
    var img = document.images[i]

    var imgName = img.src.toUpperCase()
    if (imgName.substring(imgName.length-3, imgName.length) == "PNG"){
      var imgID = (img.id) ? "id='" + img.id + "' " : ""
      var imgClass = (img.className) ? "class='" + img.className + "' " : ""
      var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
      var imgStyle = "display:inline-block;" + img.style.cssText 
      if (img.align == "left") imgStyle = "float:left;" + imgStyle
      if (img.align == "right") imgStyle = "float:right;" + imgStyle
      if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
      var strNewHTML = "<span " + imgID + imgClass + imgTitle
      + " style=" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
      + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
      + "(src='" + img.src + "', sizingMethod='scale');></span>" 
      img.outerHTML = strNewHTML
      i = i-1
      }
    }
  } 
}

function setElementShown(elementId, show)
{
  var element = document.getElementById(elementId);
  element.style.display = (show ? 'block' : 'none');
}

function goPrintablePage()
{
  // Save the old the form target & action
  var f = document.getElementById('mainForm');
  var oldTarget = f.target;
  var oldAction = f.action;
  
  try
  {
    // Temporarily change the form target
    f.target = '_printablePage';
    
    // Temporarily change the form action to append an extra param
    f.action = oldAction + '&printable=true'
    
    // Click on the hidden printable link
    var link = document.getElementById('printablePageCommand');
    clickLink(link);
  }
  finally
  {
    // Reset the form target
    f.target = oldTarget;
    f.action = oldAction;
  }
}

function advertDialogPublishToSupplier(advert, detailAccessKey, url, frame)
{
  var advertPublishUrlElem = document.getElementById('advertPublishUrl');
  advertPublishUrlElem.value = url;

  // Save the old the form target & action
  var f = document.getElementById('mainForm');
  var oldTarget = f.target;
  var oldAction = f.action;
  
  try
  {
    // Temporarily change the form target
    f.target = frame;
    
    // Click on the hidden printable link
    var linkElem = document.getElementById('internalAdvertClickedCommand');
    clickLink(linkElem);
  }
  finally
  {
    // Reset the form target
    f.target = oldTarget;
    f.action = oldAction;
  }
}

function clickLink(link)
{
  var cancelled = false;

  if (document.createEvent)
  {
    var event = document.createEvent("MouseEvents");
    event.initMouseEvent("click", true, true, window,
        0, 0, 0, 0, 0,
        false, false, false, false,
        0, null);
    cancelled = !link.dispatchEvent(event);
  }
  else if (link.fireEvent)
  {
    cancelled = !link.fireEvent("onclick");
  }

  if (!cancelled)
  {
    window.location = link.href;
  }
}

function _setVer(n)
{
  var _verElem = document.getElementById('ver_');
  changeText(_verElem,n);
}

/**
 * Convert the email id to a candidate user id.
 * Basically does the following:
 * - removes the '@' and everything after it
 * - converts it to lowercase
 * - removes any characters which are not one of [0-9][a-z][A-Z][._].
 * Note that an empty string may result if the input string consists
 * entirely of invalid characters.
 */
function getDefaultUserId(emailElementId, userIdElementId)
{
  var emailElem  = document.getElementById(emailElementId);
  var userIdElem = document.getElementById(userIdElementId);

  var email  = emailElem.value;
  var userId = userIdElem.value;
  
  if ((userId == null || userId == '') &&
      (email  != null && email != '' ) )
  {
    userId = email.toLowerCase(); 
    if (userId.indexOf('@') != -1)
      userId = userId.substring(0, userId.indexOf('@'));

    var strippedUserId = '';
    var c;
    for (var i=0; i < userId.length; i++)
    {
      c = userId.charAt(i);
      if (isCharLetter(c) || isCharNumeric(c) || c == '.' || c == '_' )
        strippedUserId += c;
    }
    
    userIdElem.value = strippedUserId;
  }
}

/**
 * The following function is used to make a Trinidad dialog draggable.
 * It should be invoked after the dialog is launched.
 */

function attachDraggabilityToDialog()
{
  // The div that contains the iframe for the dialog
  var dialogFrameDiv = null;

  var frames = document.getElementsByTagName("iframe");
  if (frames.length > 0)
  {
    var _node = document.getElementsByTagName("iframe")[0].parentNode;
    if (_node != null && _node.tagName == "DIV")
    {
      dialogFrameDiv = _node;
    }
  }

  if (dialogFrameDiv != null)
  {
    var topOffset = isIE() ? -10 : 0;
    jQuery(function(){
      jQuery(dialogFrameDiv).draggable({
        iframeFix: true,
        cursorAt: {top: topOffset},
        cursor: 'move',
        containment: 'window'
        });
    });
  }
}

function isIE()
{
  var ua = navigator.userAgent;
  return (ua.indexOf("MSIE") >= 0);
}


/** 
 * SPM-815: Change behaviour of up/down buttons on inputNumberSpinbox so
 * changing a null value is more intuitive. This function overrides/replaces
 * the one in trinidad javascript so may need revising when uptaking a new
 * version of trinidad.
 */
function _stepSpinboxValue(id, increment, stepSize, min, max)
{
   var circular = false;
   var input = _getElementById(document, id);
   if (input)
   {
      var value = input.value;
      if (isNaN(value) || isNaN(stepSize) || isNaN(min) || isNaN(max))
      {
        alert("value, stepSize, min, and max must all be numbers. value: "+
               value+", stepSize: "+stepSize+", min: "+min+", max: "+max);
        return false;
      }
      if (increment)
      {
        var incrementedValue = parseFloat(value) + parseFloat(stepSize);
        if (incrementedValue < max)
              input.value = incrementedValue;
        else if (circular)
              input.value = min;
        else input.value = min; // {tn} SPM-815 was set to max. Change to min.
      }
      else
      {
        var decrementedValue = parseFloat(value) - parseFloat(stepSize);

        if (decrementedValue > min)
          input.value = decrementedValue;
        else if (circular)
          input.value = max;
        else input.value = max; // {tn} SPM-815 was set to min. Change to max.
      }
      return true;
   }
   return false;
}

function fixViewStateId()
{
  var viewStateFields = document.getElementsByName('javax.faces.ViewState');
  if (viewStateFields !== null)
  {
    for (var i=0; i < viewStateFields.length; i++)
    {
      var viewStateField = viewStateFields[i];
      if (typeof(viewStateField.id) == 'undefined' ||
          viewStateField.id == null                ||
          viewStateField.id == ''                   )
      {
        viewStateField.id = viewStateField.name;
      }
    }
  }
}

function addAutoCompleteButton(autoCompleteVar, toggleListButtonId)
{
  var bToggler = YAHOO.util.Dom.get(toggleListButtonId);

  var toggleB = function(e) {
    // Is open 
    if(autoCompleteVar.isContainerOpen())
    { 
      autoCompleteVar.collapseContainer(); 
    } 
    // Is closed 
    else
    {
      autoCompleteVar.getInputEl().focus(); // Needed to keep widget active 
      setTimeout(function() { // For IE 
        autoCompleteVar.sendQuery("~"); 
      },0); 
    } 
  } 
  bToggler.onclick=toggleB;

  autoCompleteVar.containerExpandEvent.subscribe(function(type, acs){
    // Disable the form onkeypress event
    var f = document.getElementById('mainForm');
    if (f != null)
    {
      f._onkeypress = f.onkeypress;
      f.onkeypress = null;
    }
  });

  autoCompleteVar.containerCollapseEvent.subscribe(function(type, acs){
    // Disable the form onkeypress event
    var f = document.getElementById('mainForm');
    if (f != null)
    {
      if (f._onkeypress && f._onkeypress != null)
      {
        f.onkeypress = f._onkeypress;
        f._onkeypress = null;
      }
    }
  });

  // Open the container when the user types a down arrow
  var inputElement = autoCompleteVar.getInputEl();
  inputElement.onkeypress = function(e){
    var unicodeKey = e.keyCode? e.keyCode : e.charCode;
    if (unicodeKey == 40 && !autoCompleteVar.isContainerOpen())
    {
      var queryString = "~";
      if (inputElement.value && inputElement.value !== "")
        queryString = inputElement.value;
      
      setTimeout(function() { // For IE 
        autoCompleteVar.sendQuery(queryString); 
      },0); 
    }
  };
}

