/**
 * 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 (this.preFunction) this.preFunction();
  		if (this.cancelExecution) {
	    	this.cancelExecution = false;
	    	return ;
      	}
  new Ajax.Updater(ajaxupdateData.id,ajaxupdateData.href,{onComplete: ajaxupdateData.postFunction});
  }


});


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

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

  setOptions: function(options) {
    this.options = Object.extend({
      parameters: options.parameters || '',
      doPost: options.doPost || false,
      valueUpdateByName:  options.valueUpdateByName || false,
      eventType: options.eventType ? options.eventType : "click",
      parser: options.parser ? options.parser : new ResponseTextParser(),
      handler: options.handler ? options.handler : this.handler
    }, options || {});
  },

  setListeners: function() {
    eval("$(this.options.action).on"+this.options.eventType+" = this.execute.bindAsEventListener(this)");
  },

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

    // parse targets
    var targetList = this.options.target.split(',');

    var obj = this; // required because 'this' conflict with Ajax.Request
    var setFunc = this.setField;
    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, {targets: targetList, items: results});
      },
      onFailure: function(request) {
        if (obj.options.errorFunction != null) obj.options.errorFunction(request,obj.options.parser);
      },
      onComplete: function(request) {
        if (obj.options.postFunction != null) obj.options.postFunction();
      }
    });
  },

  handler: function(request, optionsArr) {
  // this points to options
    for (var i=0; i<optionsArr.targets.length && i<optionsArr.items.length; i++) {
   	var namedIndex = i;
   	
   	if (this.valueUpdateByName) {
    	for (var j=0; j <optionsArr.items.length; j++) {
    		if (optionsArr.targets[i]    ==  optionsArr.items[j][0]) {
    			namedIndex = j;
    		}
    	}
    }
    $(optionsArr.targets[i]).value = optionsArr.items[namedIndex][1];
    }
  }

});



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

  initialize: function(url, options) {
    this.url = url;
    this.setOptions(options);
    var old = window.onload;
    var obj = this;
    // bug FF 
    // execute later 
    window.onload = function ( ){
    	obj.run();
    	if (isFunction(old)) {
    	  old ();
    	}
    }
  },

  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 || {});
  },
  run: function(){
    if (!this.isRunning) {
      this.execute();
    }
  },
  execute: function(e) {
    if (this.options.preFunction != null) 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);
        var results = obj.options.parser.items; // array (id,value)
        obj.options.handler(results);
      },
      onFailure: function(request) {
        if (obj.options.errorFunction != null) obj.options.errorFunction();
        obj.isRunning = false;
      },
      onComplete: function(request) {
        if (obj.options.postFunction != null) obj.options.postFunction();
        obj.isRunning = false;
        obj.run();
      }
    });
  },

  handler: function( results) {
  // this points to options
    for (var i=0; i< results.length; i++) {
   	  var item = results[i];
   	  if (!this.plainText) { 
   	    $(item[0]).innerHTML = item[1]; 
   	  } else {
	  // nun tags lesen
	    var tagname =  $(item[0]).tagName.toLowerCase();
	    if (tagname == "input") {
	      var type = $(item[0]).type.toLowerCase();
	      
	      // 3 -- werte ? 
	      if (item[2]) {
	  	    if ($(item[0]).type.toLowerCase() == "text") {
	          $(item[0]).value = item[1];
	        } else 
	        if (type == "text" || type == "password") {
	          $(item[0]).value = item[1];
	        } else 
	        if (type == "checkbox" || type == "radio") {
	          $(item[0]).value = item[1];
	          $(item[0]).checked = item[2];
	        }
	      } else {
	        $(item[0]).value = item[1];
	      }
	    } else
	    { // textarea ...
	      $(item[0]).innerHTML = item[1]; // andere tags nur ueber innerhtml setzen
	    }
	    	
     }
    }
  }

});
/// 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();
    }
  },

  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() {
    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 (this.options.preFunction != null) 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 (obj.options.errorFunction != null) obj.options.errorFunction();
      },
      onComplete: function(request) {
        if (obj.options.postFunction != null) 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;
    }
  }

});




