/*
 * jQuery UI @VERSION
 *
 * Copyright (c) 2008 Paul Bakaus (ui.jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;(function($) {

$.kui = {
	plugin: {
		add: function(module, option, set) {
			var proto = $.kui[module].prototype;
			for(var i in set) {
				proto.plugins[i] = proto.plugins[i] || [];
				proto.plugins[i].push([option, set[i]]);
			}
		},
		call: function(instance, name, args) {
			var set = instance.plugins[name];
			if(!set) { return; }
			
			for (var i = 0; i < set.length; i++) {
				if (instance.options[set[i][0]]) {
					set[i][1].apply(instance.element, args);
				}
			}
		}	
	},
	cssCache: {},
	css: function(name) {
		if ($.kui.cssCache[name]) { return $.kui.cssCache[name]; }
		var tmp = $('<div class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
		
		//if (!$.browser.safari)
			//tmp.appendTo('body'); 
		
		//Opera and Safari set width and height to 0px instead of auto
		//Safari returns rgba(0,0,0,0) when bgcolor is not set
		$.kui.cssCache[name] = !!(
			(!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) || 
			!(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
		);
		try { $('body').get(0).removeChild(tmp.get(0));	} catch(e){}
		return $.kui.cssCache[name];
	},
	disableSelection: function(el) {
		$(el).attr('unselectable', 'on').css('MozUserSelect', 'none');
	},
	enableSelection: function(el) {
		$(el).attr('unselectable', 'off').css('MozUserSelect', '');
	},
	hasScroll: function(e, a) {
		var scroll = /top/.test(a||"top") ? 'scrollTop' : 'scrollLeft', has = false;
		if (e[scroll] > 0) return true; e[scroll] = 1;
		has = e[scroll] > 0 ? true : false; e[scroll] = 0;
		return has;
	},
	ui : {
	    bubbles: {

			randomize: function() {

				var widthMax = 185,
					widthAdd = 25,
					heightAddPerLine = 4,
					heightAdd = 30,
					speed = 10;

	            
				setTimeout(function() { $('#entity_stories').css('display', 'block'); }, speed);


				$('#entity_stories .bubble').each(function(i) {

					var currentSizeX = parseInt(Math.floor(Math.random() * 30) + 71, 10),
							currentSizeY = parseInt(Math.floor(Math.random() * 60) + 41, 10),
							currentPosX = parseInt(Math.floor(Math.random() * 51), 10),
							currentPosY = parseInt(Math.floor(Math.random() * 41), 10),
							currentFontSize = currentSizeX,
							zIndex = parseInt(Math.floor(Math.random() * 5000) + 100, 10);

					currentSizeX = parseInt(parseFloat(currentSizeX / 100) * widthMax, 10);
					currentFontSize = (currentFontSize < 80 ? 80 : currentFontSize);

					if (parseInt(parseInt(currentSizeX, 10) + parseInt(currentPosX, 10), 10) > parseInt(widthMax, 10)) {

						if (parseInt(currentSizeX, 10) > parseInt(widthMax, 10)) {
							currentSizeX = widthMax;
						}

						if (parseInt(parseInt(currentSizeX, 10) + parseInt(currentPosX, 10), 10) > parseInt(widthMax, 10)) {
							currentPosX = ((-currentSizeX) + currentPosX) - (-widthMax) - currentPosX;
						}

						if (currentPosX < 0) {
							currentPosX = 0;
						}
					}

					$('body').append('<p id="tempBubbleParagraph" style="background-color:pink; font-size: ' + currentFontSize + '%; width:' + currentSizeX + 'px;">' + $(this).children('p').get(0).innerHTML + '</p>');

					$(this).children('p').css({ left: 0, right: 0 }).animate({
						left: currentPosX,
						top: currentPosY,
						width: currentSizeX + 'px'
					}, {
						duration: speed,
						easing: 'easeOutElastic'
					}).css('z-index', zIndex + 1).css('fontSize', currentFontSize + "%");

					currentSizeY = $("#tempBubbleParagraph").height();
					currentSizeX = $("#tempBubbleParagraph").width();

					$("#tempBubbleParagraph").remove();

					$(this).children('img').css({ left: 0, right: 0 }).animate({
						width: currentSizeX + widthAdd + "px",
						height: currentSizeY + (heightAddPerLine * parseInt(currentSizeY / 15, 10)) + heightAdd + "px",
						left: currentPosX,
						top: currentPosY
					}, {
						duration: speed,
						easing: 'easeOutElastic'
					}).css('z-index', zIndex);

					speed = 500;
				});
			},

			getBubblesData: function() {
				var nn = $.j('Type[GetBubblesData]:parent', arguments),
					isStories = false;

				$('#entity_stories .bubble').each(function(i) {
					if (nn.DataSet['text' + i.toString()] !== '') {
						isStories = true;
						$(this).children('p').get(0).innerHTML = (nn.DataSet['text' + i.toString()]).replace(/\[#[0-9]\]/g, '') + '' + nn.DataSet['profile' + i.toString()];
					}
				});

				if (!isStories) {
					$('#entity_stories').hide();
				}

				$.kui.ui.bubbles.randomize();

			},

			fetchData: function() {
				var payload = { GetBubblesData: { whatever: parseInt(0, 10)} };
				$.km.data.doJsonPost('ui.bubbles:getBubblesData', payload);
			}
		}
	}
};


/** jQuery core modifications and additions **/

var _remove = $.fn.remove;
$.fn.remove = function() {
	$("*", this).add(this).triggerHandler("remove");
	return _remove.apply(this, arguments );
};

// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
// created by Scott González and Jörn Zaefferer
function getter(namespace, plugin, method) {
	var methods = $[namespace][plugin].getter || [];
	methods = (typeof methods == "string" ? methods.split(/,?\s+/) : methods);
	return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
	var namespace = 'k' + name.split(".")[0];
	name = name.split(".")[1];
	
	// create plugin method
	$.fn[name] = function(options) {
		var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);
		
		if (isMethodCall && getter(namespace, name, options)) {
			var instance = $.data(this[0], name);
			return (instance ? instance[options].apply(instance, args)
				: undefined);
		}
		
		return this.each(function() {
			var instance = $.data(this, name);
			if (isMethodCall && instance && $.isFunction(instance[options])) {
				instance[options].apply(instance, args);
			} else if (!isMethodCall) {
				$.data(this, name, new $[namespace][name](this, options));
			}
		});
	};
	
	// create widget constructor
	$[namespace][name] = function(element, options) {
		var self = this;
		
		this.widgetName = name;
		this.widgetBaseClass = namespace + '-' + name;
		
		this.options = $.extend({}, $.widget.defaults, $[namespace][name].defaults, options);
		this.element = $(element)
			.bind('setData.' + name, function(e, key, value) {
				return self.setData(key, value);
			})
			.bind('getData.' + name, function(e, key) {
				return self.getData(key);
			})
			.bind('remove', function() {
				return self.destroy();
			});
		this.init();
	};
	
	// add widget prototype
	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
};

$.widget.prototype = {
	init: function() {},
	destroy: function() {
		this.element.removeData(this.widgetName);
	},
	
	getData: function(key) {
		return this.options[key];
	},
	setData: function(key, value) {
		this.options[key] = value;
		
		if (key == 'disabled') {
			this.element[value ? 'addClass' : 'removeClass'](
				this.widgetBaseClass + '-disabled');
		}
	},
	
	enable: function() {
		this.setData('disabled', false);
	},
	disable: function() {
		this.setData('disabled', true);
	}
};

$.widget.defaults = {
	disabled: false
};


/** Mouse Interaction Plugin **/

$.kui.mouse = {
	mouseInit: function() {
		var self = this;
	
		this.element.bind('mousedown.'+this.widgetName, function(e) {
			return self.mouseDown(e);
		});
		
		// Prevent text selection in IE
		if ($.browser.msie) {
			this._mouseUnselectable = this.element.attr('unselectable');
			this.element.attr('unselectable', 'on');
		}
		
		this.started = false;
	},
	
	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);
		
		// Restore text selection in IE
		($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
	},
	
	mouseDown: function(e) {
		// we may have missed mouseup (out of window)
		(this._mouseStarted && this.mouseUp(e));
		
		this._mouseDownEvent = e;
		
		var self = this,
			btnIsLeft = (e.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(e.target).parents().add(e.target).filter(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this.mouseCapture(e)) {
			return true;
		}
		
		this._mouseDelayMet = !this.options.delay;
		if (!this._mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				self._mouseDelayMet = true;
			}, this.options.delay);
		}
		
		if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
			this._mouseStarted = (this.mouseStart(e) !== false);
			if (!this._mouseStarted) {
				e.preventDefault();
				return true;
			}
		}
		
		// these delegates are required to keep context
		this._mouseMoveDelegate = function(e) {
			return self.mouseMove(e);
		};
		this._mouseUpDelegate = function(e) {
			return self.mouseUp(e);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
		
		return false;
	},
	
	mouseMove: function(e) {
		// IE mouseup check - mouseup happened when mouse was out of window
		if ($.browser.msie && !e.button) {
			return this.mouseUp(e);
		}
		
		if (this._mouseStarted) {
			this.mouseDrag(e);
			return false;
		}
		
		if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
			this._mouseStarted =
				(this.mouseStart(this._mouseDownEvent, e) !== false);
			(this._mouseStarted ? this.mouseDrag(e) : this.mouseUp(e));
		}
		
		return !this._mouseStarted;
	},
	
	mouseUp: function(e) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
		
		if (this._mouseStarted) {
			this._mouseStarted = false;
			this.mouseStop(e);
		}
		
		return false;
	},
	
	mouseDistanceMet: function(e) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - e.pageX),
				Math.abs(this._mouseDownEvent.pageY - e.pageY)
			) >= this.options.distance
		);
	},
	
	mouseDelayMet: function(e) {
		return this._mouseDelayMet;
	},
	
	// These are placeholder methods, to be overriden by extending plugin
	mouseStart: function(e) {},
	mouseDrag: function(e) {},
	mouseStop: function(e) {},
	mouseCapture: function(e) { return true; }
};

$.kui.mouse.defaults = {
	cancel: null,
	distance: 1,
	delay: 0
};


$(window).bindEvent({
    event: 'ui.bubbles:getBubblesData',
    callback: [
			{ n: '$.kui.ui.bubbles', f: 'getBubblesData' }
		]
});

})(jQuery);

