/*
 * Copyright Kitpages 2006
 * need prototype-1.5.0.js
 * need Base-1.0.2.js
 * eventually include : logger.js
 */

////
// using firebug console even if not installed
////
if (typeof (console) == "undefined") {
     var console = {
            debug: function() {},
            info: function() {},
            warning: function() {},
            error: function() {}
    };
}

////
// common functions
////
function is_array(variable) {
	var source = variable.toJSONString();
	return (source.search(/^\[([^,]*,)+[^,]*\]/) != -1);
};
////
// Package definition
////
var Kitpages = new Array();
Kitpages.util=new Array();
Kitpages.mvc=new Array();
Kitpages.widget=new Array();
Kitpages.custom=new Array();

//////
////
// MVC Définition
////
//////

////
// Model
////
Kitpages.mvc.BasicModel = Base.extend ({
	constructor: function(initValues) {
		//console.debug("init BasicModel initValue="+initValues.uiId);
		this.subInit(initValues);
	},

	subInit: function(initValues) {
		this.content = $H();
		this.ui = $(initValues.uiId);
		this.fromServiceUrl = initValues.fromServiceUrl;
		this.toServiceUrl = initValues.toServiceUrl;

		if (this.ui == undefined) {
			console.error("the id '"+initValues.uiId+"' given in the model is wrong");
		}
		this.ui.kitpagesModel = this;
	},

	////
	// standard methods
	////
	fromService: function(controller) {
		console.debug("fromService : call "+this.fromServiceUrl);
		if (this.fromServiceUrl != null) {
			var myAjax = new Ajax.Request(
				this.fromServiceUrl,
				{
					method: 'get',
					onFailure: this.fromServiceFailureCallback.bind(controller),
					onSuccess: this.fromServiceSuccessCallback.bind(controller)
				}
			);
		}
	},

	toService: function(controller) {
		console.debug("toService testString="+controller.testString);
		if (this.toServiceUrl != null) {
			this.fromUi();
			var myAjax = new Ajax.Request(
				this.toServiceUrl,
				{
					method: 'post',
					postBody: this.content.toQueryString(),
					onFailure: this.toServiceFailureCallback.bind(controller),
					onSuccess: this.toServiceSuccessCallback.bind(controller)
				}
			);
		}
	},

	fromUi: function() {
		// to be overriden
	},

	toUi: function() {
		// to be overriden
	},

	////
	// added methods
	////
	setContent: function(content) {
		this.content = content;
	},

	////
	// callback methods
	////
	fromServiceSuccessCallback: function(originalRequest) {
		console.debug("fromServiceSuccessCallback1");
		// get response
		var response = originalRequest.responseText.parseJSON();
		//console.debug("fromService : response "+this.fromServiceUrl+" txt="+originalRequest.responseText);
		if (!response) {
			console.error("wrong JSON response : "+originalRequest.responseText);
			this.onFromServiceFailure(originalRequest.responseText);
			return false;
		}
		// check code response
		if (response.code != "OK") {
			console.error("code != OK in response : "+originalRequest.responseText);
			this.onFromServiceFailure(originalRequest.responseText);
			return false;
		}
		// parse response content
		console.debug("fromServiceSuccessCallback2");
		if (response.content) {
			//console.debug("fromServiceSuccessCallback3");
			var json = response.content.parseJSON();
			if (json != false) {
				//console.debug("fromServiceSuccessCallback5 json="+json);
				this.model.content = $H(json);
				//console.debug("fromServiceSuccessCallback6");
			}
			else {
				//console.debug("fromServiceSuccessCallback7");
				this.model.content = $H();
				//console.debug("fromServiceSuccessCallback8");
			}
		}
		else {
			//console.debug("fromServiceSuccessCallback4");
			this.model.content = $H();
		}
		// update UI
		console.debug("before toUi");
		this.model.toUi();
		console.debug("after toUi");
		// fire success event
		this.onFromServiceSuccess(originalRequest.responseText);
	},

	fromServiceFailureCallback: function(originalRequest) {
		console.error("server does'nt respond on URL "+this.fromServiceUrl);
		this.onFromServiceFailure(originalRequest.responseText);
	},

	toServiceSuccessCallback: function(originalRequest) {
		var response = originalRequest.responseText.parseJSON();
		console.debug("JSON response : "+originalRequest.responseText);
		if (!response) {
			console.error("manageResponse, wrong JSON response : "+originalRequest.responseText);
			this.onToServiceFailure(originalRequest.responseText);
			return;
		}
		//console.debug("before onToServiceSuccess");
		//console.debug("toServiceSuccessCallback testString="+this.testString);
		this.onToServiceSuccess(originalRequest.responseText);
	},

	toServiceFailureCallback: function(originalRequest) {
		console.error("server doesn't respond on URL"+this.toServiceUrl);
		this.onToServiceFailure(originalRequest.responseText);
	}
});

/**
 * Class used for managing model of a form
 * Example :
var formModel = new Kitpages.mvc.FormModel({
	uiId:"myForm",
	fromServiceUrl:"http://toto.com/service/fillMyInfoForm",
	toServiceUrl:"http://toto.com/service/saveMyInfoForm"
});
formModel.fromService(); // initialize the model and send to UI

formModel.toService(); // get data from UI and send to service (for saving)
 */
Kitpages.mvc.FormModel = Kitpages.mvc.BasicModel.extend ({
	constructor: function(initValues) {
		//console.debug("init FormModel initValue="+initValues.uiId);
		this.base(initValues);
	},

	////
	// communication model<->ui
	////
	fromUi: function() {
		var elements = Form.getElements(this.ui);
		var content = {};
		elements.each(function(field) {
			if (field.name.indexOf("[]") != -1) {
				var optionList = field.getElementsByTagName("option");
				var tmpTable = [];
				for (i=0 ; i<optionList.length ; i++) {
					var option = optionList[i];
					if (option.selected) {
						tmpTable[tmpTable.length] = option.value;
					}
				}
				//console.debug("field.name="+field.name+" count tmpTable="+tmpTable.length);
				content[field.name] = tmpTable.toJSONString();
			}
			else {
				if (field.type == "checkbox") {
					if (field.checked) {
						content[field.name] = field.value;
					}
				}
				else {
					content[field.name] = field.value;
				}
			}
		});
		this.content = $H(content);
	},

	toUi: function() {
		var form=$(this.ui);
		var selectList = form.getElementsByTagName('select');
		//console.debug("form "+form.id+" toUi: count select="+selectList.length);
		for (i=0; i<selectList.length ; i++) {
			selectTag = selectList[i];
			if (undefined != this.content[selectTag.name]) {
				if (selectTag.name.indexOf("[]") != -1) {
					var tmpContent = this.content[selectTag.name].parseJSON();
				}
				else {
					var tmpContent = this.content[selectTag.name];
				}
				var valueArray = $A();
				if (is_array(tmpContent)) {
					valueArray = $A(tmpContent);
				}
				else {
					valueArray = $A([tmpContent]);
				}
				var optionList = selectTag.getElementsByTagName('option');
				for (j=0 ; j<optionList.length ; j++) {
					optionTag = optionList[j];
					if (valueArray.indexOf(optionTag.value) != -1) {
						optionTag.selected = true;
					}
					else {
						optionTag.selected = false;
					}
				}
			}
		}

		tagList = form.getElementsByTagName('input');
		//console.debug("form "+form.id+" toUi: count input="+tagList.length);
		for (i=0; i<tagList.length ; i++) {
			tag = tagList[i];
			if (undefined != this.content[tag.name]) {
				if ( (tag.type == "text") ||
					 (tag.type == "hidden") ) {
					tag.value = this.content[tag.name];
				}
				if (tag.type == "checkbox") {
					if (this.content[tag.name] == 1) {
						tag.checked = true;
					}
					else {
						tag.checked = false;
					}
				}
			}
		}

		tagList = form.getElementsByTagName('textarea');
		//console.debug("form "+form.id+" toUi: count textarea="+tagList.length);
		for (i=0; i<tagList.length ; i++) {
			tag = tagList[i];
			if (undefined != this.content[tag.name]) {
				new Insertion.Top(tag,this.content[tag.name]);
				if (tinyMCE) {
					tag.value = this.content[tag.name];
					tinyMCE.updateContent(tag.name);
				}
				//tag.appendChild(document.createTextNode(this.content[tag.name]));
			}
		}
	}
});

Kitpages.mvc.UploadModel = Kitpages.mvc.BasicModel.extend ({
	constructor: function(initValues) {
		//console.debug("init UploadModel initValue="+initValues.uiId);
		this.base(initValues);
		var uploadForm = this.ui;
		new Insertion.Top(uploadForm, '<iframe id="'+this.ui.id+'_uploadTarget" name="'+this.ui.id+'_uploadTarget" src="" style="width:0px;height:0px;border:0"></iframe>');
		new Insertion.Bottom(uploadForm, '<div id="'+this.ui.id+'_uploadProgressBar" style="display: none">Transfert en cours...</div>');
		var targetString = this.ui.id+"_uploadTarget";
		uploadForm.target = targetString;
		uploadForm.action = initValues.toServiceUrl;
	},

	////
	// standard methods
	////
	toService: function(controller) {
		var uploadForm = this.ui;
		$(this.ui.id+"_uploadProgressBar").show();
		var uploadTarget = $(this.ui.id+"_uploadTarget");
		Event.observe(uploadTarget, 'load', this.toServiceSuccessCallback.bind(controller), false);
		uploadForm.submit();
	},

	////
	// communication model<->ui
	////
	fromUi: function() {},

	toUi: function() {},

	////
	// callbacks
	////
	toServiceSuccessCallback: function(originalRequest) {
		var uploadTarget = $(this.model.ui.id+"_uploadTarget");
		$(this.model.ui.id+"_uploadProgressBar").hide();
		var txtResponse = Try.these (
			function() {
				var ret = uploadTarget.contentDocument.body.textContent;
				return ret;
			},
			function() {
				var ret = uploadTarget.contentWindow.document.body.innerText;
				return ret;
			},
			function() {
				var ret = uploadTarget.document.body.textContent;
				return ret;
			}
		);
		var response = txtResponse.parseJSON();
		if (!response) {
			console.error("manageResponse, wrong JSON response : "+txtResponse);
			this.onToServiceFailure(txtResponse);
			return;
		}
		this.onToServiceSuccess(txtResponse);
	}
});


////
// Controllers
////
Kitpages.mvc.Controller = Base.extend ({
	constructor: function(model, elementId, eventNameWithoutOn, onResultAction) {
		//console.debug("init Controller initValue="+elementId+" event="+eventNameWithoutOn);
		this.subInit(model, elementId, eventNameWithoutOn, onResultAction);
	},
	subInit: function(model, elementId, eventNameWithoutOn, onResultAction) {
		this.model = model;
		this.onResultAction = $H(onResultAction);
		this.eventElementId = elementId;
		model.fromService(this);
		// submit
		//console.debug("controller observe:"+elementId+" "+eventNameWithoutOn+" className="+this.className);
		Event.observe(elementId, eventNameWithoutOn, this._onControllerEvent.bind(this), false);
	},

	onToServiceFailure: function(responseText) {
		console.debug("onToServiceFailure, responseText="+responseText);
		new Insertion.Top("errorMessage",'<li>Problème technique</li>');
	},

	onFromServiceFailure: function(responseText) {
		new Insertion.Top("errorMessage",'<li>Problème technique</li>');
	},

	onFromServiceSuccess: function(responseText) {
		//console.debug("onFromServiceSuccess");
	},

	onToServiceSuccess: function(responseText) {
		console.debug("onToServiceSuccess, responseText="+responseText);
		var response = responseText.parseJSON();
		var action = this.onResultAction[response.code];
		if (undefined == action) {
			action = this.onResultAction["DEFAULT"];
			if (undefined == action) {
				new Insertion.Top("errorMessage",'<li>Erreur technique</li>');
				console.error("no action defined, and no DEFAULT action, responde.code="+response.code+";formId="+this.formDescription.id);
				return false;
			}
		}
		if (undefined != action.redirect) {
			//console.debug("redirection to:"+action.redirect);
			location.href = action.redirect;
		}
		if (undefined != action.errorCallback) {
			Element.update(action.errorCallback,"");
    		var errorList = $A(response.errorMessage);
    		errorList.each(function (error) {
    			new Insertion.Top("errorMessage",'<li>'+error+'</li>');
    		});
		}
		if (undefined != action.callback) {
			var callback = eval(action.callback);
			callback.apply(this,new Array(response, action.parameter));
		}
	},

	onControllerEvent: function() {
		return true;
	},

	_onControllerEvent: function() {
		if (this.onControllerEvent()) {
			var model = this.model;
			//console.debug("_onControllerEvent testString="+this.testString);
			model.toService.bind(model)(this);
		}
	}
});

Kitpages.mvc.FormController = Kitpages.mvc.Controller.extend({
	constructor: function(model, elementId, eventNameWithoutOn, onResultAction) {
		//console.debug("init Controller initValue="+elementId+" event="+eventNameWithoutOn);
		$(elementId).onsubmit = function() {return false;};
		this.base(model, elementId, eventNameWithoutOn, onResultAction);
	}
});

Kitpages.mvc.UploadController = Kitpages.mvc.Controller.extend({
	constructor: function(model, elementId, eventNameWithoutOn, onResultAction) {
		//console.debug("init Controller initValue="+elementId+" event="+eventNameWithoutOn);
		$(elementId).onsubmit = function() {return false;};
		this.base(model, elementId, eventNameWithoutOn, onResultAction);
	}
});

////
// progress bar management
////

Kitpages.util.progressBarManager = function(progressBarId) {
	var myGlobalHandlers = {
		onCreate: function () {
			$(progressBarId).show();
		},

		onComplete: function() {
			if (Ajax.activeRequestCount == 0) {
				$(progressBarId).hide();
			}
		}
	};
	Ajax.Responders.register(myGlobalHandlers);
	if (Ajax.activeRequestCount == 0) {
		$(progressBarId).hide();
	}
};

Event.observe(window, 'load', function() {Kitpages.util.progressBarManager("progressBar")}, false);
console.debug("Kitpages.js loaded");
