var AjaxApp = Class.create({
  initialize: function(options) {
    this.options = $H({
      baseUrl: '/xml',
      pageLoader: null
    }).update(options || {});

    this.requestnumber = Math.floor(Math.random() * 1000000); // 0 - 999999
    this.queue = $H();

    this.busy = 0; // Number of outstanding requests.
  },

  /**
   * Action is the action string and parameters object are send to the server. The options
   * contains JS options.
   *
   */
  enqueue: function(action, parameters, myoptions) {
    var options = $H({
      element: null,
      actionBefore: null,
      action: null,
      actionAfter: null
    }).update(myoptions || {});

    this.queue.set(++this.requestnumber, { action: action, parameters: parameters, options: options });
  },

  processQueue: function() {
    var queue = this.queue.clone();
    this.clearQueue();

    var parameters = [];
    queue.each(function(pair) {
      var func = pair.value.options.actionBefore;
      if(func!=null) {
        func($(pair.value.options.get('element')));
      }

      parameters[parameters.length] = { number: pair.key, action: pair.value.action, parameters: pair.value.parameters };
    }.bind(this));

    new Ajax.Request(this.options.get('baseUrl'), {
      method: 'post',
      parameters: { request: parameters.toJSON() },
      onLoading: this.ajaxOnLoading.bind(this),
      onComplete: this.ajaxOnComplete.bind(this),
      onSuccess: this.actionCallback.bind(this, queue)
    });
  },

  clearQueue: function() {
    this.queue = $H();
  },

  ajaxOnLoading: function() {
    this.busy++; 
    if (this.busy > 0 && this.options.get('pageLoader')) $(this.options.get('pageLoader')).show();
  },

  ajaxOnComplete: function() {
    this.busy--; 
    if (this.busy == 0 && this.options.get('pageLoader')) $(this.options.get('pageLoader')).hide();
  },

  actionCallback: function(queue, transport) {
    var errors = transport.responseJSON.errors;
    var responses = transport.responseJSON.response;

    var response;
    var responseNumber;
    var queuedItem;
    var element, actionFunc;
    var actions;

    for(var i=0,lenr=responses.length;i<lenr;++i) {
      response = responses[i];
      // responseNumber = response.number;

      queuedItem = queue.get(response.number);

      if (!Object.isUndefined(queuedItem)) {
        element = $(queuedItem.options.get('element'));
        actionFunc = queuedItem.options.get('action');

        actions = response.actions;

        for(var j=0,lena=actions.length;j<lena;++j) {
          switch(actions[j].actionType) {
            case 'content':
              if (!Object.isUndefined(element) && element!=null) {
                element.update(actions[j].content);
              }
              break;
            case 'value':
              if (actionFunc != null) {
                actionFunc(actions[j].value);
              }
              break;
            case 'script':
              // var func = actions[j].script;
              // func(element);
			  eval(actions[j].script);
              break;
			case 'debug':
			  var tmp = $('debug');
			  if (!Object.isElement(tmp)) {
			    var tmp = new Element('div', {'id': 'debug'});
				$$("body")[0].appendChild(tmp);
			  }
			  tmp.update(actions[j].content);
			  break;
            case 'property':
              element.writeAttribute(actions[j].property, actions[j].value);
              break;
            default:
              // alert('unknown ' + actions[j].actionType);
              break;
          }
        }

        var func = queuedItem.options.get('actionAfter');
        if(!Object.isUndefined(func) && func!=null) {
          func(element);
        }
      }
    }
  }
});
