﻿/// <reference name="MicrosoftAjax.js"/>
Type.registerNamespace("Ngn.Utils");
Ngn.Utils = {
	re: {
		Guid: /(^[\da-f]{8}\-[\da-f]{4}\-[\da-f]{4}\-[\da-f]{4}\-[\da-f]{12}$)/i
	},
	GetHeight: function(baseH) {
		var wh = jQuery(window).height() - 30;
		if (!baseH || baseH > wh)
			return wh;
		else
			return baseH;
	},
	GetWidth: function(baseW) {
		var ww = jQuery(window).width() - 20;
		if (!baseW || baseW > ww)
			return ww;
		else
			return baseW;
	},
	ShowError: function(sender, args) {
		alert(args.message); //String.format("{0}\nОшибка: {1}", args.message, args.name));
	},
	EmptyGuid: "00000000-0000-0000-0000-000000000000",
	IsGuid: function(s) {
		return this.re.Guid.test(s);
	},
	GetGuid: function(ref, df) {
		var id = (ref == null) ? null : (typeof (ref) == 'string') ? ref : (ref.data) ? (ref.data.ID || ref.data.id) : (ref.ID || ref.id);
		return Ngn.Utils.IsGuid(id) ? id : df;
	},
	dataFilter: function(data, type) {
		if (type == "json") {
			this.dataTypes = ['json'];
			data = Ngn.Utils.deserializeJson(data);
		}
		return data;
	},
	typedMerge: function() {
		var n, r, s = {}, df = arguments[arguments.length - 1];
		for (var i = 0, l = arguments.length - 1; i < l; i++) {
			if (null == (r = arguments[i]))
				continue;
			for (n in r) {
				if (s[n] == undefined || (df[n] != undefined && typeof (s[n]) != typeof (df[n])))
					s[n] = r[n];
			}
		}
		for (n in df) {
			if (typeof (s[n]) != typeof (df[n]))
				s[n] = df[n];
		}
		return s;
	},
	mergePrototype: function(A) {
		if (A.prototype && typeof (A.prototype) == "object") {
			for (var i = 1, l = arguments.length; i < l; i++) {
				var B = arguments[i];
				if (B && B.prototype && typeof (B.prototype) == "object") {
					for (var n in B.prototype) {
						if (!A.prototype[n])
							A.prototype[n] = B.prototype[n];
					}
				}
			}
		}
	},
	isArray: function(instance) { return (Object.getTypeName(instance) == "Array"); },
	deserializeJson: function(str, supressError) {
		var rs = Sys.Serialization.JavaScriptSerializer.deserialize(str);
		if (rs == null || rs.__ResultIsNull === true)
			return null;
		else if (rs.__ResultIsException === true) {
			var e = Error.create(rs.Message, { name: rs.Type, server: true });
			if (!supressError)
				throw e;
			else
				return e;
		} else
			return rs;
	},
	getJson: function(executor) {
		var statusCode = executor.get_statusCode(), rs;
		if ((statusCode >= 200 && statusCode < 300) || statusCode === 304 || statusCode === 1223) {
			if (statusCode !== 204 && statusCode !== 304 && statusCode !== 1223) {
				var contentType = executor.getResponseHeader('Content-Type');
				if ((contentType) && (contentType.indexOf('application/json') !== -1)) {
					return Ngn.Utils.deserializeJson(executor.get_responseData());
				}
				else
					throw Error.create("Неверный тип ответа сервера.", { name: "InvalidContentTypeException", executor: executor });
			} else
				throw Error.create("Неверный ответ сервера.", { name: "InvalidResponseException", executor: executor });
		}
		else {
			throw Error.create("Неверный запрос.", { name: "InvalidRequestException", executor: executor });
		}
	},
	createJsonRequest: function(url, onSuccess, onFailure) {
		var wRequest = new Sys.Net.WebRequest(), h = wRequest.get_headers();
		wRequest.set_url(url);
		wRequest.set_httpVerb("POST");
		h["Accept"] = "application/json";
		h["Content-Type"] = "application/json";
		wRequest.add_completed(function(executor) {
			var result = null;
			try {
				var result = Ngn.Utils.getJson(executor);
			}
			catch (e) {
				if (onFailure)
					onFailure(executor, e);
				else
					Ngn.Utils.ShowError(executor, e);
				return;
			}
			if (onSuccess) {
				onSuccess(result);
			}
		});
		return wRequest;
	},
	createHtmlRequest: function(url, onSuccess, onFailure) {
		var wRequest = new Sys.Net.WebRequest();
		wRequest.set_url(url);
		//wRequest.set_httpVerb("POST");

		//wRequest.get_headers()["Accept"] = "application/json";
		wRequest.add_completed(function(executor) {
			var result = null;
			var statusCode = executor.get_statusCode();
			try {
				if ((statusCode >= 200 && statusCode < 300) || statusCode === 304 || statusCode === 1223) {
					if (statusCode !== 204 && statusCode !== 304 && statusCode !== 1223) {
						result = executor.get_responseData();
						if (onSuccess) {
							onSuccess(result);
						}
					} else
						throw Error.create("Неверный ответ сервера.", { name: "InvalidResponseException", executor: executor });
				}
				else {
					throw Error.create("Неверный запрос.", { name: "InvalidRequestException", executor: executor });
				}
			}
			catch (e) {
				if (onFailure)
					onFailure(executor, e);
				return;
			}
		});
		return wRequest;
	},
	createUrl: function(url, data) {
		if (!data) {
			return url;
		}
		var qs = Ngn.Utils.createQueryString(data);
		if (qs.length > 0) {
			var sep = '?';
			if (url && url.indexOf('?') !== -1)
				sep = '&';
			return url + sep + qs;
		} else {
			return url;
		}
	},
	createQueryString: function(data) {
		var a = [];
		for (var arg in data) {
			if (data[arg] != null)
				a.push(String.format("{0:C}={1:C}", arg, data[arg].toString()));
		}
		return a.join("&");
	},
	pager: function(total, index, path, maxItems) {
		var start = 0, end = total - 1, maxIndex = total - 1;
		
		if (maxIndex > 0) {
			var shift = Math.floor(maxItems / 2);
			start = (index > shift) ? index - shift : 0;
			end = index + shift;
			if (end >= maxIndex)
				end = maxIndex;
		}
		
		var sb = new Sys.StringBuilder("<div class=\"pager\"><ul class=\"pagination-list clearfix\">");

		if (index > 0) {
			sb.appendFormat("<li class=\"navigate-previous\"><a href=\"{1}\" class=\"previous\">{0}</a></li>",
							"Предыдущая",
							String.format(path, index - 1));
		} else {
			sb.appendFormat("<li class=\"navigate-previous inactive\">{0}</li>",
							"Предыдущая");
		}
		

		if (start > 0) {
			sb.appendFormat("<li><a href=\"{0}\">1</a></li>", String.format(path, 0));
			if (start > 1)
				sb.append("<li class=\"inactive\">...</li>");
		}
		for (; start <= end; start++) {
			if (start != index)
				sb.appendFormat("<li><a href=\"{1}\">{0}</a></li>", start + 1, String.format(path, start));
			else
				sb.appendFormat("<li class=\"current\">{0}</li>", start + 1);
		}
		if (end < maxIndex) {
			if (end < maxIndex - 1)
				sb.append("<li class=\"inactive\">...</li>");
			sb.appendFormat("<li><a href=\"{1}\">{0}</a></li>", total, String.format(path, maxIndex));
		}
		
		if (index < maxIndex) {
			sb.appendFormat("<li class=\"navigate-next\"><a href=\"{1}\" class=\"next\">{0}</a></li>",
				"Следующая",
				String.format(path, index + 1));
		} else {
			sb.appendFormat("<li class=\"navigate-next inactive\">{0}</li>",
				"Следующая");
		}
		
		sb.append("</ul></div>");
		return sb.toString();
	},
	delegate: function(instance, method, delay) {
		if (delay && delay > 0)
			return function() {
				var a = arguments;
				setTimeout(function() {
					method.apply(instance, a);
				}, delay);
			};
		else
			return function() {
				method.apply(instance, arguments);
			};
	}
};
Sys.StringBuilder.prototype.appendFormat = function() {
	this.append(String.format.apply(null, arguments));
};
(function() {
	var reAmp = new RegExp("&", "g"),
		reLt = new RegExp("\<", "g"),
		reGt = new RegExp("\>", "g"),
		reApos = new RegExp("'", "g"),
		reQuot = new RegExp('"', "g");
	String.prototype.toFormattedString = function(format) {
		switch (format) {
			case 'L':
				return this.toLowerCase();
			case 'U':
				return this.toUpperCase();
			case 'C':
				return encodeURIComponent(this);
			case 'T':
				return this.replace(reAmp, "&amp;").replace(reLt, "&lt;").replace(reGt, "&gt;").replace(reApos, "&apos;").replace(reQuot, "&quot;");
			default:
				return this;
		}
	};
})();
