/**
 * Main javascript functions
 *
 * @package    UTPC
 * @subpackage javascript
 * @author     Real Deal Marketing, www.realdealmarketing.net
 * @copyright  All rights reserved
 * @version    1.0
 */

if (typeof(asyncUrl) == 'undefined')
{
	var asyncUrl = '/async/';
}

/**
 * Return true | false if variable is defined
 *
 * @param mixed variable
 */

function is_defined(variable)
{
	return (typeof(window[variable]) == "undefined") ? false: true;
}

/**
 * Return true | false if variable is set
 *
 * @param mixed variable
 * @return bool
 */

function isset(variable)
{
	return (typeof(variable) == "undefined") ? false: true;
}

/**
 * Return true | false if element id is in the array
 *
 * @param mixed elem
 * @param array arr
 */

function in_array(elem, arr)
{
	for (i=0; i < arr.length; i++)
	{
		if (elem == arr[i])
		{
			return true;
		}
	}
	return false;
}

/**
 * Toggle element display (show / hode) and update text on / off
 *
 * @param string target_id - element to toggle
 * @param string source_id - link element id
 * @param string text_on - text to display in the link_id if target_id is not visible
 * @param string text_off - text to display in the link_id if target_id is visible
 */

function toggleText (target_id, source_id, text_on, text_off)
{
	$("#"+target_id).toggle();
	$("#"+source_id).html($("#"+target_id).is(':hidden') ? text_on : text_off);
}

/**
* Redirect to url if user confirms
*
* @param string prompt_text - test to display
* @param string url - url to go to if user clicks on ok
*/

function askConfirmation (prompt_text, url)
{
	if (confirm(prompt_text))
	{
		self.location = url;
	}
}

/**
* Submit form if user confirms (asnwers 'yes' to prompt_text)
*
* @param string prompt_text - test to display
* @param string form_name
*/

function askSubmit(prompt_text, form_name)
{
	if (confirm(prompt_text))
	{
		document.forms[form_name].submit();
	}
}

/**
 * Async request object
 *
 * @package    UTPC
 * @subpackage javascript
 * @author     Real Deal Marketing, www.realdealmarketing.net
 * @copyright  All rights reserved
 * @version    1.0
 */
var async = {

	url : asyncUrl,
	async: true,

/**
* Execute async request and load returned content in a div (if container is defined)
*
* @param string type - GET or POST, default is GET (must be uppercase)
* @param string params - params to pass to async controller
* @param string container - element ID
* @param bool visible - if true, no need to "show" container
* @param bool notify - if > 0 then display message
* @param string callbackOk - callback function to execute if everything is ok
* @param string callbackError - callback function to execute if there was an error
**/

	req: function (type, params, container, visible, notify, callbackOk, callbackError)
	{
		if (typeof(visible) == 'undefined') { visible = true; }

		/* Set the request type */
		if (typeof(type) == 'undefined')
		{
			type = 'GET';
		}
		else if (type != 'GET' && type != 'POST')
		{
			type = 'GET';
		}

		if (( container != null ) && ( container != false ) && ( container != 0 ))
		{
			if ( container.charAt(0) != '#' && container.charAt(0) != '.' ) { container = '#' + container; }

			$(container).show().addClass('loadingContainer');

			if (visible) { $(container).before('<div id="loader" class="loader">Loading...</div>'); }
		}

		// do we have to notify user or simply return
		notify = (typeof(notify) != 'undefined' && notify > 0) ? true : false;

		$.ajax({
			type: type,
			url: this.url,
			async: this.async,
			data: params,
			success: function(sys_response)
			{

				if ( async.isValidResponse (sys_response) )
				{
					sys_response = eval('(' + sys_response + ')');

					//default action
					if (typeof(sys_response['content']['default']) != 'undefined')
					{
						$(container).html(sys_response['content']['default']);
					}
					$(container).removeClass('loadingContainer');
					$('#loader').remove();

					if (notify)
					{
						//errors
						$.each(sys_response.errors, function(index, value){
							sysMessage.addError(value);
						});
						//messages
						$.each(sys_response.messages, function(index, value){
							if (parseInt(index) < 0)	{ sysMessage.addNotification(value); }
							else						{ sysMessage.addMessage(value); }
						});

						//warnings
						$.each(sys_response.warnings, function(index, value){
							sysMessage.addWarning(value);
						});
					}

					if (sys_response['status'] == -1)
					{
						if (typeof(callbackError) == 'function') { callbackError.call(this, sys_response); }
						else if (typeof(callbackError) != 'undefined')	{ eval(callbackError); }
					}
					else
					{
						if (typeof(callbackOk) == 'function') { callbackOk.call(this, sys_response); }
						else if (typeof(callbackOk) != 'undefined')	{ eval(callbackOk); }
					}

				}
				else //responses without using System_Response
				{

					// if ( $(container).length > 0 ) //but this working slower
					if (( container != null ) && ( container != false ) && ( container != 0 ))
					{
						$(container).html(sys_response).removeClass('loadingContainer');

						if (typeof(callbackOk) == 'function') { callbackOk.call(this, sys_response); }
						else if (typeof(callbackOk) != 'undefined')	{ eval(callbackOk); }

						$('#loader').remove();
					}
					else // _request
					{
						var msg = sys_response;

						// if there was an error message it starts with "-", eg "-Sorry, there was an error"
						var responseStatus = msg.charAt(0) == "-" ? 'error' : 'success';

						if (responseStatus == 'success')
						{

							if (typeof(callbackOk) == 'function') { callbackOk.call(this, sys_response); }
							else if (typeof(callbackOk) != 'undefined')	{ eval(callbackOk); }

							if (notify)								{ sysMessage.addMessage (msg); }
							msg = true;
						}
						else
						{
							if (typeof(callbackError) == 'function') { callbackError.call(this, sys_response); }
							else if (typeof(callbackError) != 'undefined')	{ eval(callbackError); }

							if (notify)									{ sysMessage.addError (msg.substr(1,255)); }
							msg = false;
						}
					}
				}

			},

			error: function(msg, why)
			{
//				sysMessage.addError ('Service error ' + msg + '. Reason: ' + why);
				return false;
			}
		});

	}, //end of req

	isValidResponse: function(sys_response)
	{
		if ( sys_response.charAt(0) != '{' ) { return false; }

		try {
			sys_response = eval('(' + sys_response + ')');
		} catch (e) {
			return false;
		}

		if ( ! isset ( sys_response['errors']   ) ) { return false; }
		if ( ! isset ( sys_response['messages'] ) ) { return false; }
		if ( ! isset ( sys_response['warnings'] ) ) { return false; }
		if ( ! isset ( sys_response['status']   ) ) { return false; }
		if ( ! isset ( sys_response['content']  ) ) { return false; }
		if ( ! isset ( sys_response['data']     ) ) { return false; }

		return true;
	},

	//aliases for req
	request:
	{
		post: function (params, container, visible, notify, callbackOk, callbackError)
		{
			async.req('POST', params, container, visible, notify, callbackOk, callbackError);
		},

		get: function (params, container, visible, notify, callbackOk, callbackError)
		{
			async.req('GET', params, container, visible, notify, callbackOk, callbackError);
		}
	},

/**
* Execute async request and load returned content in a div
*
* @param string type - GET or POST, default is GET (must be uppercase)
* @param string params - params to pass to async controller
* @param string container - element ID
* @param bool visible - if true, no need to "show" container
* @param string callback - callback function to execute after load
*/
	_read : function (type, params, container, visible, callback)
	{
		async.req(type, params, container, visible, null, callback, null);
		return false;
		// if (typeof(visible) == 'undefined')
		// {
		// 	visible = true;
		// }
		//
		// /* Set the request type */
		// if (typeof(type) == 'undefined')
		// {
		// 	type = 'GET';
		// }
		// else if (type != 'GET' && type != 'POST')
		// {
		// 	type = 'GET';
		// }
		//
		// $("#"+container).show().addClass('loadingContainer');
		//
		// if (visible)
		// {
		// 	$("#"+container).before('<div id="loader" class="loader">Loading...</div>');
		// }
		//
		// $.ajax({
		// 	type: type,
		// 	url: this.url,
		// 	async: this.async,
		// 	data: params,
		// 	success: function(msg)
		// 	{
		// 		$('#'+container).html(msg).removeClass('loadingContainer');
		// 		$('#loader').remove();
		// 	}
		// });
		//
		// if (typeof(callback) != 'undefined')
		// {
		// 	eval(callback);
		// }
	},

/**
 * Execute async request but do not load anything anywhere, just read response and execute callback functions
 *
 * If script returns error prepend error message with "-"
 *
 * @param string params - params to pass to async controller
 * @param bool notify - if > 0 then display message
 * @param string callbackOk - callback function to execute if everything is ok
 * @param string callbackError - callback function to execute if there was an error
 * @return mixed - message if success, false if error
 */

	_request : function (type, params, notify, callbackOk, callbackError)
	{
		async.req(type, params, null, null, notify, callbackOk, callbackError);
		return false;
		// $.ajax({
		// 	type: type,
		// 	url: this.url,
		// 	async: this.async,
		// 	data: params,
		// 	success: function(msg)
		// 	{
		// 		// if there was an error message it starts with "-", eg "-Sorry, there was an error"
		// 		var responseStatus = msg.charAt(0) == "-" ? 'error' : 'success';
		//
		// 		// do we have to notify user or simply return
		// 		notify = (typeof(notify) != 'undefined' && notify > 0) ? true : false;
		//
		// 		if (responseStatus == 'success')
		// 		{
		// 			if (typeof(callbackOk) != 'undefined')	{ eval(callbackOk); }
		// 			if (notify)								{ sysMessage.addMessage (msg); }
		// 			msg = true;
		// 		}
		// 		else
		// 		{
		// 			if (typeof(callbackError) != 'undefined')	{ eval(callbackError); }
		// 			if (notify)									{ sysMessage.addError (msg.substr(1,255)); }
		// 			msg = false;
		// 		}
		//
		// 		return msg;
		// 	},
		//
		// 	error: function(msg, why)
		// 	{
		// 		sysMessage.addError ('Service error ' + msg + '. Reason: ' + why);
		// 		return false;
		// 	}
		// });
		//
		// return false;
	},

/**
 * Execute GET ajax request
 */
	load : function (params, container, visible, callback)
	{
		this._read ('GET', params, container, visible, callback);
	},

/**
 * Same as load, except it loads only if not already loaded
 *
 * @return bool
 */
	once : function (force, params, container, visible, callback)
	{
		if (typeof(force) == 'undefined')
		{
			force = false;
		}

		if (force == true || !$('#'+container).hasClass('loaded'))
		{
			async.load (params, container, visible, callback);
			$('#'+container).addClass('loaded');
			return true;
		}

		return false;
	},

/**
 * Execute async request but do not load anything anywhere, just read response and execute callback functions
 */
	exec : function (params, notify, callbackOk, callbackError)
	{
		this._request ('GET', params, notify, callbackOk, callbackError);
	},


/**
* Special load shortcut that will replace main container with content returned
*/

	container : function (name, callback)
	{
		this.load ('c=execute&a='+name, 'container', true, callback)
	},

/**
 * Some aliases for GET method
 *
 * You can use async.get.load instead of async.load, etc
 */
	get :
	{
		load : function (params, container, visible, callback)
		{
			async.load (params, container, visible, callback);
		},

		once : function (force, params, container, visible, callback)
		{
			async.once (force, params, container, visible, callback);
		},

		exec : function (params, notify, callbackOk, callbackError)
		{
			async.exec (params, notify, callbackOk, callbackError)
		}
	},

/**
 * POST ajax requests
 *
 * Everything is the same as GET, it only sends POST request
 */
	post :
	{
		/**
		 * Same as async.load, except it will use POST
		 */
		load : function (params, container, visible, callback)
		{
			async._read ('POST', params, container, visible, callback);
		},

		/**
		 * Same as async.once except it will use POST method for request
		 */
		once : function (force, params, container, visible, callback)
		{
			if (typeof(force) == 'undefined')
			{
				force = false;
			}

			if (force == true || !$('#'+container).hasClass('loaded'))
			{
				async.post.load (params, container, visible, callback);
				$('#'+container).addClass('loaded');
				return true;
			}

			return false;
		},

		/**
		 * Same as async.exec, except it will use POST
		 */
		exec : function (type, params, notify, callbackOk, callbackError)
		{
			async._request ('POST', type, params, notify, callbackOk, callbackError);
		}
	},

/**
 * Initialize object
 *
 * @param string url - where to send all request
 * @param bool async - use async or sync request
 */
	init : function (url, async)
	{
		if (typeof(url) == 'undefined') 	{ url = asyncUrl; }
		if (typeof(async) == 'undefined')	{ async = true; }

		this.url = url;
		this.async = async;
	}
};

/**
 * Execute synchronously request and load returned content in a div
 *
 */

var sync = {

/**
 * Execute synchronously request and load returned content in a div
 *
 * @param string params - params to pass to async controller
 * @param string container - element ID
 * @param string callback - callback function to execute after load
 */
	load : function (params, container, visible, callback)
	{
		var request = async;
		request.async = false;
		request.load (params, container, visible, callback);
	}
};


/**
* Dialog object
*/
var Dialog =
{
	container: 	'dialogContainer',
	className: 	'',
	scrollTo:	false,
	load: function (params, container, visible, callback)
	{
		this.container 	= isset(container) ? container 	: this.container;
		visible	  		= isset(visible)   ? visible	: false;
		this.reset();
		$('#' + this.container).slideDown().addClass(this.className);
		if (this.scrollTo != false)	{ app.doc.scrollTo (this.scrollTo); }
		else 						{ $('#' + this.container).css({'margin-top': $(window).scrollTop() + '50px'}); }
		async.load (params, this.container, visible, callback);
		$(document).bind('keydown', function(event)  { if (event.which == '27') 	{ Dialog.close();} });
	},
	setClass: 		function (name)			{ this.className = isset(name) ? name : this.className; },
	close: 			function ()				{ $('#' + this.container).slideUp(); },
	reset: 			function ()				{ if (!$('#' + this.container).is(':hidden'))	{ $('#' + this.container).hide(); } },
	setScrollTo: 	function (scrollTo)		{ if (isset(scrollTo)) 	{ this.scrollTo = scrollTo; } }

}
/**
* System messages object - used to display and hide special system messages
*
*/

var sysMessage = {

/**
 * Icon to display to close message
 */
	close_icon: '<img src="/public/static/close.png" height="14" width="14" align="right" border="0" alt="close" class="icon" />',
/**
 * Hide interval in limiseconds
 */
	hide_interval: 1500,

/**
 * Timeout
 */
	to: null,
/**
 * Counter
 */
	count: 0,

/**
 * Set fade interval
 */
	setInterval: function(interval)
	{
		this.hide_interval = interval;
		this.start()
	},

/**
 * Start fading
 */
	start: function ()
	{
		if ($(".fadeable").length > 0 && this.hide_interval > 0)
		{
			if (this.count > 1)
			{
				if (this.count % 2 == 0) { $(".fadeable").eq(0).slideUp(); }
				else { $(".fadeable").eq(0).remove(); }
			}

			this.count++;
			this.to = setTimeout("sysMessage.start()", this.hide_interval);
		}
		else
		{
			clearTimeout(this.to);
		}
	},

/**
 * Remove one message
 */
	remove: function (obj)
	{
		$(obj).parent().remove();
	},

/**
 * Add text message of specific type
 */
	add:function (msg, type)
	{
		if (msg != '')
		{
			var className = 'info'+type;
			if (type != 'Error' && type != 'Notification')
			{
				className += " fadeable";
			}

			$('<div class="infoAsync '+className+'"><span onclick="sysMessage.remove(this);">'+this.close_icon+'</span><p>'+msg+'</p></div>').appendTo('#sysMsgContainer').slideDown('fast');
			clearTimeout(this.to);
			this.to = null;
			this.count = 0;
			sysMessage.start();
		}
	},

/**
* Shortcut to add message
*/
	addMessage:function (msg)		{ sysMessage.add (msg, 'Message'); },

/**
* Shortcut to add notification (sticky message)
*/
	addNotification:function (msg)	{ sysMessage.add (msg, 'Notification'); },

/**
* Shortcut to add error
*/
	addError:function (msg)			{ sysMessage.add (msg, 'Error'); },

/**
* Shortcut to add warning
*/
	addWarning:function (msg)
	{
		sysMessage.add (msg, 'Warning');
	},

/**
* Clear all items in system mesages container
*/
	clearAll:function ()
	{
		$("#sysMsgContainer DIV").remove();
		clearTimeout(this.to);
	}
};

/**
* Initialize sysMessages timeouts and containers
*
* @return object this
*/

$( function (i) {
	$("#sysMsgContainer").mouseover( function () { clearTimeout(sysMessage.to); } );
	$("#sysMsgContainer").mousemove( function () { clearTimeout(sysMessage.to); } );
	$("#sysMsgContainer").mouseout( function ()  { sysMessage.to = setTimeout("sysMessage.start()", sysMessage.hide_interval); } );
});


/**
* Set background color
*
* @param string bg - css background attribute to set
*/
$.fn.background = function(bg) { return this.css('background', bg);  };

/**
* Set text color
*
* @param string clr - css color attribute to set
*/
$.fn.color 		= function(clr) { return this.css('color', clr);  };

/**
* Make elmentId togglabe - parent element can expand or collapse this elementId
*
* @param string elementId - element id to toggle
* @return object this
*/

$.fn.togglable = function(elementId)
{
	this.data('txt', this.html());
	this.css('cursor', 'pointer');

	if ($(elementId).is(":visible"))
	{
		$(this).prepend('<img class="appicosmall toggle_up" src="/public/static/pixel.png" alt="expand" align="absmiddle" /> ');
	}
	else
	{
		$(this).prepend('<img class="appicosmall toggle_down" src="/public/static/pixel.png" alt="collapse" align="absmiddle" /> ');
	}

	return $(this).click(function ()
	{
		t = $(this).data('txt');
		$(elementId).toggle();
		$(this).html($(elementId).is(":visible") ? '<img class="appicosmall toggle_up" src="/public/static/pixel.png" alt="expand" align="absmiddle" /> '+t : '<img class="appicosmall toggle_down" src="/public/static/pixel.png" alt="collapse" align="absmiddle" /> '+t);
	});
};

/**
* Make object hoverable - on mouse over it will display it's child element
*
* @return object this
*/

$.fn.hoverable = function()
{
	var t = this;
	$(this).each (function (i)
	{
		$(this).parent().hover (
			function() { $(t, this).eq(i).show(); },
			function() { $(t, this).eq(i).fadeOut(); }
		);
	} );
	return $(this);
};

/**
* First P in the element has truncated text, last child has full text.
* when clicked it will toggle between truncated and full text
*
* @return object this
*/

$.fn.moreless = function(lenght)
{
	this.css('cursor', 'pointer');
	this.attr('title', 'click to view more/less text');

	$("P:first-child", this).append(" <span>more &raquo;</span>");
	$("P:last-child", this).append(" <span>&laquo; less</span>").hide();

	return $(this).click(function ()
	{
		$("P:first-child", this).toggle();
		$("P:last-child", this).toggle();
	});
};

/**
* Simple dropdown menu will make element display html menu that is initially hidden
*
* @param string menuId - element id containing menu items
* @param string bindEvent - event to bind: click, moouseover...
* @param string align - how to align menu items: left | right
* @param string callback - callback function to execute (if any)
* @return object this
*/
$.fn.simpleDropdown = function(menuId, bindEvent, align, callback)
{
	$(this).data("ddClass", $(menuId).attr("class"));
	$('A', this).addClass('hasDropdown');

	if (typeof(bindEvent) == 'undefined')	{ bindEvent = 'click'; }
	if (typeof(align) == 'undefined')		{ align = 'left'; }

	$(this).bind (bindEvent, function (e)
	{
		var self = this;
		if (typeof(callback) != 'undefined') { eval (callback); }

		$("."+$(this).data("ddClass")).not(menuId).hide();
		$(".hasDropdown").parent().removeClass("visibleDropdown");

		$(this).toggleClass("visibleDropdown");

		e.stopPropagation();
		var offset = $(this).offset();

		if (align == 'right')	{ $(menuId).css("left", offset.left+$(this).width()-$(menuId).width()+"px"); }
		else 					{ $(menuId).css("left", offset.left+"px"); }

		$(menuId).css("top",  offset.top+$(this).height()+"px").toggle();

		var el = this;
		$(this).toggleClass("ddSelected");

		$(document).one("click", function (e)
		{
			$("."+$(el).data("ddClass")).hide();
			$(el).removeClass("ddSelected");
			$(self).removeClass("visibleDropdown");
		});
	});

	return this;
};

/**
* Display simple drop down submenu
*
* @param string menuId - element id containing menu items
* @param string bindEvent - event to bind: click, moouseover...
*/

$.fn.simpleSubmenu = function(menuId, bindEvent)
{
	$(this).data("ddClass", $(menuId).attr("class"));
	if (typeof(bindEvent) == 'undefined')	{ bindEvent = 'click'; }
	$("A", this).addClass ('hasMenu');

	$(this).bind (bindEvent, function (e)
	{
		$(".simpleDropdownMenu.submenu").hide();
		$("."+$(this).data("ddClass")).not(menuId).hide();
		$("."+$(this).attr("class")).not(this).removeClass("ddSelected");

		e.stopPropagation();
		var offset = $(this).offset();

		$(menuId).css("left", offset.left+$(this).width()-2+"px");
		$(menuId).css("top",  offset.top+2+"px");
		$(menuId).toggle();

		var el = this;
		$(this).toggleClass("ddSelected");

		$(document).one("click", function (e)
		{
			$("."+$(el).data("ddClass")).hide();
//			$(el).removeClass("ddSelected");
		});
	});

	return this;
};

/**
 * Insert text to the caret position
 *
 * @return object this
 */

$.fn.insertAtCaret = function (tagName)
{
	return this.each(function()
	{
		/* IE support */
		if (document.selection)
		{
			this.focus();
			sel = document.selection.createRange();
			sel.text = tagName;
			this.focus();
		}
		/* MOZILLA/NETSCAPE support */
		else if (this.selectionStart || this.selectionStart == '0')
		{
			startPos 	= this.selectionStart;
			endPos 		= this.selectionEnd;
			scrollTop	= this.scrollTop;

			this.value	= this.value.substring(0, startPos) + tagName + this.value.substring(endPos,this.value.length);
			this.focus();
			this.selectionStart = startPos + tagName.length;
			this.selectionEnd	= startPos + tagName.length;
			this.scrollTop 		= scrollTop;
		}
		else
		{
			this.value += tagName;
			this.focus();
		}
	});
};




/**
 * Create simple inline editor
 *
 * @example: <span id="home--mem_comment" class="editableText" title="Your comment" >Click on this text to change</span>
 *
 * $('.editableText').inlineEdit();
 */

(function($) {

	$.fn.inlineEdit = function(options) {

		options = $.extend({
			value: '',
			save: false,
			notify: 1,
			buttonText: 'Save',
			cancelText: 'Cancel',
			placeholder: 'Click to edit'
		}, options);

		return $.each(this, function() {
			$.inlineEdit(this, options);
		});
	};

	$.inlineEdit = function(obj, options)
	{
		var self = $(obj);
		var placeholderHtml = '<span class="inlineEdit-placeholder">'+ options.placeholder +'</span>';

		self.value = function(newValue)
		{
			if (arguments.length)
			{
				self.data('value', $('newValue').hasClass('inlineEdit-placeholder') ? '' : newValue);
			}
			return self.data('value');
		};

		self.save = function (e, data)
		{
			var ok = data.title == '' ? true : confirm('Change '+data.title+' to "'+ data.value +'"?');
			if (ok)
			{
				async.post.exec ('c='+data.callback[0]+'&a=update-field&f='+data.callback[1]+'&v='+data.value, options.notify);
				return true;
			}
			return false;
		};

		self.callbackOK = function (hash)
		{
			self.html(hash.value);
			self.color('#00c000').animate({color: '#000000'}, 5000);
		};

		self.value($.trim(self.text()) || options.value);

		self.bind('click', function(event) {
			var $this = $(event.target);

			if ($this.is('button'))
			{
				var hash =
				{
					id: 	self.attr('id'),
					title:	self.attr('title'),
					name:	self.attr('name'),
					callback:	self.attr('id').split('--'),
					value:	$this.siblings('input').val()
				};

				if (options.save == false)
				{
					if (self.save(event, hash))
					{
						self.callbackOK(hash);
					}
				}
				else if (($.isFunction(options.save) && options.save.call(self, event, hash)) !== false || !options.save)
				{
					self.callbackOK(hash);
				}
			}
			else if ($this.is(self[0].tagName) || $this.hasClass('inlineEdit-placeholder'))
			{
				var v = $this.width();
				self.html('<input type="text" value="'+ self.value() +'" maxlength="255" style="width:'+v+'px;"> <button>'+ options.buttonText +'</button> <a href="javascript:;">' + options.cancelText + '</a>')
					.find('input')
					.bind('blur', function()
					{
						if (self.timer)
						{
							window.clearTimeout(self.timer);
						}
						self.timer = window.setTimeout(function()
						{
							self.html(self.value() || placeholderHtml);
						}, 200);
					})
					.focus();
			}
		});

		if (!self.value())
		{
			self.html($(placeholderHtml));
		}
		else if (options.value)
		{
			self.html(options.value);
		}
	};

})(jQuery);

/**
 * Create confirmation box for specific actions (usually delete).
 *
 * @example: <a class="areYouSure" href="photos" title="delete this item">{#ico_delete#} Delete</a>
 *
 * <script type="text/javascript">
 * $(".areYouSure").areYouSure();
 * </script>
 */

(function($) {

	$.fn.areYouSure = function(options) {

		options = $.extend({
			value: '',
			disableDone: true,
			buttonText:	 'Yes',
			cancelText:  'No',
			doneText:    'Done',
			placeholder: 'Are you sure you want to '
		}, options);

		return $.each(this, function() {
			$.areYouSure(this, options);
		});
	};

	$.areYouSure = function(obj, options)
	{
		var self = $(obj), placeholderHtml = '<span class="areYouSure-placeholder">'+ options.placeholder +'</span>';

		self.old = self.html();
		self.href = self.attr('href');
		self.attr('href', 'javascript:;');

		self.value = function(newValue)
		{
			if (arguments.length)
			{
				self.data('value', $(newValue).hasClass('areYouSure-placeholder') ? '' : newValue);
			}
			return self.data('value');
		};

		self.save = function (e, data)
		{
			var href = self.href.split(":");
			if (href[0] == 'javascript') { eval(href[1]); }
			else { window.location.href = typeof(href[1] == 'undefined') ? href[0] : href[1]; }

			if (options.disableDone)
			{
				self.unbind ('click');
				self.removeClass('active').addClass('done').html(options.doneText);
			}
			else
			{
				self.removeClass('active').html(self.old);
			}
			return true;
		};

		self.cancel = function (e, data)
		{
			self.removeClass('active').html(self.old);
			return false;
		};

		self.callbackOK = function ()
		{
			self.value(self.href);
			if (options.disableDone)
			{
				self.animate({color: '#808080'}, 5000);
			}
		};

		self.value($.trim(self.text()) || options.value);

		self.bind('click', function(event)
		{
			var $this = $(event.target);
			if ($this.is('button'))
			{
				var hash = { value: self.href };

				if (self.save(event, hash))
				{
					self.callbackOK(hash);
				}
			}
			else if ($this.is('em'))
			{
				self.cancel();
			}
			else if ($this.is(self[0].tagName) || $this.hasClass('areYouSure-placeholder'))
			{
				self.addClass('active').html(options.placeholder + self.attr('title') + '? <button>'+ options.buttonText +'</button> <em>' + options.cancelText + '</em>')
			}
		});

		if (!self.value())
		{
			self.html($(placeholderHtml));
		}
		else if (options.value)
		{
			self.html(options.value);
		}
	};

})(jQuery);

/**
 *  Detect if JavaScript is enabled
 */
$(document).ready(function() {
	$('body').addClass('hasJS');
});

function timezoneClientside()
{
	var rightNow = new Date();
	var gmt_offset = rightNow.getTimezoneOffset() * -1;
	return gmt_offset;
}

var cdate = new Date();
var cdate = new Date(cdate.getTime() + (1 * 1000 * 60 * 60 * 24));
document.cookie="tz_offset=" + timezoneClientside() + "; expires=" + cdate.toGMTString();

