﻿(function($) {

function findLabel(element) {
	var elt = $(element);
	return elt.parents('form:first').find('label[for=' + elt.attr(elt.is(':hidden') ? 'name' : 'id') + ']');
}

jQuery.validator.setDefaults({
	highlight: function(element, errorClass) { findLabel(element).addClass('invalid'); },
	unhighlight: function(element, errorClass) { findLabel(element).removeClass('invalid'); }
});

$.extend({
	visualEdit: function(vedit, options) {
		var elements = $('[vedit=' + vedit + ']');
		return typeof options === 'undefined' ? elements : elements.resource(options);
	}
});

$.fn.extend({
	msgbox: function(clazz, messages) {
		return this.each(function() {
			var container = $(this).empty()
				.attr('class', 'msg')
				.addClass(clazz);
			for (var i = 0; i < messages.length; i++) {
				container.append($('<label />').html(messages[i]));
			}
		});
	},

	msgprogress: function(messages) {
		return this.msgbox('progress', messages);
	},

	msgsuccess: function(messages) {
		var self = $(this);
		setTimeout(function() { self.fadeOut('slow'); }, 5000);
		return this.msgbox('success', messages);
	},

	msgerror: function(messages) {
		return this.msgbox('error', messages);
	},

	msgassert: function(success, messages) {
		return success ? this.msgsuccess(messages) : this.msgerror(messages);
	},

	enableInputs: function(enable) {
		return this.find(':input').enable(enable).end();
	},

	defaultValue: function(defaultValue) {
		function blur() {
			var defaultValue = $(this).attr('default');
			if ($(this).val() == defaultValue || $(this).val() == '')
				$(this).val(defaultValue).css('color', 'gray');
		}
		function focus() {
			var defaultValue = $(this).attr('default');
			if ($(this).val() == defaultValue)
				$(this).val('').css('color', 'black');
		}
		return this.each(function() {
			if (typeof defaultValue === 'undefined') {
				defaultValue = $(this).attr('default')
				if (defaultValue)
					$(this).focus(focus).blur(blur);
				else
					return;
			} else {
				focus.apply(this);
				$(this).attr('default', defaultValue);
			}
			blur.apply(this);
		});
	}
});

$.widget("ui.litebox", {
	options: {
		showCloseButton: true,
		autoShow: false
	},

	_create: function() {
		this._litebox = $(
			'<div style="display:none; position:relative; z-index:99999">' +
			'<div class="fixed overlay">' +
			'<div class="centered">' +
			'<div class="centered-outer">' +
			'<div class="centered-inner">' +
			'<div class="litebox">' +
			'</div>' +
			'</div>' +
			'</div>' +
			'</div>' +
			'</div>' +
			'</div>'
		).appendTo(document.body);
		var litebox = this._litebox.find('.litebox');
		var self = this;
		if (this.options.showCloseButton)
			litebox.append($('<a class="control close" href="#">&nbsp;</a>').click(function(event) {
				self.close();
				event.preventDefault();
			}));
		litebox.append(this.element);
		if (this.options.autoShow)
			this.show();
	},

	show: function() {
		this._litebox.show();
		this.element.show();
	},

	close: function() {
		this._litebox.hide();
		if (window.opera) {
			// force opera to redraw the layout
			var body = $(document.body).css('outline', 0);
			setTimeout(function(){body.css('outline', 'none');}, 10);
		}
	}
});

$.widget("ui.resource", {
	options: {
		showDelay: 0,
		hideDelay: 300,
		mode: '*',
		multiline: false,
		txtEdit: 'click to edit',
		txtCancel: 'Cancel',
		txtSubmit: 'Submit'
	},

	_create: function() {
		var self = this;
		if (!$.ui.resource._visualEdit)
			$.ui.resource._visualEdit = $('<div class="visualedit"><div class="arrow">&nbsp;</div></div>')
				.mouseover($.ui.resource._resetHideTimeout)
				.mouseout($.ui.resource._onMouseOut)
				.hide()
				.appendTo($(document).mousedown($.ui.resource._checkExternalClick).find('body'));
		var element = this.element.parents('a,button');
		if (element.length == 0)
			element = this.element;
		element
			.not('a,button').css('cursor', 'help').click(
				function(ev) { 
					if ($.ui.resource._visualEdit.data('owner') == self)
						self._onClick(ev);
				}).end()
			.mouseover(function(ev) { self._onMouseOver(ev); })
			.mouseout($.ui.resource._onMouseOut);
	},

	_openPopup: function() {
		var offset = this.element.offset();
		var self = this;
		$.ui.resource._visualEdit
			.data('owner', this)
			.children('div + *').remove().end()
			.append($('<a class="red nodecor" href="#" />').text(self.options.txtEdit).click(function(ev) { self._onClick(ev); }))
			.css('left', offset.left)
			.css('top', offset.top + this.element.innerHeight() + 7).show();
	},

	_onClick: function(ev) {
		var self = this;
		var container = $.ui.resource._visualEdit.attr('editMode', true).children('a').addClass('icon progress');
		jQuery.ajax({
			type: 'GET',
			url: this.options.url,
			data: { key: this.options.key },
			cache: false,
			success: function(text) {
				$('<form method="get">' +
				  (self.options.multiline ? '<textarea style="width:400px;height:57px" />' : '<input type="text" style="width:250px" />') +
				  '<div class="aright">' +
				  '<span class="fleft"><a class="icon cross red" href="#"></a></span>' +
				  '<button type="submit"><span></span></button>' +
				  '</div>' +
				  '</form>')
				.appendTo($.ui.resource._visualEdit.children('div + *').remove().end())
				.find('textarea,input').addClass('small').val(text).focus().end()
				.find('a').text(self.options.txtCancel).click(function(ev) { $.ui.resource._closePopup(); ev.preventDefault(); }).end()
				.find('button > span').text(self.options.txtSubmit).end()
				.submit(function(ev) { self._save(); ev.preventDefault(); });
			},
			error: function(request, status, error) { container.removeAttr('editMode').removeClass('progress').addClass('error'); }
		});
		ev.preventDefault();
	},

	_setValue: function(value) {
		$.visualEdit(this.element.attr('vedit')).each(function() {
			switch ($(this).data('resource').options.mode) {
				case '*':
					$(this).html(value);
					break;
				default:
					$(this).attr(this.options.mode, value);
					break;
			}
		});
	},

	_save: function() {
		var self = this;
		jQuery.ajax({
			type: 'POST',
			url: this.options.url,
			data: {
				action: this.options.action,
				id: this.options.id,
				key: this.options.key,
				value: $.ui.resource._visualEdit.find('textarea,input').val()
			},
			cache: false,
			success: function(data) { self._setValue(data); },
			complete: function(request, status) { $.ui.resource._closePopup(); }
		});
	},

	_onMouseOver: function(ev) {
		if ($.ui.resource._isEditMode())
			return;
		$.ui.resource._resetShowTimeout();
		$.ui.resource._resetHideTimeout();
		var self = this;
		var handler = (function () { self._openPopup(); });
		if (this.options.showDelay > 0)
			$.ui.resource._timerShow = setTimeout(handler, this.options.showDelay);
		else
			handler();
	}
});

$.ui.resource._checkExternalClick = function(ev) {
	var owner = $.ui.resource._visualEdit.data('owner');
	if ((owner && owner.element.get(0) != ev.target || $(ev.target).is('a,button')) && $(ev.target).parents('div.visualedit').length == 0)
		$.ui.resource._closePopup();
};

$.ui.resource._closePopup = function() {
	$.ui.resource._visualEdit.removeAttr('editMode').hide();
}

$.ui.resource._resetShowTimeout = function() {
	if ($.ui.resource._timerShow) {
		clearTimeout($.ui.resource._timerShow);
		$.ui.resource._timerShow = null;
	}
};

$.ui.resource._resetHideTimeout = function() {
	if ($.ui.resource._timerHide) {
		clearTimeout($.ui.resource._timerHide);
		$.ui.resource._timerHide = null;
	}
};

$.ui.resource._isEditMode = function() {
	return $.ui.resource._visualEdit.attr('editMode');
},

$.ui.resource._onMouseOut = function(event) {
	if ($.ui.resource._isEditMode())
		return;
	var owner = $.ui.resource._visualEdit.data('owner');
	if (owner != null && owner.options.hideDelay > 0)
		$.ui.resource._timerHide = setTimeout($.ui.resource._closePopup, owner.options.hideDelay);
	else
		$.ui.resource._closePopup();
	$.ui.resource._resetShowTimeout();
};

$.widget("ui.imageGallery", {
	options: {
	},

	_create: function() {
		var items = $('ul > li', this.element);
		if (items.size() > 1) {
			var self = this;
			var pager = $('<ol />').appendTo(this.element);
			var position = 0;
			jQuery.each(items, function(index) {
				if (!$(this).attr('src'))
					position = index;
				pager.append($('<li />').append($('<a href="#" />').text(index + 1).click(function(ev) { self.position(index); ev.preventDefault(); })));
			});
			$('.prev', this.element).click(function() { self.position(self.position() - 1); });
			$('.next', this.element).click(function() { self.position(self.position() + 1); });
			if (this.element.mousewheel)
				this.element.mousewheel(function(ev, d) { self.position(self.position() + (d > 0 ? -1 : 1)); ev.preventDefault(); });
			this.position(position);
		}
	},

	position: function(value) {
		if (typeof value === 'undefined')
			return this._position;
		if (value < 0 || value >= $('ul > li', this.element).size())
			return;
		var image = $('ul > li:eq(' + value + ')', this.element);
		var pager = $('ol > li:eq(' + value + ')', this.element);
		var src = image.attr('src');
		if (src) {
			var self = this;
			pager.addClass('progress');
			$('<img />').prependTo(image.removeAttr('src').children('ins')).load(function(ev) {
				pager.removeClass('progress');
				self.position(value);
			}).attr('src', src);
		} else {
			pager.siblings('.current').removeClass('current').end().addClass('current');
			image.siblings(':visible').fadeOut('fast', function() { image.fadeIn('fast'); });
		}
		$('.prev', this.element)[image.is(':first-child') ? 'attr' : 'removeAttr']('disabled', 'disabled');
		$('.next', this.element)[image.is(':last-child') ? 'attr' : 'removeAttr']('disabled', 'disabled');
		this._position = value;
	}
});

})(jQuery);

