﻿/**
 * @author Vlad Yakovlev (scorpix@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 * @version 0.1 (18.01.2009)
 * @requires jQuery
 */

var ie6FixPngImagePath = 'http://www.stream.ru/f/1/global/i/0.gif';

var Common = {

	/**
	 * Объект событий.
	 * @type {Event}
	 */
	Event: {

		/**
		 *
		 * @param {Event} oEvent
		 * @return {Event}
		 */
		normalize: function(oEvent) {
			var oEvent = oEvent ? oEvent : window.event;

			if (oEvent && oEvent.srcElement && !window.opera) {
				oEvent.target = oEvent.srcElement;
			}

			if (!oEvent) {
				return oEvent;
			}

			oEvent.iKeyCode = oEvent.keyCode ? oEvent.keyCode : (oEvent.which ? oEvent.which : null);

			if (oEvent.wheelDelta) {
				oEvent.iMouseWheelDelta = oEvent.wheelDelta / 120;

				if (window.opera) {
					oEvent.iMouseWheelDelta *= -1;
				}
			} else if (oEvent.detail) {
				oEvent.iMouseWheelDelta = -oEvent.detail / 3;
			}

			return oEvent;
		},

		/**
		 * Возвращает координаты курсора мыши от левого верхнего края окна браузера.
		 * @param {Event} oEvent
		 * @return {Object} Координаты: по горизонтали (<code>iLeft</code>) и вертикали (<code>iTop</code>).
		 */
		getAbsoluteCoords: function(oEvent) {
			var oEvent = oEvent ? oEvent : window.event;
			var oResult = {
				iLeft: 0,
				iTop: 0
			};

			if (oEvent.pageX || oEvent.pageY) {
				oResult.iLeft = oEvent.pageX;
				oResult.iTop = oEvent.pageY;
			} else if (oEvent.clientX || oEvent.clientY) {
				oResult.iLeft = oEvent.clientX + document.body.scrollLeft - document.body.clientLeft;
				oResult.iTop = oEvent.clientY + document.body.scrollTop - document.body.clientTop;

				if (document.body.parentElement && document.body.parentElement.clientLeft) {
					var oBodyParent = document.body.parentElement;

					oResult.iLeft += oBodyParent.scrollLeft - oBodyParent.clientLeft;
					oResult.iTop += oBodyParent.scrollTop - oBodyParent.clientTop;
				}
			}

			return oResult;
		}
	},

	/**
	 * Объект для работы с Cookie
	 * @type {Cookie}
	 */
	Cookie: {
		/**
		 * Устанавливает cookie.
		 * @param {String} sName
		 * @param {String} sValue
		 * @param {String} sExpire
		 * @param {String} sPath
		 */
		set: function(sName, sValue, sExpire, sPath) {
			document.cookie = sName + '=' + (window.encodeURI ? encodeURI(sValue) : escape(sValue)) + ((sExpire == null) ? '' : ('; expires=' + sExpire.toGMTString())) + ((sPath == null) ? '' : ('; path=' + sPath));
		},

		/**
		 * Возвращает значение cookie по его имени.
		 * @param {String} sName
		 * @return {String}
		 */
		get: function(sName) {
			if (0 > document.cookie.length) {
				return '';
			}

			var sSearch = sName + '=';

			var iOffset = document.cookie.indexOf(sSearch);

			if (-1 == iOffset) {
				return '';
			}

			iOffset += sSearch.length;

			var iEnd = document.cookie.indexOf(';', iOffset);

			if (-1 == iEnd) {
				iEnd = document.cookie.length;
			}

			return window.decodeURI ? decodeURI(document.cookie.substring(iOffset, iEnd)) : unescape(document.cookie.substring(iOffset, iEnd));
		}
	},

	/**
	 * Объект для работы с другими объектами.
	 * @type {Object}
	 */
	Object: {

		/**
		 * Копирует свойства и методы одного объекта в свойства и методы другого.
		 * @param {Object} oDestination Объект, в который копируются свойства.
		 * @param {Object} oSource Объек, чьи свойства копируются.
		 * @param {Boolean} bReplace Флаг замены свойства, если оно уже есть.
		 * @return {Object}
		 */
		extend: function(oDestination, oSource, bReplace) {

			for (var i in oSource) {
				if ((bReplace || 'undefined' == typeof(oDestination[i])) && 'undefined' != typeof(oSource[i])) {
					oDestination[i] = oSource[i];
				}
			}

			return oDestination;
		}
	},

	Utils: {

		oPopupDefaults: {
			iWidth: 540,
			iHeight: 600,
			sToolbar: 'no',
			sMenubar: 'no',
			sResizeable: 'yes',
			sScrollbars: 'yes',
			sStatus: 'yes'
		},

		/**
		 * Создает попап.
		 * @param {String} sUrl Адрес, по которому откроется попап. Если указано изображение, то создается тело документа.
		 * @param {String} sName
		 * @param {Object} oOptions
		 * @return {Boolean}
		 */
		popup: function(sUrl, sName, oOptions) {
			oOptions = Common.Object.extend(Common.Utils.oPopupDefaults, oOptions, true);

			var iLeftOffset = screen.availWidth / 2 - oOptions.iWidth / 2;

			var iTopOffset = screen.availHeight / 2 - oOptions.iHeight / 2;

			var oNewWindow = window.open(sUrl, '', 'left=' + iLeftOffset + ', ' + 'top = ' + iTopOffset + ', ' + 'width=' + oOptions.iWidth + ', ' + 'height=' + oOptions.iHeight + ', ' + 'menubar=' + oOptions.sMenubar + ', ' + 'toolbar=' + oOptions.sToolbar + ', ' + 'resizable=' + oOptions.sResizeable + ', ' + 'scrollbars=' + oOptions.sScrollbars + ', ' + 'status=' + oOptions.sStatus);

			if (sUrl.match(/\.(gif|jpe?g|png)$/i)) {
				oNewWindow.document.open();
				oNewWindow.document.write('<html><head>' + (sName != '' ? '<title>' + sName + '</title>' : '') + '</head><body style="background: #FFF; margin: 0; padding: 0;">' +
					'<table cellpadding="0" cellspacing="0" border="0" width="100%" height="100%"><tr><td align="center">' +
					'<img src="' + sUrl + '" />' +
					'</td></tr></table></body></html>'
				);
				oNewWindow.document.close();
			}

			oNewWindow.focus();

			return false;
		},

		navigationLinks: {
			'next':  { keyCode: 0x27 },
			'prev':  { keyCode: 0x25 },
			'up':    { keyCode: 0x26 },
			'down':  { keyCode: 0x28 },
			'start': { keyCode: 0x24 }
		},

		keyNavigationInit: function() {
			var me = this;

			$('link').each(function() {
				var rel = $(this).attr('rel');

				if (me.navigationLinks[rel]) {
					me.navigationLinks[rel].href = $(this).attr('href');
				}
			});

			$(document).keydown(function(event) {
				var event = Common.Event.normalize(event);

				if (!event.ctrlKey) {
					return true;
				}

				var links = Common.Utils.navigationLinks;

				for (var rel in links) {
					if (links[rel].keyCode == event.keyCode && '' != links[rel].href) {
						document.location = links[rel].href;
					}
				}
			});
		}
	},

	Measurer: (function() {
		var funcs = {};

		var interval = 500;

		var genId =  1;

		var curHeight;

		var el;

		var isInit = false;

		var isDocReady = false;

		$(function() {
			isDocReady = true;
			isInit && initBlock();
		});

		function initBlock() {
			el = $('<div></div>').css({
				height: '1em',
				left: 0,
				lineHeight: '1em',
				position: 'absolute',
				top: '-1em',
				visibility: 'hidden',
				width: '100%'
			}).appendTo('body');
			curHeight = el.height();


			setInterval(function() {
				checkScale();
			}, interval);
			$(window).resize(callFuncs);
		}

		function checkScale() {
			var newHeight = el.height();

			if (newHeight != curHeight) {
				curHeight = newHeight;
				callFuncs();
			}
		}

		function callFuncs() {
			for (var func in funcs) {
				funcs[func]();
			}
		}

		return {
			setFunc: function(name, func) {
				if (!$.isFunction(name) && !$.isFunction(func)) {
					funcs[name] && (delete funcs[name]);

					return;
				}

				isInit = true;
				isDocReady && initBlock();

				if ($.isFunction(name)) {
					funcs[genId.toString()] = name;
					genId++;
				} else {
					funcs[name] = func;
				}
			}
		};
	})()
};

/* Extensions */

Common.Object.extend(Array.prototype, {

	isEmpty: function() {
		return 0 == this.length;
	},

	push: function() {
		for (var i = 0; i < arguments.length; i++) {
			this[this.length] = arguments[i];
		}
	},

	splice: function() {
		if (arguments[0] == this.length && 0 == arguments[1]) {
			for (var i = 2; i < arguments.length; i++) {
				this.push(arguments[i]);
			}

			return;
		}

		if (arguments[0] > this.length - 1) {
			return;
		}

		var iRemovedCount = arguments[0] + arguments[1] > this.length ? this.length - arguments[0] : arguments[1];

		if (0 < iRemovedCount) {
			for (var i = arguments[0]; i < this.length; i++) {
				this[i] = this[i + iRemovedCount];
			}

			this.length = this.length - iRemovedCount;
		}

		var iNewCount = arguments.length - 2;

		if (0 < iNewCount) {
			var iLastIndex = this.length - 1, iNewLastIndex = iLastIndex + iNewCount;

			for (var i = iLastIndex, j = 0; i >= arguments[0]; i--, j++) {
				this[iNewLastIndex - j] = this[i];
			}

			for (var i = 0; i < iNewCount; i++) {
				this[arguments[0] + i] = arguments[i + 2];
			}
		}
	},

	remove: function(mElement) {
		for (var i = 0; i < this.length; i++) {
			if (this[i] == mElement) {
				this.splice(i, 1);

				break;
			}
		}
	},

	indexOf: function(mElement) {
		for (var i = 0; i < this.length; i++) {
			if (this[i] == mElement) {
				return i;
			}
		}

		return -1;
	},

	indexOfByFunction: function(mElement, fCompareFunction) {
		if (!fCompareFunction) {
			return this.indexOf(mElement);
		}

		for (var i = 0; i < this.length; i++) {
			if (fCompareFunction(this[i], mElement)) {
				return i;
			}
		}

		return -1;
	},

	contains: function(mElement, fCompareFunction) {
		return this.indexOfByFunction(mElement, fCompareFunction) > -1;
	},

	filtrate: function(mElement, fCompareFunction) {
		var aResult = [];

		for (var i = 0; i < this.length; i++) {
			if (fCompareFunction(this[i], mElement)) {
				aResult.push(this[i]);
			}
		}

		return aResult;
	},

	intersect: function(aArrayWith) {
		var aResult = [];

		for (var i = 0; i < aArrayWith.length; i++) {
			if (this.contains(aArrayWith[i])) {
				aResult.push(aArrayWith[i]);
			}
		}

		return aResult;
	},

	union: function(aArrayWith) {
		var aResult = [].concat(this);

		for (var i = 0; i < aArrayWith.length; i++) {
			if (!this.contains(aArrayWith[i])) {
				aResult.push(aArrayWith[i]);
			}
		}

		return aResult;
	},

	subtract: function(aArrayWith) {
		var aResult = [].concat(this);

		for (var i = 0; i < aArrayWith.length; i++) {
			if (this.contains(aArrayWith[i])) {
				aResult.remove(aArrayWith[i]);
			}
		}

		return aResult;
	}
});

Common.Object.extend(String.prototype, {

	stripTags: function() {
		return this.replace(/<\/?[^>]+>/gi, '');
	},

	formatNumber: function(sGroupSeparator, sFractionSeparator) {
		var sGroupSeparator = sGroupSeparator || ' ', sFractionSeparator = sFractionSeparator || ',', iFractionIndex = this.indexOf('.'), sFraction = iFractionIndex > -1 ? this.substring(iFractionIndex + 1) : '', sNumber = iFractionIndex > -1 ? this.substring(0, iFractionIndex) : this;

		if (5 > sNumber.length) {
			return sNumber + (iFractionIndex > -1 ? sFractionSeparator + sFraction : '');
		}

		var sResult = '';

		while (3 < sNumber.length) {
			sResult = sNumber.substring(sNumber.length - 3) + (sResult.length > 0 ? sGroupSeparator : '') + sResult;
			sNumber = sNumber.substring(0, sNumber.length - 3);
		}

		sResult = sNumber + sGroupSeparator + sResult + (-1 < iFractionIndex ? sFractionSeparator + sFraction : '');

		return sResult;
	}
});

Common.Object.extend(Number.prototype, {

	toFixed: function(iTo) {
		var aParts = this.toString().split('.', 2);

		if (!aParts[1]) {
			return this;
		}

		return aParts[0] + '.' + Math.round(aParts[1] / Math.pow(10, aParts[1].length - iTo));
	},

	formatNumber: function(sGroupSeparator, sFractionSeparator) {
		return this.toString().formatNumber(sGroupSeparator, sFractionSeparator);
	}
});

$(document.documentElement).addClass('js');

$(function() {

	/*$('.popup').click(function() {
		return Common.Utils.popup($(this).attr('href'), '');
	});*/

	Common.Utils.keyNavigationInit();
});

/**
 * Эмулирует поведение input type="search" как в Сафари.
 */
$.browser.safari || $(function() {
	$('input[placeholder]').each(function () {
		makePlaceholder(this);
	});

	/**
	 * Эмулирует поведение input type="search" как в Сафари.
	 *
	 * @param {Element} elem Поле ввода
	 * @param {String} [class_empty] Класс для пустого поля ввода
	 */
	function makePlaceholder(elem, classEmpty) {
		classEmpty = ('string' === typeof classEmpty) ? classEmpty : 'empty';

		$(elem).focus(function () {
			if (this.value === $(this).attr('placeholder')) {
				this.value = '';
			}

			$(this).removeClass(classEmpty);
		});

		$(elem).blur(function () {
			if (!this.value.length) {
				this.value = $(this).attr('placeholder');
				$(this).addClass(classEmpty);
			}
		});

		elem.value.length || $(elem).blur();
	}
});

if ($.browser.msie) {
	try {
		document.execCommand('BackgroundImageCache', false, true);
	} catch(e) {}

	// В IE для VML надо добавить схему и стили.
	if (!document.namespaces['v']) {
		document.namespaces.add('v', 'urn:schemas-microsoft-com:vml');

		var ss = document.createStyleSheet();

		ss.cssText = 'v\\:* {behavior:url(#default#VML);display:block;}';
	}

	function fixIePng(element) {
		if (!(/MSIE (5\.5|6).+Win/.test(navigator.userAgent))) {
			return;
		}

		var src;

		if ('IMG' == element.tagName || ('INPUT' == element.tagName && 'image' == element.type)) {
			if (/\.png$/.test(element.src)) {
				src = element.src;
				element.src = ie6FixPngImagePath;
			}
		} else {
			src = element.currentStyle.backgroundImage.match(/url\("(.+\.png)"\)/i);

			if (src) {
				src = src[1];
				element.runtimeStyle.backgroundImage = 'none';
			}
		}

		var reScaleMode = /iesizing\-(\w+)/;
		var m = reScaleMode.exec(element.className);

		if (src) {
			var scaleMode = (m) ? m[1] : 'crop';
			element.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "',sizingMethod='" + scaleMode + "')";
		}
	}
}