var $cForm = function(id) { return core.form.options.storage[id] || null; };

var $cs = function(id, valueObj) {
	var strItem = core.form.options.storage[id];
	if (!strItem) { core.form.options.storage[id] = {id:id,value:valueObj}; } 
	else { strItem.value = valueObj; }
};

var $c = function(id, valueObj) {
	var obj = $(id);
	if (obj) {
		if (obj.hasClassName('cForm')) {
			var storedObj = core.form.options.storage[id];
			if (Object.isString(valueObj)) { core.form.updateCaption(id, valueObj); } 
			else { core.form.updateInput(id, valueObj); }
		} else {
			obj.value = valueObj;
			obj.fire('form:change', valueObj);
		}
	} else { $cs(id, valueObj); }
};

var $cF = function(id, key) {
	var storage = core.form.options.storage;
	if (storage[id]) {
		var retValue, inputObj = storage[id];
		if (!Object.isUndefined(inputObj[key])) {
			retValue = inputObj[key];
		} else {
			if (Object.isUndefined(key)) {
				retValue = inputObj ? inputObj.caption || inputObj.value : null;
			} else {
				retValue = inputObj ? (!Object.isString(inputObj.value)) ? inputObj.value[key] : key=='value' ? inputObj.value : null : null;
			}
		}
		return retValue;
	} else {
		return $(id) ? $F(id) : null;
	}
};

core.forms = Class.create({

	initialize: function(options) {
		var defOptions = { 
			mainForm : document.forms[0] || document.body,
			storage  : {},
			range 	 : []
		};
		this.options = Object.extend(defOptions, options || {});
		$(this.options.mainForm).select('div.cForm,ul.cForm').each(function(idx){this.observe(idx);}.bind(this));
	},
	
	observe: function(obj) {
		var rel = obj.readAttribute('rel');
		if (rel) {
			var relObj = rel.evalJSON();
			if (relObj) { this.options.storage[relObj.id] = relObj; }
		}
		var activeClass = obj.className.split(' ').first();
		
		switch (activeClass) {
			case 'inputBtn':
				obj.observe("mouseover",function(event){Event.element(event).addClassName('hover');})
				   .observe("mouseout",function(event){Event.element(event).removeClassName('hover');});
				
				//Clear Field
				var clearBtn = obj.next('a.inputClear');
				if (clearBtn) {
					clearBtn.observe("click",function(){
						var stObj = $cForm(this.previous('div.inputBtn').id);
						if (stObj) { core.form.clear(stObj.id); }
					});
				}
				
				//Callbacks
				if (relObj && relObj.click) { obj.observe("click", this[relObj.click.func].bind(this,relObj.click.params,relObj.id)); }
				if (relObj && relObj.change) { 
					obj.observe("form:change", relObj.change.func); 
					var editObj = $(obj.id+'-edit');
					if (editObj) {
						editObj.observe('change', relObj.change.func.curry({id:obj.id,obj:editObj}));
					}
				}
			break;
			case 'dropDown':
				ensure({js:"/js/core-dropdown.js"},function(){
					this.options.storage[relObj.id].control = new kUI.Dropdown(relObj);
				}.bind(this));
			break;
		}
	},
	
	onEnter:function(obj, func) {
		if ($(obj)) {
			$(obj).observe('keydown',function(event){
				if (event.keyCode==Event.KEY_RETURN) {
					event.stop();
					func();
				}
			});
		}
	},
	
	newWindow: function(options,inputID) {
		this.options.activeInput = inputID;
		var cFormWin = new top.kUI.Window(options);
	},
	
	fillInput: function(jsonObj) {
		if (jsonObj && (Object.keys(jsonObj).size()>0) && !this.options.activeInput.empty()) {
			var objID = this.options.activeInput, storedObj = this.options.storage[objID];
			if (storedObj) {
				var file_name = (storedObj.prefix ? storedObj.prefix : '') + jsonObj.file_name;
				var caption   = (storedObj.meta && storedObj.meta.caption) ? jsonObj[storedObj.meta.caption] : file_name;
				$c(objID,{
					caption:caption,
					file_id:jsonObj.file_id,
					file_name:file_name,
					media_id:jsonObj.media_id
				});
				if (storedObj.meta) {
					var wObj = $(storedObj.meta.width), 	hObj  = $(storedObj.meta.height);
					var dObj = $(storedObj.meta.duration), 	dsObj = $(storedObj.meta.duration_secs);
					if (wObj)  { wObj.value = jsonObj.meta.width 	|| ''; }
					if (hObj)  { hObj.value = jsonObj.meta.height 	|| ''; }
					if (dObj)  { dObj.value = jsonObj.meta.duration || ''; }
					if (dsObj) { dsObj.value = jsonObj.meta.duration_secs || ''; }
				}
			}
			this.options.activeInput = null;
		}
	},
	
	updateInput: function(id, valueObj) {
		var storedObj = this.options.storage[id], obj = $(id);
		if (valueObj &&  Object.keys(valueObj).size()>0) {
			var valObj = storedObj.value || {};
			Object.extend(valObj, valueObj);
			if (valueObj && valueObj.caption) {
				this.updateCaption(id, valueObj.caption);
			}
		}
	},
	
	updateCaption: function(id, valueObj) {
		var storedObj = this.options.storage[id], obj = $(id);
		if (Object.isString(valueObj)) {
			if (obj && obj.down('span')) { obj.down('span').update(valueObj); }
			storedObj.caption = valueObj;
			obj.writeAttribute("title", valueObj);
			if (obj.hasClassName('edit')) { $c(id+'-edit',valueObj); }
		}
	},
	
	clear: function(id) {
		var storedObj = this.options.storage[id];
		this.updateCaption(id, '');
		if (Object.isString(storedObj.value)) { storedObj.value = ''; }
		else {
			Object.keys(storedObj.value).each(function(key){ 
				storedObj.value[key] = null;
			});
			if (storedObj.meta) {
				Object.keys(storedObj.meta).each(function(key){ 
					if ($(storedObj.meta[key])) { $(storedObj.meta[key]).value = ''; }
				});
			}
		}
	},
	
	reset:function(elms){
		(Object.isArray(elms)?elms:[elms]).each(function(idx){ $(idx).value = ''; });
	},
	
	serialize: function() {
		var formValues = {}, Cnt;
		var formKeys = Object.keys(core.form.options.storage);
		for (i=0; i<formKeys.size(); i++) {
			var objStorage 	= core.form.options.storage[formKeys[i]];
			var objName 	= objStorage.name || objStorage.id;
			if (objStorage.callback && objStorage.callback.serialize) {
				objStorage.callback.serialize(formKeys[i]);
			}
			var valObj = objStorage.value;
			if (typeof(valObj)!='object') { formValues[objName] = valObj; } 
			else {
				var objKeys = Object.keys(valObj);
				for (ii=0; ii<objKeys.size(); ii++) {
					formValues[objName+'['+objKeys[ii]+']'] = valObj[objKeys[ii]];
				}
			}
		}
		return formValues;
	},
	
	store: function(options) {
		var storeObj = {};
		var keys = Object.keys(options);
		for (i=0; i<keys.size(); i++) {
			key = keys[i];
			storeObj[key]=(!Object.isString(options[key]))?options[key]:{id:key,value:options[key]};
		}
		Object.extend(this.options.storage, storeObj);
	},
	
	collect: function(options) {
		var defOptions = { validate:true };
		options = Object.extend(defOptions, options || {});
		if (options.validate) { if (!formValidateBool()) { return; }}
		options.parameters = $('mainForm').serialize(true);
		Object.extend(options.parameters, this.serialize());
		Object.extend(options.parameters, options);
		return options.parameters || {};
	},
	
	setRange: function(options) {
		if (options.parent && $(options.parent) && options.rule) {
			this.options.range = $(options.parent).select(options.rule);
			if (Prototype.Browser.IE) { $(options.parent).onselectstart = function(){return false;}; }
			else { $(options.parent).addClassName('noselect'); }
		}
	},
	clearRange:function(){ this.options.range = []; },
	resetRange:function(){ this.lastSelected = null; },
	toggleRange:function(classAction, className) { 
		if (this.options.range.size()>0) { 
			this.lastSelected = null;
			this.options.range.invoke(classAction,className);
		}
	},
	selectRange: function(event, obj, className) {
		if (event.shiftKey && this.lastSelected) {
			var action = obj.hasClassName(className) ? 'removeClassName' : 'addClassName',
				currentIndex = this.options.range.indexOf(obj),
            	lastIndex = this.options.range.indexOf(this.lastSelected);
	        for (var i=Math.min(currentIndex, lastIndex); i<=Math.max(currentIndex, lastIndex); i++) {
	          [this.options.range[i]].invoke(action, className);
	        }
		} else { obj.toggleClassName(className); }
		if (!this.lastSelected || this.lastSelected!=obj) { this.lastSelected = obj; }
	},
	
	submit: function(options) {
		if (!options || !options.url) { return; }
		var defOptions = {
			validate: 	true,
			func:		'submit',
			method:		'post',
			form:		'mainForm'
		};
		options = Object.extend(defOptions, options || {});

		//Validate non cForm form elements
		if (options.validate) { if (!formValidateBool()) { return; }}
		
        //Additional Code before ajax call
        if (options.onLoad) { var cont = options.onLoad(); if (!cont) { return; } }
        
		//Seriailze
		options.parameters = $('mainForm').serialize(true);
		options.parameters.func = options.func;
		Object.extend(options.parameters, this.serialize());
		
		var setAjax = new Ajax.Request(options.url, {
			parameters: Object.toQueryString(options.parameters),
			onComplete: function (req) {
				jsonObj = req.responseJSON;
				if (options.onComplete) { options.onComplete(jsonObj); } 
				else {
					if (options.close) {
						core.cancel({reload:options.reload,title:jsonObj.title,msg:jsonObj.alert,timer:jsonObj.timer});
					}
					if (jsonObj.alert) {
						core.alert({title:jsonObj.title||'',msg:jsonObj.alert,timer:jsonObj.timer||2500});
					}
				}
			}.bind(this),
			onFailure:function(){
				if (options.onFailure) { options.onFailure(); } 
			}.bind(this)
		});
	}
});

document.observe("dom:loaded", function() { core.form = new core.forms();	});