
//============================================================================================
AjaxBase = Class.create();
AjaxBase.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 || '',
      eventType: options.eventType ? options.eventType : "click",
      parser: options.parser ? options.parser : new ResponseTextParser(),
      handler: options.handler ? options.handler : this.handler
    }, options || {});
  },

  setListeners: function() {
	if (this.options.action != null) {
		eval("$(this.options.action).on"+this.options.eventType+" = this.execute.bindAsEventListener(this)");
    }
  },

  execute: function(e) {
    if (this.options.preFunction != null) this.options.preFunction();

    // parse parameters and do replacements
    if (this.options.parameters != null)
		var params = buildParameterString(this.options.parameters);

    // parse targets
    if (this.options.target != null)
		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: 'get',
      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);
      },
      onComplete: function(request) {
        if (obj.options.postFunction != null) obj.options.postFunction(request);
      }
    });
  },

  handler: function(request, options) {
    for (var i=0; i<options.targets.length && i<options.items.length; i++) {
      $(options.targets[i]).value = options.items[i][1];
    }
  }

});

//============================================================================================
/**
 * UPDATEFIELD TAG
 */
//============================================================================================
function buildParameter(parameterList,ajxForm,index) {
  var ajaxParameters = parameterList || '';
  var re = new RegExp("(\\{[^,&]*\\})", 'g'); // should retrieve each {} group
  var results = ajaxParameters.match(re);
  if (results != null) {
    for (var r=0; r<results.length; r++) {
      var nre = new RegExp(results[r], 'g');
      try {
		var fields = eval("ajxForm."+results[r].substring(1, results[r].length-1));
	  } catch (ex) {
	  	alert('Object :['+results[r].substring(1, results[r].length-1)+'] Error '+ex.message);
	  }
      var field = null;
      if (fields.length) {
		field = fields[index];
      } else {
		field = $(results[r].substring(1, results[r].length-1));
	  }
      ajaxParameters = replaceWithValue(ajaxParameters, nre, field);
    }
  }
  return ajaxParameters;
}
//============================================================================================
/**
 * UPDATEFIELD TAG
 */
//============================================================================================
AutoField = Class.create();
AutoField.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 || '',
      eventType: options.eventType ? options.eventType : "click",
      parser: options.parser ? options.parser : new ResponseTextParser(),
      handler: options.handler ? options.handler : this.handler
    }, options || {});
  },

  setListeners: function() {
	if (isString(this.options.action)) {
		eval("$(this.options.action).on"+this.options.eventType+" = this.execute.bindAsEventListener(this)");
	} else {
		eval("this.options.action.on"+this.options.eventType+" = this.execute.bindAsEventListener(this)");
	}
  },

  execute: function(e) {
    if (this.options.preFunction != null) this.options.preFunction();

    // parse parameters and do replacements
    var params = buildParameter(this.options.parameters,this.options.autoForm,this.parent.index);

    // 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: 'get',
      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);
      },
      onComplete: function(request) {
        if (obj.options.postFunction != null) obj.options.postFunction(request);
      }
    });
  },

  handler: function(request, options) {
    for (var i=0; i<options.targets.length && i<options.items.length; i++) {
      $(options.targets[i]).value = options.items[i][1];
    }
  }

});
//============================================================================================

function Setup_AutoField (inputSource, dataSourceUrl,urlParameter,updateForm,updateFields,updateEvent,progressElement,initFunct,updateFunct) {
	this.index = 0;
	this.showError = false;
	this.hasChange = null;

	updateEvent = "blur";

	var fUpdateForm;
	if (updateForm == null) {
		fUpdateForm = inputSource.form;
	} else {
		fUpdateForm = updateForm;
	}

	var saveSourceEvent = null;
	var objSource = null;

	if (isString(inputSource)) {
		eval("objSource = $(inputSource)");
		eval("saveSourceEvent = $(inputSource).on"+updateEvent);
	} else {
		objSource = inputSource;
		eval("saveSourceEvent = inputSource.on"+updateEvent);
	}

	var saveSourceValue = objSource.value;

	var upFieldlist = updateFields.replace(/ /g,"");

	if (inputSource.id == "") inputSource.id = inputSource.name;
	inputSource.isSourceField = true;

	objSource.hasChange = function () {
		return saveSourceValue != inputSource.value;
	}

	this.engine = new AutoField (dataSourceUrl,
		{parameters:urlParameter,
			action: inputSource,
			preFunction: function(request) {
				if (!objSource.hasChange()) return;
				objSource.value = trim(objSource.value);
				if (initFunct != undefined && initFunct != null) {
					initFunct(request);
				}
				if (progressElement != undefined) {
					Element.show(progressElement);
				}
			},
			postFunction: function(request) {
				if (!objSource.hasChange()) return;
				if (progressElement != undefined) {
					Effect.Fade(progressElement);
				}

				doUpdateField(request,inputSource,fUpdateForm,upFieldlist,parent.showError,parent.index);

				if (updateFunct != undefined && updateFunct != null) {
					updateFunct(request);
				}

				if (saveSourceEvent) {
					saveSourceEvent();
				}
			},
			source: inputSource.id,
			eventType : updateEvent,
			target: "null",
			autoForm : fUpdateForm}
	);

	this.engine.parent = this;
}
function TReturnValue() {
	this.hasError = false;
	this.Value = "";
}
//===================================================================================
function doUpdateField(request,inputSource,updateForm,updateFields,showError,index) {
	var rowSet;
	var rowMeta;
	var recSet;
	if (inputSource.value == "") {
		return;
	}

	var dataSet = new requestDataSet(request);
	dataSet.first();

	// Get Returnfield And ReturnValue
	var aUpdateFields=updateFields.split(",");
	var updateElement = new Array(aUpdateFields.length);
	var updateField = new Array(aUpdateFields.length);
	for (var i=0;i<aUpdateFields.length; i++) {
		var xField = aUpdateFields[i].split("=");
		if (xField.length > 1) {
			updateElement[i]=xField[0];
			updateField[i]=xField[1];
		} else {
			updateElement[i]=xField[0];
			updateField[i]=xField[0];
		}
	}

	// Assign ReturnValue to Returnfield;
	var alertError = false;
	for (var i=0;i<aUpdateFields.length; i++) {
		var updateValue = dataSet.valueByName(updateField[i]);

		var updateEl = null;
		try {
			if (!updateForm[updateElement[i]].tagName) { // Array Element
				var updateEls = updateForm[updateElement[i]];
				if ((updateEls[0].type == "radio") || (updateEls[0].type == "checkbox")) {
					updateEl = updateForm[updateElement[i]];
				} else {
					updateEl = updateEls[index];
				}
			} else {
				updateEl = updateForm[updateElement[i]];
			}
		} catch (ex) {
			alert("Object :["+updateElement[i]+"] Error "+ex.message);
		}

		if (!updateValue.hasError) {
			if (updateEl != null && updateEl != undefined) {
				if (updateEl.length && (!updateForm[updateElement[i]].tagName)) { //Array control or radio button
					if (updateEl[0].type == "radio") {
						for (var id=0; id < updateEl.length; id++) {
							var updateCtrl = updateEl[id];
							if (updateCtrl.value == updateValue.Value) {
								updateCtrl.checked = true;
								break;
							}
						}
					}

					if (updateEl[0].type == "checkbox") {
						for (var id=0; id < updateEl.length; id++) {
							var updateCtrl = updateEl[id];
							if (updateValue.Value.indexOf(updateCtrl.value) >= 0) {
								updateCtrl.checked = true;
								break;
							}
						}
					}

				} else {
					if (updateEl.type == "radio") {
						if (updateEl.value == updateValue.Value) {
							updateEl.checked = true;
						}
					} else if (updateEl.type == "checkbox") {
						if (updateValue.Value.indexOf(updateEl.value) >= 0) {
							updateEl.checked = true;
						}
					} else {
						updateEl.value = updateValue.Value;
					}
				}
			} else {
				var Message = "ไม่พบ Input Field : \""+updateElement[i]+"\"";
				if (iAlert) {
					iAlert(Message,inputSource);
				} else {
					alert(Message);
				try {
					inputSource.focus();
					inputSource.select();
				} catch (ex){}
				}
			}
		} else {
			if (!alertError && showError) {
				var Message = updateValue.Value;
				if (iAlert) {
					iAlert(Message,inputSource);
				} else {
					alert(Message);
					try {
						inputSource.focus();
						inputSource.select();
					} catch (ex){}
				}
				alertError = true;
			}
//			if ((updateEl.type == "hidden") || (updatEl.style.display.toLowerCase() == "none")){
//				updateEl.value = updateValue.Value;
//			} else {
				updateEl.value = "";
//			}
		}
	}

	// Execute onchange event for Returnfield if exist
	for (var i=0;i<aUpdateFields.length; i++) {
		var updateEl = null;
		if (!updateForm[updateElement[i]].tagName) { // Array Element
			var updateEls = updateForm[updateElement[i]];
			updateEl = updateEls[index];
		} else {
			updateEl = updateForm[updateElement[i]];
		}
		if (updateEl != null && updateEl != undefined) {
			if ((!updateEl.isSourceField) && !updateEl.disabled && updateEl.onchange != null) {
				updateEl.onchange(updateEl);
			}
		}
	}
}
//============================================================================================
function ajaxCall (callURL,beforeCall,afterCall) {
	this.callURL = callURL;
	this.ajaxEngine = new AjaxBase (this.callURL,
			{parameters:null,
			action: null,
			preFunction: beforeCall,
			postFunction: afterCall,
			source: null,
			target: null}
		);

	this.beforeCall = beforeCall;
	this.afterCall = afterCall;
	this.execute = function (callParams) {
		this.ajaxEngine.url = callURL+"?"+callParams+"&rx="+(Math.random());
		this.ajaxEngine.execute();
	}
}

//===================================================================================
// dataSet Object for Ajax														   ||
//===================================================================================
ajaxDataSet = function (request) {

	//==============================================================================
	this.rowString = function () {
		return rowSet[rowIdx];
	}

	//==============================================================================
	this.recNo = function() {
		return rowIdx;
	}

	//==============================================================================
	this.next = function() {
		if (rowIdx+1 < rowSet.length) {
			rowIdx++;
			recSet = rowSet[rowIdx].split("!");
			return true;
		} else {
			return false;
		}
	}

	//==============================================================================
	this.rowCount = function () {
		return rowSet.length-1;
	}
	//==============================================================================
	this.goto = function(recno) {
		if ((recno > 0) && (recno < rowSet.length)) {
			rowIdx = recno;
			recSet = rowSet[rowIdx].split("!");
			return true;
		} else if (recno == -1) {
			recSet = emptyRec;
			return true;
		} else { return false;}
	}

	//==============================================================================
	this.last = function() {
		rowIdx = rowSet.length-1;
		if (rowIdx > 0) {
			recSet = rowSet[rowIdx].split("!");
			return true;
		} else {
			return false;
		}
	}

	//==============================================================================
	this.first = function() {
		rowIdx = 1;
		if (rowIdx < rowSet.length) {
			recSet = rowSet[rowIdx].split("!");
			return true;
		} else {
			return false;
		}
	}

	//==============================================================================
	this.beforeFirst = function() {
		rowIdx = 0;
		recSet = [];
		return rowIdx < rowSet.length;
	}

	//==============================================================================
	this.prior = function() {
		if (rowIdx-1 >0) {
			rowIdx--;
			recSet = rowSet[rowIdx].split("!");
			return true;
		} else {
			return false;
		}
	}

	//==============================================================================
	this.valueByName = function (FieldName) {
		var retValue = new TReturnValue();

		retValue.hasError = true;
		retValue.Value =  "";

		if (rowMeta[0] == "") {
			retValue.hasError = true;
			retValue.Value =  "*** รูปแบบ dataSource ไม่ถูกต้อง ***";
		}

		if (recSet.length == 0) {
			retValue.hasError = true;
			retValue.Value = "";
		}

		var fieldIdx = -1;
		for (var i=0; i < rowMeta.length; i++) {
			if (rowMeta[i] == FieldName) {
				fieldIdx = i;
				break;
			}
		}

		if (fieldIdx == -1) {
			retValue.hasError = true;
			retValue.Value =  "*** ไม่ปรากฏ Field : "+FieldName+" ***";
		}

		if (rowSet.length > 1) {
			retValue.hasError = false;
			retValue.Value = recSet[fieldIdx];
		}

		return retValue;
	}

	//==============================================================================
	this.updateForm = function(rowID,workForm,filedList) {

		var saveRecno = this.recNo();
		var upFieldlist = filedList.replace(/ /g,"");
		if (this.goto(rowID)) {
			// Get Returnfield And ReturnValue
			var aUpdateFields=upFieldlist.split(",");
			var updateElement = new Array(aUpdateFields.length);
			var updateField = new Array(aUpdateFields.length);

			for (var i=0;i<aUpdateFields.length; i++) {
				var xField = aUpdateFields[i].split("=");
				updateElement[i]=xField[0];
				updateField[i]=xField[1];
			}

			// Assign ReturnValue to Returnfield;
			var alertError = false;
			for (var i=0;i<aUpdateFields.length; i++) {
				var updateValue = this.valueByName(updateField[i]);
				var updateEl = workForm[updateElement[i]];
				try {
					updateEl.value = updateValue.Value;
				} catch (ex) {
				}
			}

			// Execute onchange event for Returnfield if exist
			for (var i=0;i<aUpdateFields.length; i++) {
				var updateEl = workForm[updateElement[i]];
				if (updateEl != null && updateEl != undefined) {
					if (updateEl.onchange != null) {
						updateEl.onchange(updateEl);
					}
				}
			}
		}

		this.goto(saveRecno);
	}
	//==============================================================================
	// initialization ==
	//==============================================================================

	var rowSet;
	var recSet = [];
	var rowIdx = 0;
	var rowMeta;
	rowSet = request.responseText.split("\r\n"); //แปลงเป็น ARRAY โดยใช้รหัสขึ้นบันทัดใหม่
	for(var i=0; i < rowSet.length; i++) {
		var rowdata = rowSet[i].replace(/@#/g,"\r\n");
		rowSet[i] = rowdata;
	}

	rowMeta = rowSet[0].split("!");
	var emptyRec = rowSet[0].split("!");

	for (var idx=0;idx < emptyRec.length; idx++) {
		emptyRec[idx] = "";
	}

	if (rowSet[rowSet.length-1] == "") {
		rowSet.length = rowSet.length-1;
	}

	this.beforeFirst();
}
