﻿
/*
Base module requirements:
	Ext 3.0 loaded
	JQuery loaded
	MicrosoftAjax.js loaded
*/
Ext.ns("eKonx");
Ext.ns("eKonx.Runtime");
Ext.ns("eKonx.Debug");

eKonx.Debug =
{
	LogConsoleEnabled: false,
	CompressScripts: false
}

eKonx.CheckComponent = function(names, forceLoading)
{
	/// <summary>
	/// lazy load scripts
	/// </summary>
	/// <param name="names" type="String">
	/// list of components to load splitted by quotas
	/// </param>
	/// <param name="names" type="boolean">
	/// optional set to true to force load component without checks for exists
	/// </param>
	var namesArray = names.split(',');
	var result = false;
	//check for component exists
	var resultArray = [];
	var i = 0;
	$.ajaxSetup({ async: false });
	for (i = 0; i < namesArray.length; i++)
	{
		result = false;
		try
		{
			result = eval(namesArray[i]) != undefined;
		}
		catch (e) { }
		//component does not exists
		if (!result || forceLoading)
			resultArray.push(namesArray[i]);
		$.getScript(String.format('/JavaScript/GetScript?name={0}&compress={1}',
                namesArray[i],
                eKonx.Debug.CompressScripts));
	}
	/*
	$.getScript(String.format('/JavaScript/GetScript?name={0}&compress={1}',
                resultArray.join(","),
                eKonx.Debug.CompressScripts));
    */            
	$.ajaxSetup({ async: true });

	var errorMessage = "";
	for (i = 0; i < resultArray.length; i++)
	{
		result = false;
		try
		{
			result = eval(resultArray[i]) != undefined;
		}
		catch (e)
		{
			errorMessage = e.message + e.name;
		}
		if (!result) break;
	}

	if (!result)
	{
		Ext.Msg.show({
			icon: Ext.Msg.ERROR,
			msg: 'Unable to load component(s) - ' + names + " " + errorMessage,
			buttons: Ext.Msg.OK,
			title: 'Component loading'
		});
	}
	return result;
}

eKonx.MessageBox = function(header, message)
{
	Ext.Msg.minWidth = 200;
	Ext.Msg.alert(header, message);
};
eKonx.WrongAction = function(message)
{
	Ext.Msg.show(
			{
				title: 'Неверное действие',
				msg: message,
				buttons: Ext.Msg.OK,
				animEl: 'animEl',
				icon: Ext.MessageBox.WARNING
			});
};
eKonx.Error = function(message, header)
{
	if (!header) header = eKonx.Res.Global.Error;
	Ext.Msg.show(
			{
				title: header,
				msg: message,
				buttons: Ext.Msg.OK,
				animEl: 'animEl',
				icon: Ext.MessageBox.ERROR,
				width: 450
			});
};
eKonx.Confirm = function(message)
{
	return Ext.Msg.show(
	{
		title: 'Внимание!',
		msg: message,
		buttons: Ext.Msg.YESNOCANCEL,
		animEl: 'animEl',
		icon: Ext.MessageBox.QUESTION,
		width: 450
	});
}

eKonx.SubmitForm = function(formItem)
{
	debugger;
	if (!formItem) return;
	var form = null;
	while (form == null && formItem != null)
	{
		if (formItem.getForm)
			form = formItem.getForm();
		else
			formItem = formItem.ownerCt;
	};
	if ((form == null) || (!form.isValid()))
		return false;
	return eKonx.Ajax(form.url, form.getValues(), true);
}

eKonx.CheckForm = function(formPanel)
{
	var values =
		{
			ErrorMessages: [],
			IsValid: true
		};
	if (formPanel)
	{
		var frm=formPanel.getForm();
		values = frm.getValues();
		values.ErrorMessages = [];
		values.IsValid = frm.isValid();
		if (!values.IsValid)
		{
			frm.items.each(function(f)
			{
				if (!f.validate())
				{
					var ttl = formPanel.title;
					if (!ttl) ttl = "";
					else ttl += ": ";
					values.ErrorMessages.push(ttl + f.fieldLabel);
				}
			});
		}
	}
	return values;
}

/*
required following config:
{
	Forms: <array of forms>,
	SubmitUrl: <string url to submit>,
	Params: <submit params object>,
	OnSaved: <function after form submitted (will take response argument)>,
	OnCancel: <function after form submission cancelled by user during errors>,
	OnBeforeSubmit: <function 
}
events OnSaved, OnCancel gets a parameter with list of all saved values with properties:
IsValid
	reserved property contains true/false about form valid or not
SaveResult
	reserved property server response
*/
eKonx.SubmitForms = function(config)
{
	var allValues =
		{
			ErrorMessages: []
		};
	var temp = {};
	var isValid = true;
	for (var i = 0; i < config.Forms.length; i++)
	{
		temp = eKonx.CheckForm(config.Forms[i]);
		if (temp.IsValid === false) isValid = false;
		Array.addRange(temp.ErrorMessages, allValues.ErrorMessages);
		Ext.apply(allValues, temp);
	}
	if (!config.Params) config.Params = {};
	Ext.apply(allValues, config.Params);

	if (!isValid)
	{
		Ext.Msg.show({
			title: 'Сохранить?',
			msg:
				"Не заполнены (с ошибками) поля:<br/><br/>" +
				"<span style='color:red'>" +
				allValues.ErrorMessages.join("<br/>") + "<br/></span><br/>" +
				"Всё равно сохранить?",
			buttons: Ext.Msg.YESNO,
			minWidth: 400,
			fn: function(buttonId)
			{
				if (buttonId == 'yes')
				{
					allValues.ErrorMessages = "";
					if (config.OnBeforeSubmit)
					{
						allValues = config.OnBeforeSubmit(allValues) || allValues;
					}
					allValues.SaveResult = eKonx.Ajax(config.SubmitUrl, allValues, false);
					if (config.OnSaved) config.OnSaved(allValues);
				}
				else
				{
					if (config.OnCancel) config.OnCancel(allValues);
				}
			},
			icon: Ext.MessageBox.QUESTION
		});
	}
	else
	{
		allValues.ErrorMessages = "";
		if (config.OnBeforeSubmit)
		{
			allValues = config.OnBeforeSubmit(allValues) || allValues;
		};
		allValues.SaveResult = eKonx.Ajax(config.SubmitUrl, allValues, false);
		if (config.OnSaved) config.OnSaved(allValues);
	}
}

eKonx.Json = function(configOrUrl, params)
{
	if (!params) params = {};
	if (eKonx.Ajax(configOrUrl, params, true))
		return params.result;
	return false;
}
eKonx.Ajax = function(configOrUrl, params, isJSON)
{
	var config = {};
	if (typeof configOrUrl === typeof "")
	{
		config.url = configOrUrl;
		config.params = params;
	}
	else
		config = configOrUrl;
	config.async = false;
	var responseObj = null;
	Ext.lib.Ajax.on(
		{
			response: function(connection, response, callback, isAbort)
			{
				if (eKonx.Debug.LogConsoleEnabled)
					Ext.log(['response', response.responseText]);
				responseObj = response;
			},
			exception: function(connection, response, callback, isAbort)
			{
				if (eKonx.Debug.LogConsoleEnabled)
					Ext.log(['HTTPException', connection]);
			},
			abort: function()
			{
				if (eKonx.Debug.LogConsoleEnabled)
					Ext.log('Request was aborted');
			},
			timeout: function()
			{
				if (eKonx.Debug.LogConsoleEnabled)
					Ext.log('Request timed out');
			},
			readystatechange: function(connection)
			{
				if (eKonx.Debug.LogConsoleEnabled)
					Ext.log('readystatechange', connection.conn != null ? connection.conn.readyState : "");
			}
		});
	Ext.Ajax.request(config);
	var success = (responseObj == null ? false : responseObj.getResponseHeader("Success"));
	//null.d;
	if (success)
	{
		//WhatAFuck(success, isJSON, responseObj, config);
		var result = responseObj.responseText;
		//if (isJSON)
		try
		{
			result = Ext.decode(responseObj.responseText, true);
		}
		catch (e) { }

		config.result = result;
		if (typeof params == "undefined" || !params) params = {};
		params.result = result;
		if (result.message && result.message.length && result.message.length > 0)
		{
			var text = "";
			if (Ext.isArray(result.message))
			{
				for (var i = 0; i < result.message.length; i++)
					text += result.message + "<br/><br/>";
			}
			else
				text = result.message;
			eKonx.MessageBox("", result.message);
		}
		return true;
	}
	//error
	if (result && result.message)
		eKonx.Error(message);
	return false;
}

eKonx.GetColumnModel = function(url)
{
	var json = {};
	eKonx.Ajax(url, json, true);
	return json.result;
}

eKonx.GetAlertJSON = function(jsonObject, tab)
{
	var o, h = "";
	if (!tab) tab = "";
	for (o in jsonObject)
	{
		if (typeof jsonObject[o] == "function") continue;
		h += String.format("{0}{1}={2}\r\n", tab, o, jsonObject[o]);
		if (typeof jsonObject[o] == "object")
			h += eKonx.GetAlertJSON(jsonObject[o], tab + " ");
	}
	return h;
}

/// removeItemsByName: [ "Email", "Sex", ... ] to do not include this items
eKonx.ReplaceFormFieldArray = function(arrToReplace, idPrefix, onBeforeReplace, removeItemsByName)
{
	var onArrayItemClone = function(item, arrToReplace)
	{
		if (onBeforeReplace && (onBeforeReplace(item) === false)) return false;
		if (item.name)
		{
			if (removeItemsByName && (removeItemsByName.indexOf(item.name) >= 0)) return false;
			item.name = idPrefix + item.name;
		}
		if (item.hiddenName)
			item.hiddenName = idPrefix + item.hiddenName;

		if (item.items)
		{
			if (item.items.items)
				item.items.items = Array.deepClone(item.items.items, onArrayItemClone);
			else
				item.items = Array.deepClone(item.items, onArrayItemClone);
		}
	};
	return Array.deepClone(arrToReplace, onArrayItemClone);
}

Array.deepClone = function(arrayToClone, onItemClone)
{
	var result = [];
	for (var i = 0; i < arrayToClone.length; i++)
	{
		var item = Ext.apply({}, arrayToClone[i]);
		if ((onItemClone) && (onItemClone(item, arrayToClone) === false)) continue;
		result.push(item);
	}
	return result;
}

//split array into array of arrays
Array.asArrays = function(sourceArray, arrayCount)
{
	var result = [];
	if (sourceArray && sourceArray.length && arrayCount > 0)
	{
		var subArrSize=Math.floor(sourceArray.length/arrayCount);
		for (var i = 0; i < arrayCount; i++)
		{
			if (i + 1 == arrayCount)	//last execution
				result.push(sourceArray.slice(i * subArrSize, i * subArrSize + subArrSize*2));
			else
				result.push(sourceArray.slice(i * subArrSize, i * subArrSize + subArrSize));
		}
	}
	return result;
}

eKonx.GetAsColumnLayout = function(items, columnsCount)
{
	var result = [];
	if (!columnsCount) columnsCount = 2;
	if (items && items.length)
	{
		result = Array.asArrays(items, columnsCount);
		result.layout = 'column';
		result.border = false;
		var colWidth = 1 / columnsCount;
		for (var i = 0; i < columnsCount; i++)
		{
			var tmp = result[i];
			result[i] = {};
			result[i].items = tmp;
			result[i].columnWidth = colWidth;
			result[i].layout = 'form';
			result[i].border = false;
			result[i].defaults =
			{
				anchor: "98%"
			};
		}
	}
	else
		result = items;
	return result;
}

eKonx.ApplyConfigWithItems = function(receiverConfig, sourceConfig, idPrefix, shouldAppendItems)
{
	receiverConfig = receiverConfig || {};
	sourceConfig = sourceConfig || {};
	if (!idPrefix) idPrefix = "";
	if (sourceConfig.idPrefix) idPrefix = sourceConfig.idPrefix;

	var replacedTargetItems = [];
	if (receiverConfig.items)
		replacedTargetItems = eKonx.ReplaceFormFieldArray(
			receiverConfig.items,
			idPrefix,
			function(item)
			{
				if (!item) return;
				var founded = false;
				if (sourceConfig.removeItems)
				{
					Ext.each(
						sourceConfig.removeItems,
						function(itemToRemove)
						{
							founded = (itemToRemove && itemToRemove.name == item.name);
							if (founded) return false;
						});
				}
				//use only required fields
				if (sourceConfig.requiredOnly === true)
				{
					//if (item.name == "PriceForFieldset") WhatAFuck1.call(this, item);
					founded = !(item.allowBlank === false)
				}
				if (founded) return false;
			});

	if (sourceConfig.insertItems)
	{
		var insertItems = eKonx.ReplaceFormFieldArray(sourceConfig.insertItems, idPrefix);
		Array.addRange(insertItems, replacedTargetItems);
		replacedTargetItems = insertItems;
	}
	if (sourceConfig.appendItems)
	{
		var appendItems = eKonx.ReplaceFormFieldArray(sourceConfig.appendItems, idPrefix);
		Array.addRange(replacedTargetItems, appendItems);
	}

	if (shouldAppendItems)
	{
		var replacedSourceItems = [];
		if (sourceConfig.items)
			replacedSourceItems = eKonx.ReplaceFormFieldArray(sourceConfig.items, idPrefix);
		Array.addRange(replacedTargetItems, replacedSourceItems);
	}
	Ext.apply(receiverConfig, sourceConfig);
	receiverConfig.items = replacedTargetItems;

	//parsing column layout
	if (receiverConfig.layout == "column")
		receiverConfig.items = eKonx.GetAsColumnLayout(receiverConfig.items, 2);
	return receiverConfig;
}

eKonx.FillForm = function(form, jsonValues)
{
	//alert("form "+ form.id +" rendered: "+ form.rendered);
	for (var valName in jsonValues)
	{
		var field = form.findField(valName);
		//alert("field [" + valName + "] is " + field);
		if (field && field.setValue)
			field.setValue(jsonValues[valName]);
	}
}

Ext.override(Ext.form.ComboBox,
{
	setValue: function (v)
	{
		var text = v;
		if (this.valueField)
		{
			var r = this.findRecord(this.valueField, v);
			if (r)
			{
				text = r.data[this.displayField];
			} else if (Ext.isDefined(this.valueNotFoundText))
			{
				text = this.valueNotFoundText;
			}
		}
		this.lastSelectionText = text;
		if (this.hiddenField)
		{
			this.hiddenField.value = Ext.value(v, '');
		}
		Ext.form.ComboBox.superclass.setValue.call(this, text);
		this.value = v;
		this.fireEvent('change', this, v);
		return this;
	},
	setParent: function (combo, getDataFn)
	{
		var that = this;
		that.parentCombo = combo;
		var onChange = function (combo, v, old, isInitial)
		{
			if (v)
			{
				if (isInitial !== true)
				{
					that.clearValue();
				}
				this.store.proxy.data = getDataFn(combo, v);
				//this.store.loadData(getDataFn(combo, v), false);
				this.store.load();
				if (isInitial === true)
				{
					this.setValue(this.getValue());
				}
				//this.enable();
			}
		};
		onChange.call(that, combo, combo.getValue(), null, true);
		combo.on("change", onChange, that);
	}
});

Ext.override(Ext.Panel,
{
	disableFields: function ()
	{
		Ext.each(
			this.findBy(function (item) { return item != null && item.isFormField; }),
			function (cmp)
			{
				if (cmp.disable)
				{
					cmp.disable();
				}
			});
	},
	makeFieldsReadOnly: function ()
	{
		Ext.each(
			this.findBy(function (item) { return item != null && item.isFormField; }),
			function (cmp)
			{
				if (cmp.disable)
				{
					cmp.disable();
					if (cmp.disabled)
					{
						cmp.readOnly = true;
						if (this.el && this.el.dom)
						{
							this.el.dom.disabled = null;
						}
					}
				}
			});
	}
});

Ext.applyIf(Array.prototype,
{
	findByID: function(id)
	{
		var len = this.length;
		for (var from = 0; from < len; from++)
		{
			if (this[from].ID === id)
			{
				return this[from];
			}
		}
		return null;
	}
});

Ext.util.JSON.encodeDate = function(d)
{
	return d.format('"d/m/y"');
	//return d.format('M$')
	//return '"'+d.format('M$')+'"';
};

eKonx.ProcessMSDates = function(data)
{
	if (data)
	{
		do
		{
			if (Ext.isArray(data))
			{
				Ext.each(data, eKonx.ProcessMSDates);
				break;
			}
			if (Ext.isString(data) && data.indexOf("Date(") >= 0)
			{
				data = eKonx.ProcessMSDate(data);
				break;
			}
			if (Ext.isObject(data))
			{
				for (var i in data)
				{
					data[i] = eKonx.ProcessMSDates(data[i]);
				}
				break;
			}
		}
		while (false);
	}
	return data;
}

eKonx.ProcessMSDate = function(msDateString)
{
	return Date.parseDate(msDateString, 'M$');
}

