logBuffer.setErrorLevel(logBuffer.MSG_NOTICE | logBuffer.MSG_WARNING | logBuffer.MSG_ERROR | logBuffer.MSG_DEBUG);

function xFormErrorProcessorFilter(mode) {
  this.ns = xFormErrorProcessorFilter.getNS();
  this.mode = mode;
  this.enabled = true;
}
/* filter interface */
xFormErrorProcessorFilter.prototype.isEnabled = function() {
  return this.enabled;
};
xFormErrorProcessorFilter.PROCESSMARKED = 0;
xFormErrorProcessorFilter.PROCESSALL = 1;

xFormErrorProcessorFilter.prototype.getName = function() {
  return 'formServerErrorProcessor';
};
xFormErrorProcessorFilter.getNS = function() {
  return '';
};
xFormErrorProcessorFilter.prototype.process = function(element, logBuffer) {
  for (var iterator = new xFormElementIterator(element, xFormElementIterator.ITERATE_DESCENDANT);
           iterator.hasMore();
           iterator.nextElement()) {
    var item = iterator.getCurrent();
    var domNode = item.getElement();

    var tagName = domNode.tagName;
    if (tagName == 'INPUT' || tagName == 'TEXTAREA' || tagName == 'SELECT') {
      var serverErrors = $('.server', $(domNode).parent());

      if (serverErrors.length) {
        $(domNode).addClass('alarm');
        xform_setupError(domNode, 'server');

        if (!window.form.firstIsSet) {
          window.form.firstIsSet = true;

          domNode.focus();
        }
      }
    }
  }
};

//xFormParser.registerFormFilter(new xFormGUIDWriterFilter(),           xFormParser.filters.PREPROCESSOR,  'xfGUID');
xFormParser.registerFormFilter(new xFormErrorProcessorFilter(),       xFormParser.filters.PREPROCESSOR,  'xfErrorProcessor');
xFormParser.registerFormFilter(new xFormCheckerFilter(),              xFormParser.filters.PREPROCESSOR,  'xfChecker');
xFormParser.registerFormFilter(new xFormClearerFilter(),              xFormParser.filters.CLEAR,         'xfClearer');
xFormParser.registerFormFilter(new xFormReseterFilter(),              xFormParser.filters.RESET,         'xfReseter');
xFormParser.registerFormFilter(new xFormValidatorFilter(),            xFormParser.filters.POSTPROCESSOR, 'xfRestr');
/*
xFormParser.registerFormFilter(new xFormCleanerFilter('not changed'), xFormParser.filters.PREPROCESSOR |
                                                                      xFormParser.filters.POSTPROCESSOR, 'xfCleaner');
xFormParser.registerFormFilter(new xFormSplitterFilter(10, true),     xFormParser.filters.POSTPROCESSOR, 'xfTransform');
xFormParser.registerFormFilter(xFormSerializerFilter, xFormParser.filters.POSTPROCESSOR, 'xformsTransform');
*/
function xform_setupError(element) {
  if (1 == arguments.length ||
      (2 == arguments.length && 'server' == arguments[1])) {
    if ('server' == arguments[1]) {
      element.onfocus = xform_showServerErrorMessage;
    } else {
      element.onfocus = xform_showErrorMessage;
    }

    element.onblur = xform_hideErrorMessage;
    $(element).addClass('alarm');
  } else {
    element.onfocus = null;
    element.onblur = null;
    $(element).removeClass('alarm');
  }
}

function xform_showErrorMessage() {
  xform_showErrorMessageInternal(this, '.errorMessage');
}

function xform_showServerErrorMessage() {
  xform_showErrorMessageInternal(this, '.server');
}

function xform_hideErrorMessage(evt, type) {
  var popup = $('#formPopup');
  
  if (!type || type == popup.attr('type')) {
    popup.hide();
  }
}


function xform_showErrorMessageInternal(element, type) {
  var parent = $(element).parent();
  var offset = $(element).offset();
  var popup = $('#formPopup');
  var width = $(element).width();

  if (width < 170) {
    width = 170;
  }
  if (width > 300) {
    width = 300;
  }
  width -= 30;

  if (!type) {
    type = '.errorMessage';
  }

  popup.
    html($(type, parent).html()).
    show().
    css({position : 'absolute', width : width, left : offset.left + 5}).
    css({top : offset.top - 14 - popup.height()}).
    attr('type', type);
}

var x = new Date();
xFormParser.parse(document);
logBuffer.log(sprintf('Parsing done in %f sec.', (new Date() - x) / 1000));

var filtersCBArea = document.getElementById('filters');
for (var i = 0; i < xFormParser.filters.list.length; i++) {
  var filt   = xFormParser.filters.list[i].filter;
  var button = DOMUtl.createNode('input', {type : 'checkbox'});

  button.checked = true;
  button.filter = filt;
  button.onclick = new Function(
    'this.filter.enabled = !this.filter.enabled; ' +
    'log(sprintf("filter %s is now %s", this.filter.getName(), ' +
    'this.filter.isEnabled() ? "enabled" : "disabled"));' +
    'this.enabled = this.filter.isEnabled()');

  filtersCBArea.appendChild(button);
  filtersCBArea.appendChild(document.createTextNode(filt.getName()));
  filtersCBArea.appendChild(DOMUtl.createNode('br'));
}

function clone(elt) {
  var root;
  do {
    if (elt.xelement && 'group' == elt.xelement.getDataType()) {
      root = elt;
      break;
    }
  } while (elt = elt.parentNode);

  if (root) {
    var newroot = root.cloneNode(true);
    var mult    = newroot.getElementsByTagName('span')[1];
    mult.innerHTML = '[&#0150;]';
    mult.setAttribute('onclick', 'unclone(this);');
    mult.onclick = new Function('unclone(this);');

    xFormParser.onClone(root, newroot);
    DOMUtl.appendAfter(newroot, root);
  }
}

function unclone(elt) {
  DOMUtl.removeNode(elt.parentNode.parentNode);
}