var WREventUtils = {
    _fieldsValues: $H(),
    _focusedElement: null,
    _lastFocusedFields: {},

    saveFieldValue: function(field) {
        if ($(field).getAttribute("forcefocus") != "true") {
            this._fieldsValues.set(field, Form.Element.getValue(field));
        }
    },
    
    updateFocusedElement: function() {
        if (arguments[0]) {
            var field = Event.element(arguments[0]);
            this._focusedElement = field.id;
            if (field.form) {
                this._lastFocusedFields[field.form.id] = field.id;
            }
        } else {
            this._focusedElement = null;
        }
    },
    
    getFocusedElement: function() {
        return this._focusedElement;
    },
    
    getLastFocusedField: function(form) {
        form = $(form);
        return form ? $(this._lastFocusedFields[form.id]) : null;
    },
    
    forgetForm: function(form) {
        form = $(form);
        if (form) {
            delete(this._lastFocusedFields[form.id]);
        }
    },
    
    fieldValueChanged: function(field) {
        var storedValue = this._fieldsValues.get(field);
        var fieldValue = Form.Element.getValue(field);
        return storedValue != fieldValue;
    }
};

var WREvent = {
  e: null,
  page : null,
  link: null,
  otherOptions: null,
  
  observe: function (event){   
    options = $A(arguments);
    e = options[0];
    page = options[1];
    link = options[2];    
    otherOptions = options[3];
    
    var field = $(Event.element(event))
    var isField = field.tagName.toLowerCase() == "input" || field.tagName.toLowerCase() == "select" || field.tagName.toLowerCase() == "textarea"
  if (isField && WREventUtils.fieldValueChanged(field.id)) {
      if (event.type == 'focus') {
          if (field.id != fieldWithFocus) {
              WREvent.doEvent();
          }
          WREventUtils.updateFocusedElement(field.id)
      } else if (event.type == 'blur') {
          if (field.id == WREventUtils.getFocusedElement()) {
              WREventUtils.updateFocusedElement(null)
          }
          WREvent.doEvent();
      } else {
          WREventUtils.saveFieldValue(field.id);
          WREvent.doEvent();
      }
    }
  if (!isField) {
    WREvent.doEvent();
  }   
  },
                
  doEvent: function (){
    ajaxRequest(page + 'FormBean', $H({'sourcePage': page, 'isForm': true, 'pressedLink' : 'button#' + link}).merge(otherOptions))
  }
};

function RadioRequest(page,link,field,lastValue,otherOptions){
    ajaxRequest(page + 'FormBean', $H({'sourcePage': page, 'isForm': true, 'pressedLink' : 'button#' + link}).merge(otherOptions))
};

function CheckboxRequest(page,link,field,lastValue,otherOptions){
    ajaxRequest(page + 'FormBean', $H({'sourcePage': page, 'isForm': true, 'pressedLink' : 'button#' + link}).merge(otherOptions))
};

Form.Element.RadioEventObserver = Class.create(Abstract.EventObserver,{
   initialize: function(form, name, callback) {
    this.elements = Form.getInputs(form, 'radio', name);
    this.callback = callback;
    for (var i = 0; i < this.elements.length; i++) {
      this.registerCallback(this.elements[i]);
    }
  },
  
  onElementEvent: function(event) {
    var element = Event.element(event);

    this.callback(element, Form.Element.getValue(element)); 
  }
});


Form.Element.CheckboxEventObserver = Class.create(Abstract.EventObserver,{
  
  initialize: function(form, name, callback) {
    this.elements = Form.getInputs(form, 'checkbox', name);
    this.callback = callback;
    for (var i = 0; i < this.elements.length; i++) {
      this.registerCallback(this.elements[i]);
    }
  },
  
  onElementEvent: function(event) {
   var element = Event.element(event);

   this.callback(element, Form.Element.getValue(element)); 
  }
  
});