/**
 * Copyright 2005 Darren L. Spurgeon
 * Copyright 2007 Jens Kapitza
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
 
var AjaxJspTag = {
  Version: '1.3'
};

/**
 * AjaxTags
 */

AjaxJspTag.Base = function() {};
AjaxJspTag.Base.prototype = {

  resolveParameters: function() {
    // Strip URL of querystring and append it to parameters
    var qs = delimitQueryString(extractQueryString(this.url));
    if (this.options.parameters) {
      this.options.parameters += ',' + qs;
    } else {
      this.options.parameters = qs;
    }
    this.url = trimQueryString(this.url);
    
    if ((this.options.parameters.length > 0 ) && (this.options.parameters.charAt(this.options.parameters.length - 1) === ',')) {
      this.options.parameters = this.options.parameters.substr(0,this.options.parameters.length-1);
    }
  }

};

/**
 * Prefunction Invoke Ajax.Update TAG
 */
AjaxJspTag.PreFunctionUpdateInvoke = Class.create();
AjaxJspTag.PreFunctionUpdateInvoke.prototype = Object.extend(new AjaxJspTag.Base(), {

  initialize: function(ajaxupdateData) {
  this.preFunction = ajaxupdateData.preFunction;
  if (isFunction(this.preFunction))
  { 
  	this.preFunction();
  }
  if (this.cancelExecution) {
	    	this.cancelExecution = false;
	    	return ;
      	}
  var thisCall = new Ajax.Updater(ajaxupdateData.id,ajaxupdateData.href,{onComplete: ajaxupdateData.postFunction});
  }


});



/**
 * CALLBACK TAG
 */
AjaxJspTag.Callback = Class.create();
AjaxJspTag.Callback.prototype = Object.extend(new AjaxJspTag.Base(), {

  initialize: function(url, options) {
    this.url = url;
    this.setOptions(options); 
    this.errorCount = 0;
    addOnLoadEvent(this );
  },
  setOptions: function(options) {
    this.options = Object.extend({
      parameters: options.parameters || '',
      parser: options.parser ? options.parser : new ResponseCallBackXmlParser(),
      plainText: options.plainText ?   true : false ,
      handler: options.handler ? options.handler : this.handler
    }, options || {});
  },
  onload: function(){
  	this.run();
  },
  run: function(){
  // wenn fehler kommen den client veranlassen eben nicht mehr versuchen sich anzumelden
    if (!this.isRunning && this.errorCount < 100) {
      this.execute();
    }  
  },
  execute: function(e) {
    if (isFunction(this.options.preFunction)) { this.options.preFunction();}
	if (this.options.cancelExecution) {
	    this.cancelExecution = false;
	    return ;
      }
    // parse parameters and do replacements
    //var params = buildParameterString(this.options.parameters);

    // parse targets
    this.isRunning = true;
    var obj = this; // required because 'this' conflict with Ajax.Request
    var aj = new Ajax.Request(this.url, {
      asynchronous: true,
      method:  'post',
      evalScripts: true,
      onSuccess: function(request) {
        obj.options.parser.load(request);
        obj.options.list = obj.options.parser.items; 
        obj.errorCount = 0;
      
      },
      onFailure: function(request) {
        if (isFunction(obj.options.errorFunction)) {obj.options.errorFunction();}
        obj.isRunning = false;
        obj.errorCount++;
      },
      onComplete: function(request) {
      	// nun this.list kann mit der antwor alles gemacht werden was man will
        if (isFunction(obj.options.postFunction)) {obj.options.postFunction();}
        obj.isRunning = false;
        obj.run();
      }
    });
  }
});
/// callback -- ende





/**
 * SELECT TAG
 */
AjaxJspTag.Select = Class.create();
AjaxJspTag.Select.prototype = Object.extend(new AjaxJspTag.Base(), {

  initialize: function(url, options) {
    this.url = url;
    this.setOptions(options);
    this.setListeners();

    if (parseBoolean(this.options.executeOnLoad)) {
      this.execute();
    }
   addAjaxListener(this);
  },
  reload: function () {
    this.setListeners();
  },
  
  setOptions: function(options) {
    this.options = Object.extend({
      parameters: options.parameters || '',
      doPost: options.doPost || false,
      emptyOptionValue: options.emptyOptionValue || '',
      emptyOptionName:  options.emptyOptionName || '',
      eventType: options.eventType ? options.eventType : "change",
      parser: options.parser ? options.parser : new ResponseXmlParser(),
      handler: options.handler ? options.handler : this.handler
    }, options || {});
  },

  setListeners: function() {
  $(this.options.source).ajaxSelect = this; 
  
    Event.observe($(this.options.source),
      this.options.eventType,
      this.execute.bindAsEventListener(this),
      false);
    eval("$(this.options.source).on"+this.options.eventType+" = function(){return false;};");
  },

  execute: function(e) {
    if (isFunction(this.options.preFunction)) {this.options.preFunction();}
	if (this.options.cancelExecution) {
	    this.cancelExecution = false;
	    return ;
      }
    // parse parameters and do replacements
    var params = buildParameterString(this.options.parameters);

    var obj = this; // required because 'this' conflict with Ajax.Request
    var aj = new Ajax.Request(this.url, {
      asynchronous: true,
      method: obj.options.doPost ? 'post':'get',
      evalScripts: true,
      parameters: params,
      onSuccess: function(request) {
        obj.options.parser.load(request);
        var results = obj.options.parser.itemList;
        obj.options.handler(request, {target: obj.options.target,
                                      items: results });
      },
      onFailure: function(request) {
        if (isFunction(obj.options.errorFunction)){ obj.options.errorFunction();}
      },
      onComplete: function(request) {
        if (isFunction(obj.options.postFunction)) {obj.options.postFunction();}
      }
    });
  },

  handler: function(request, options) {
    // build an array of option values to be set as selected
    
    $(options.target).options.length = 0;
    $(options.target).disabled = false;
    for (var i=0; i<options.items.length; i++) {
      var newOption = new Option(options.items[i][0], options.items[i][1]);
      //$(options.target).options[i] = new Option(options.items[i][0], options.items[i][1]);
      // set the option as selected if it is in the default list
      if ( newOption.selected == false && options.items[i].length == 3 && parseBoolean(options.items[i][2]) ){
           newOption.selected = true;
      }
      $(options.target).options[i] = newOption;
    }
    
    
    if (options.items.length == 0)
    {
      $(options.target).options[i] = new Option(this.emptyOptionName, this.emptyOptionValue);
    	$(options.target).disabled = true;
    }
    // auch ein SELECT TAG ?
   	if ($(options.target).ajaxSelect && $(options.target).ajaxSelect.execute)
   	{
   		$(options.target).ajaxSelect.execute();
   	}
  }

});


/**
 * HTMLCONTENT TAG
 */
AjaxJspTag.HtmlContent = Class.create();
AjaxJspTag.HtmlContent.prototype = Object.extend(new AjaxJspTag.Base(), {

  initialize: function(url, options) {
    this.url = url;
    //alert(this.url);
    this.setOptions(options);
    this.setListeners();
    addAjaxListener(this);
    
  },
  reload: function(){
  	this.setListeners();
  },
  setOptions: function(options) {
    this.options = Object.extend({
      parameterName: options.parameterName ? options.parameterName : AJAX_DEFAULT_PARAMETER,
      parameters: options.parameters || '',
      doPost: options.doPost || false,
      
      preFunctionParameter:options.preFunctionParameter || null,
      errorFunctionParameter:  options.errorFunctionParameter || null,
      postFunctionParameter: options.postFunctionParameter || null,
      
      eventType: options.eventType ? options.eventType : "click",
      parser: options.parser ? options.parser : new ResponseHtmlParser(),
      handler: options.handler ? options.handler : this.handler
    }, options || {});
  },

  setListeners: function() {
    if (this.options.source) {
      eval("$(this.options.source).on"+this.options.eventType+" = this.execute.bindAsEventListener(this)");
    } else if (this.options.sourceClass) {
      var elementArray = document.getElementsByClassName(this.options.sourceClass);
      for (var i=0; i<elementArray.length; i++) {
        eval("elementArray[i].on"+this.options.eventType+" = this.execute.bindAsEventListener(this)");
      }
    }
  },

  execute: function(e) {
  	// CUSTOM BQ BEGIN
  	var forbiddenKeyCodes=",9,13,16,17,18,37,38,39,40,27,112,113,114,115,116,117,118,119,120,121,122,123,44,145,19,45,36,33,35,34,91,93,20,";
  	if(forbiddenKeyCodes.indexOf(","+e.keyCode+",")!=-1)return;
  	// CUSTOM BQ END

  	this.options.preFunctionParameters = evalJScriptParameters(  this.options.preFunctionParameter);
   
    if (isFunction(this.options.preFunction)) {this.options.preFunction();}
	if (this.options.cancelExecution) {
	    this.cancelExecution = false;
	    return ;
      }
    // replace default parameter with value/content of source element selected
    var ajaxParameters = this.options.parameters;
    if (this.options.sourceClass) {
      var re = new RegExp("(\\{"+this.options.parameterName+"\\})", 'g');
      var elem = Event.element(e);
      if (elem.type) {
        ajaxParameters = ajaxParameters.replace(re, $F(elem));
      } else {
        ajaxParameters = ajaxParameters.replace(re, elem.innerHTML);
      }
    }

    // parse parameters and do replacements
    var params = buildParameterString(ajaxParameters);

    var obj = this; // required because 'this' conflict with Ajax.Request
    var aj = new Ajax.Updater(this.options.target, this.url, {
      asynchronous: this.options.bqSync?true:false,
      method: obj.options.doPost ? 'post':'get',
      evalScripts: true,
      bqAjaxExec:this.options.bqAjaxExec,
      parameters: params,
      onFailure: function(request) {
        obj.options. errorFunctionParameters =  evalJScriptParameters(  obj.options.errorFunctionParameter  );
        if (isFunction(obj.options.errorFunction)) {obj.options.errorFunction();}
      },
      onComplete: function(request) {
        obj.options. postFunctionParameters =  evalJScriptParameters(   obj.options.postFunctionParameter);
        if (isFunction(obj.options.postFunction)) {obj.options.postFunction();}
      }
    });
  }

});


