/**
 * Check the length of a text field against a maximum.
 * @param {Object} input
 * @param {Object} notice
 * @param {Object} maxLength
 */
function checkMaxLength(input, notice, maxLength)
{
  var length = input.value.length;
  var charsLeft = maxLength - length;
  if(charsLeft < 0) {
    charsLeft = 0;
    input.value = input.value.substr(0, maxLength);
  }
  var msg = charsLeft + ' character';
  if(charsLeft != 1) msg += 's';
  msg += ' left'
  notice.update(msg);
}

/**
 * Initialise search box.
 * @param {Object} element
 * @param {Object} text
 */
function initSearchBox(element, text)
{
	element.value = text;
	element.onclick = function() {clearSearchBox(this)}
	element.addClassName('grey-text');
}

/**
 * Clear search box.
 * @param {Object} element
 */
function clearSearchBox(element)
{
	element.value = '';
	element.onclick = '';
	element.removeClassName('grey-text');
}

/**
 * Highlight the given block holder.
 * @param {Object} blockHolderId
 */
function highlightBlockHolder(blockHolderId)
{
  if($(blockHolderId)) Effect.Shake(blockHolderId);
}

/**
 * Highlight the given block.
 * Give the option of searching the DOM if an initial match can't be found.
 * @param {Object} blockId
 * @param {Object} searchDom
 */
function highlightBlock(blockId, searchDom)
{
  if($(blockId)) {
    Effect.Shake(blockId);
  } else if(searchDom) {
    var match = blockId.match(/^block_(\d+)$/);
    var blockId = match[1];
    var blockHolders = $$('div.block-holder');
    for(var i = 0; i < blockHolders.length; i++) {
      var blockHolder = blockHolders[i];
      var match = blockHolder.id.match(/^block_holder_(\d+)$/);
      var blockHolderId = match[1];
      var newBlockId = 'block_' + blockHolderId + '_' + blockId;
      if($(newBlockId)) {
        Effect.Shake(newBlockId);
      }
    }
  }
}

/**
 * Activate blocks when in control panel.
 */
function activateBlocks()
{
  var blocks = $$('.block');
  
  for(var i = 0; i < blocks.length; i++) {        
    blocks[i].observe('mouseover', function(event) {
      var block = Event.element(event);
      if(!block.hasClassName('block')) {
        block = block.up('.block'); 
      }
      block.setStyle({
        outline: '1px solid #666'
      });
      block.down('.block-body').setStyle({        
        opacity: 0.5
      });
      block.down('.block-helper').show();
    });
    
    blocks[i].observe('mouseout', function(event) {
      var block = Event.element(event);
      if(!block.hasClassName('block')) {
        block = block.up('.block'); 
      }
      block.setStyle({
        outline: 'none'
      });
      block.down('.block-body').setStyle({
        opacity: 1.0
      });
      block.down('.block-helper').hide();
    });
  }
}

/**
 * Reset form-template form.
 * @param {Object} formTemplateId
 */
function resetForm(formTemplateId)
{
  var formId = 'form_' + formTemplateId;
  var form = $(formId);
  var messages = $$('#' + formId + ' .form-msg');
  for(var i = 0; i < messages.length; i++) {
    messages[i].hide();
  }
  form.reset();
}

/**
 * Perform client-side validation on form-template form.
 * @param {Object} formTemplateId
 */
function validateForm(formTemplateId)
{
  // Assume the form is valid.
  var isValid = true;
  // Get the form items.
  var formId = 'form_' + formTemplateId;
  var formItems = $$('#' + formId + ' .form-item');
    
  // Check each form item.
  for(var i = 0; i < formItems.length; i++) {
    // The item and child fields.
    var item = formItems[i];
    var field = item.down('.form-field');
    var fields = item.select('.form-field');
    
    // The message box.
    var msgBox = item.down('.form-msg');
    // If there's no message box, create one.
    if(!msgBox) {
      var label = item.down('label');
      var msgBox = document.createElement('span');
      Element.extend(msgBox);
      msgBox.addClassName('form-msg');
      label.insert(msgBox);
    }
    
    // Init error message.
    var msg = '';

    // Do we have one or more form fields?
    for(var j = 0; j < fields.length; j++) {
      var field = fields[j];
      // Get the value, and init message.
      var value = $F(field);
            
      // Check required fields.
      if(item.hasClassName('required')) {
        if(value == '') msg = 'is required';
      }
      // Check numeric fields.
      if(msg == '') {
        if(item.hasClassName('numeric')) {
          if(!value.match(/^\d*$/)) msg = 'is not a number'; 
        }
      }
      // Check decimal fields.
      if(msg == '') {
        if(item.hasClassName('decimal')) {
          if(!value.match(/^[\d\.]*$/)) msg = 'is not a number'; 
        }
      }
      // Check currency fields.
      if(msg == '') {
        if(item.hasClassName('currency')) {
          if(!value.match(/^[\$\d\.]*$/)) msg = 'is not a number'; 
        }
      }
      // Check phone fields.
      if(msg == '') {
        if(item.hasClassName('phone')) {
          if(value != '' && !value.match(/^[0-9+ ()]+$/)) msg = 'is not valid'; 
        }
      }
      // Check email fields.
      if(msg == '') {
        if(item.hasClassName('email')) {
          if(value != '' && !value.match(/^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/)) {
            msg = 'is not a valid email'; 
          }
        }
      }
      // Check time fields.
      if(msg == '') {
        if(item.hasClassName('time')) {
          if(value != 'AM' && value != 'PM' && !value.match(/^[\d:.]*$/)) msg = 'is not valid'; 
        }
      }
      
      // No error message means everything's OK.
      if(msg == '') {
        msgBox.update('');
        msgBox.hide();
      } else {
        // Otherwise, show error message.
        msgBox.update(msg);
        msgBox.show();
        // Mark form as invalid.
        isValid = false;
      }
    }
  }
  
  // Warn user if invalid.
  if(!isValid) {
    alert("There was a problem with your submission.\nPlease review the form.");
  }
  
  return isValid;
}

/**
 * Return to form-template form from thank-you message.
 * @param {Object} formTemplateId
 */
function returnToForm(formTemplateId)
{
  $('form_thanks_' + formTemplateId).hide();
  $('form_fields_' + formTemplateId).show();
  resetForm(formTemplateId);
}

/**
 * String helpers.
 */
var StringUtils = {
  /**
   * Convert number to currency.
   * @param {Object} number
   * @param {Object} options
   */
  numberToCurrency : function(number, options) {
    try {
      var options = options || {};
      var precision = options['precision'] || 2;
      var unit = options['unit'] || '$';
      var separator = precision > 0 ? options['separator'] || '.' : '';
      var delimiter = options['delimiter'] || ',';    
      var parts = parseFloat(number).toFixed(precision).split('.');
      return unit + this.numberWithDelimiter(parts[0], delimiter) + separator + parts[1].toString();
    } catch(e) {
      return number
    }  
  },
  
  /**
   * Add delimiters to number.
   * @param {Object} number
   * @param {Object} delimeter
   * @param {Object} separator
   */
  numberWithDelimiter : function(number, delimiter, separator) {
    try {
      var delimiter = delimiter || ',';
      var separator = separator || '.';    
      var parts = number.toString().split('.');
      parts[0] = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + delimiter);
      return parts.join(separator);
    } catch(e) {
      return number;
    }
  }
}
