/****
* print_r - similar to PHP print_r
*/
function print_r(theObj,indent){
	  var output="";
	  if (indent == undefined) { indent = "  "; } else { indent += "  "; }
	  if(theObj.constructor == Array || theObj.constructor == Object) {
		for(var p in theObj){
		  if(theObj[p].constructor == Array|| theObj[p].constructor == Object){
			  var type = (theObj[p].constructor == Array) ? "Array" : "Object";
			  output += indent+"["+p+"]("+type+")=>\n";
			  output += print_r(theObj[p],indent);
		  } else { output += indent+"["+p+"]:"+theObj[p]+"\n"; }
		}
	  }
	  return output;
}

/* JQUERY plugins */
(function($) {
	$.fn.extend({
		fctooltip: function(options) {
			var defaults = {
				offset: [0, 0],
				// http://flowplayer.org/tools/tooltip/index.html - positioning, a nev sorrend kotott
				position: 'top center',
				tipClass: 'tooltip',
				layout: '<div />'
			};
			var options = $.extend(defaults, options);

			var offsets = {
				'top left': 	[-10, 20],
				'top center':	[-10, 0],
				'top right':	[-10, -20],
				'center right':	[0, 10],
				'bottom right': [10, -20],
				'bottom center': [10, 0],
				'bottom left':	[10, 20],
				'center left':	[0, -10]
			}

			ofstmp = offsets[options.position];
			ofstmp[0] += options.offset[0];
			ofstmp[1] += options.offset[1];
			options.offset = ofstmp;

			this.each(function(index, element) {
				$(element).tooltip({
					tipClass: options.tipClass,
					layout: options.layout,
					effect: 'fade',
					fadeOutSpeed: 200,
					fadeInSpeed: 200,
					position: options.position,
					offset: options.offset,
					onBeforeShow: function(e) {
						var tip = this.getTip();
						var conf = this.getConf();

						tip.html(tip.html().replace(/(\\n|\n)/g, '<br />'));

						if (tip.find('span.arrow').length == 0) {
							tip.prepend('<span class="arrow"></span>');
							if (conf.position[0] == 'center' && conf.position[1] == 'left') {
								tip.prepend('<span class="arrow" style="right: -17px; margin-top: -7px; border-left-color: #757679;"></span>');
							}

							if (conf.position[0] == 'top' && conf.position[1] == 'left') {
								tip.prepend('<span class="arrow" style="bottom: -17px; right: -1px; border-top-color: #757679;"></span>');
							}

							if (conf.position[0] == 'top' && conf.position[1] == 'center') {
								tip.prepend('<span class="arrow" style="bottom: -17px; margin-left: -7px; border-top-color: #757679;"></span>');
							}

							if (conf.position[0] == 'top' && conf.position[1] == 'right') {
								tip.prepend('<span class="arrow" style="bottom: -17px; left: 1px; border-top-color: #757679;"></span>');
							}
						} else {
							tip.find('span.arrow').attr('class', 'arrow');
						}

						var rclass = conf.position.join('');
						if (rclass) {
							tip.find('.arrow').addClass('arrow-'+rclass);
						}
					}
				}).dynamic({
					bottom: {
						direction: "down",
						bounce: true
					}
				});
			});

			return this;
		},

		// FIXME, this quick&dirty plugin is poorly designed, feel free to improve it and add a proper math :-)
		resizablePane: function(options) {
			var defaults = {};
			var options = $.extend(defaults, options);

			this.resizable({
				handles: 'e',
				containment: 'parent',
				resize: function(event, ui) {
					var pw = $(this).parent().width();
					var tw = $(this).width() - ($(this).outerWidth(true) - $(this).width()) - 10;	// 10, resize handle, FIXME?
					var sw = pw - tw - ($(this).next().outerWidth(true) - $(this).next().width());

					tw = tw / pw * 100 - 2;	// -2, lack of good math :-)
					sw = sw / pw * 100 - 2;

					$(this).next().css({
						width: sw+'%'
					});

					$(this).css({
						width: tw+'%'
					});
				}
			}).find('.ui-resizable-e').addClass('fc-resizable-pane');

			return this;
		},

		searchText: function(options) {
			// like HTML5's textinput placeholder
			var defaults = {
				color: '#aaa',
				text: ''
			}
			var options = $.extend(defaults, options);

			this.attr('placeholder', options.text);
			this.attr('placeholdercolor', options.color);
			this.attr('currentcolor', this.css('color'));

			// leak...
			this.blur(function() {
				if ($(this).val().replace(/ /g, '') == '') {
					$(this).css('color', $(this).attr('placeholdercolor'));
					$(this).val($(this).attr('placeholder'));
				}
			});

			this.focus(function() {
				if ($(this).val() == $(this).attr('placeholder')) {
					$(this).val('');
					$(this).css('color', $(this).attr('currentcolor'));
				}
			});

			this.parents('form').submit(function() {
				$(this).find('input[placeholder]').each(function(index, element) {
					if ($(element).attr('placeholder') == $(element).val()) {
						$(element).val('');
					}
				});
			});

			if (this.val() == '') {
				this.val(options.text);
				this.css('color', options.color);
			}

			return this;
		},

		normalizeHeight: function(options) {
			var defaults = {
				groupBy: 0
			}
			var options = $.extend(defaults, options);

			if (options.groupBy > 0) {
				var length = this.length;
				for (i = 0; i < length; i = i + options.groupBy) {
					if (i == 0) {
						$($(this).selector+':lt('+options.groupBy+')').normalizeHeight();
					} else {
						$($(this).selector+':gt('+(i-1)+'):lt('+options.groupBy+')').normalizeHeight();
					}
				}
			} else {
				var maxheight = 0;
				$(this).map(function() {
					if (maxheight < $(this).height()) {
						maxheight = $(this).height();
					}
				});

				$(this).height(maxheight);
			}

			return this;
		},

		preventDoubleClick: function(options) {
			// crap hack to prevent double clicking(posting)
			var defaults = {
				message: '',
				duration: 500
			}
			var options = $.extend(defaults, options);

			this.click(function(event) {
				var o = this;
				var prevMessage = $(this).get(0).tagName.toLowerCase() == 'button' ? $(this).html() : $(this).val();

				setTimeout(function(o, options) {
					return function() {
						if (options.message) {
							if ($(o).get(0).tagName.toLowerCase() == 'button') {
								$(o).html('<span class="ui-button-text">'+options.message+'</span>');
							} else {
								$(o).val(options.message);
							}
						}
						o.disabled = true;
					}
				}(o, options), 1);

				if (options.duration > 0) {
					setTimeout(function(o, prevMessage) {
						return function() {
							o.disabled = false;
							if ($(o).get(0).tagName.toLowerCase() == 'button') {
								$(o).html(prevMessage);
							} else {
								$(o).val(prevMessage);
							}
						}
					}(o, prevMessage), options.duration);
				}
			});

			return this;
		},

		clearForm: function(options) {
			// adopted, extended
			var defaults = {
				skip: ''
			}

			var options = $.extend(defaults, options);

			return this.not(options.skip).each(function() {
				var type = this.type, tag = this.tagName.toLowerCase();
				if (tag == 'form') {
					return $(':input', this).clearForm(options);
				}

				if (type == 'text' || type == 'password' || type == 'hidden' || tag == 'textarea') {
					this.value = '';
				} else if (type == 'checkbox' || type == 'radio') {
					this.checked = false;
				} else if (tag == 'select') {
					this.selectedIndex = -1;
				}
			});
		},

		fillParent: function(options) {
			var defaults = {
				nPerRow: 6,
				onTop: function(index, element) {},
				onRemainder: function(index, element) {}
			}

			var options = $.extend(defaults, options);

			var length = this.length;
			if (length == options.nPerRow) {
				var remainders = length;
			} else {
				var remainders = length % options.nPerRow;
			}

			this.each(function(index, element) {
				var ow = $(element).outerWidth(true);
				var w = $(element).width();
				var diff = ow - w;

				if (index < length - remainders) {
					var tabWidth = $(element).parent().width() / options.nPerRow - diff - 1;
					var callback = options.onTop;
				} else {
					var tabWidth = $(element).parent().width() / remainders - diff - 1;
					var callback = options.onRemainder;
				}

				$(element).width(tabWidth+'px');

				callback(index, element);
			});

			return this;
		}
	});
})(jQuery);
