
var lib = {
	console :{
		on 			: function(){if(typeof console == 'object' && console.firebug && navigator.userAgent.indexOf('Firefox') != 0  ){return true;} else if(typeof console == 'object' && navigator.userAgent.indexOf('Webkit') != 0 ) {return true;} else { return false; }},
		log 		: function(cmd){if(lib.console.on()){console.log(cmd);}},
		debug 		: function(cmd){if(lib.console.on()){console.debug(cmd);}},
		info 		: function(cmd){if(lib.console.on()){console.info(cmd);}},
		warn 		: function(cmd){if(lib.console.on()){console.warn(cmd);}},
		error 		: function(cmd){if(lib.console.on()){console.error(cmd);}},
		trace 		: function(cmd){if(lib.console.on()){console.trace();}},
		group 		: function(title){if(lib.console.on()){console.group(title);}},
		groupEnd 	: function(cmd){if(lib.console.on()){console.groupEnd();}},
		dir 		: function(obj){if(lib.console.on()){console.dir(obj);}},
		trace 		: function(cmd){if(lib.console.on()){console.trace();}}
	}
};



jj = {};

/**
 * Creates cookie or return it's value.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Creates session cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'site.com', secure: true });
 * @desc Creates cookie with values.
 * @example $.cookie('the_cookie', null);
 * @desc Deletes cookie.
 * @example $.cookie('the_cookie');
 * @desc Returns value of the cookie.
 *
 * @param String name Cookie name.
 * @param String value Cookie value.
 * @param Object options Cookie options object.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @return Cookie value or jj object.
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 * @version 1.0
 */
jj.cookie = function(name, value, options) {

	if ('undefined' != typeof value) {
		options = options || {};

		if (null === value) {
			value = '';
			options.expires = -1;
		}

		var expires = '';

		if (options.expires && ('number' == typeof options.expires || options.expires.toUTCString)) {
			var date;

			if ('number' == typeof options.expires) {
				date = new Date();
				date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
			} else {
				date = options.expires;
			}

			expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
		}

		// CAUTION: Needed to parenthesize options.path and options.domain
		// in the following expressions, otherwise they evaluate to undefined
		// in the packed version for some reason...
		var path = options.path ? '; path=' + options.path : '';
		var domain = options.domain ? '; domain=' + options.domain : '';
		var secure = options.secure ? '; secure' : '';
		document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');

		return this;
	}

	var cookieValue = null;

	if (document.cookie && '' != document.cookie) {
		var cookies = document.cookie.split(';');

		for (var i = 0; i < cookies.length; i++) {
			var cookie = jQuery.trim(cookies[i]);

			// Does this cookie string begin with the name we want?
			if (cookie.substring(0, name.length + 1) == (name + '=')) {
				cookieValue = decodeURIComponent(cookie.substring(name.length + 1));

				break;
			}
		}
	}

	return cookieValue;
};



/**
 * Попапы-блоки внутри окна браузера.
 *
 * @param {String|Element|jQuery} Контейнер попапа.
 * @param {Object} options Настройки:
 * <ul>
 *   <li>{String|Element|jQuery} fader - блок тени,</li>
 *   <li>{String|Element|Array[Element]|jQuery} link - блоки для показа/скрытия попапа,</li>
 *   <li>{String|Element|Array[Element]|jQuery} close - блоки для закрытия попапа,</li>
 *   <li>beforeShow - функция, выполняемая перед открытием,</li>
 *   <li>afterShow - функция, выполняемая после открытия,</li>
 *   <li>beforeHide - функция, выполняемая перед закрытием,</li>
 *   <li>afterHide - функция, выполняемая после закрытия.</li>
 * </ul>
 * @return {Object} Функции:
 * <ul>
 *   <li>hide</li>
 *   <li>cancel</li>
 *   <li>show</li>
 *   <li>toggle</li>
 * </ul>
 *
 * @author Stepan Reznikov [stepan.reznikov@gmail.com], Vladislav Yakovlev [red.scorpix@gmail.com]
 * @version 2.1.5
 * @date 2009-08-12
 *
 * @changelog
 * Version 2.1.5
 * Исправлена ошибки, по которой были проблемы с множественным созданием попапов.
 * Оптимизирован код.
 * Обязательная опция блока вынесена в отдельный параметр <code>container</code>.
 *
 * @changelog
 * Version 2.1.4
 * Оптимизирован код.
 *
 * @changelog
 * Version 2.1.3
 * Добавлены комментарии.</li>
 * Параметр <code>showFunction</code> удален.</li>
 * Добавлены параметры <code>beforeShow</code>, <code>afterShow</code>, <code>beforeHide</code>, <code>afterHide</code>.</li>
 *
 * @changelog
 * Version 2.1
 * Флаг <code>keep</code> заменен на <code>event.stopPropagation().</code>
 * Форма появляется и исчезает плавно (под IE появляется/исчезает мгновенно в виду проблем с <code>filter</code>).
 * Добавлен параметр <code>showFunction</code> - функция, выполняемая после показа popup'а.
 */
jj.popupBlock = (function() {

	function PopupBlock(container, options) {
		var
			documentClickHandler,
			documentKeyDownHandler;

		container.click(function(event) {
			event.stopPropagation();
			return false;
		});

		if (options.fader) {
			options.fader = $(options.fader);
		}

		if (options.link) {
			options.link = $(options.link);
			options.link.click(toggle);
		}

		if (options.close) {
			options.close = $(options.close);
			options.close.click(toggle);
		}

		function cancel(event) {
			var code = event.keyCode ? event.keyCode : event.which ? event.which : null;
			code === 27 && hide(event);
		}

		function hide(event) {
			if (container.hasClass('hidden')) return;

			options.beforeHide && options.beforeHide();
			options.fader && options.fader.addClass('hidden');
			container.addClass('hidden');
			$(document)
				.unbind('click', documentClickHandler)
				.unbind('keydown', documentKeyDownHandler);

			options.afterHide && options.afterHide();

			if (event) {
				event.preventDefault();
				event.stopPropagation();
			}
		}

		function show(event) {
			if (!container.hasClass('hidden')) return;

			options.beforeShow && options.beforeShow();
			options.fader && options.fader.removeClass('hidden');

			$.browser.msie ? container.removeClass('hidden') : container.css('opacity', 0).removeClass('hidden').animate({ opacity: 1 }, 3000, function() {
				container.css('opacity', '');
				options.afterShow && options.afterShow();
			});

			documentClickHandler = hide;
			documentKeyDownHandler = cancel;

			$(document)
				.click(documentClickHandler)
				.keydown(documentKeyDownHandler);

			$.browser.msie && options.afterShow && options.afterShow();

			if (event) {
				event.preventDefault();
				event.stopPropagation();
			}
		}

		function toggle(event) {
			container.hasClass('hidden') ? show(event) : hide(event);
		}

		return {

			/**
			 * Вызывает событие скрытия попапа.
			 * @param {Event} [event]
			 */
			hide: hide,

			/**
			 * Вызывает событие показа попапа.
			 * @param {Event} [event]
			 */
			show: show,

			/**
			 * Вызывает событие переключения состояния попапа.
			 * @param {Event} [event]
			 */
			toggle: toggle
		};
	}

	return function(container, options) {
		return new PopupBlock($(container), options);
	};
})();

