/**
 * @author trixta
 */
(function($){
	var posMatrix = {
		left: 0,
		top: 0,
		center: 1,
		middle: 1,
		right: 2,
		bottom: 2,
		sameleft: 3,
		sametop: 3,
		sameright: 4,
		samebottom: 4
	};
	function getPosition(aroundElement, posElement, offset, type, pos, fitToView){
		var params = (type == 'horizontal') ? ['Left', 'outerWidth', 'width'] : ['Top', 'outerHeight', 'height'], 
			ret, 
			viewPort = {};
		pos = isFinite(pos) ? pos : posMatrix[pos];
		
		switch(pos) {
			case 0:
				ret = offset[params[0].toLowerCase()] - posElement[params[1]]();
				break;
			case 1:
				ret = offset[params[0].toLowerCase()] + (aroundElement[params[1]]() / 2) - (posElement[params[1]]() / 2);
				break;
			case 2:
				ret = offset[params[0].toLowerCase()] + aroundElement[params[1]]();
				break;
			case 3:
				ret = offset[params[0].toLowerCase()];
				break;
			case 4:
				ret = offset[params[0].toLowerCase()] + aroundElement[params[1]]() - posElement[params[1]]();
				break;
		}
		
		if(fitToView){
			viewPort.start = $(window)['scroll'+ params[0]]();
			viewPort.end = viewPort.start + $(window)[params[2]]();
			if(viewPort.start > ret && pos < 2){
				pos = 2;
				ret = getPosition(aroundElement, posElement, offset, type, pos)[0];
			} else if(viewPort.end < ret + posElement[params[1]]() && pos > 0){
				pos = 0;
				ret = getPosition(aroundElement, posElement, offset, type, pos)[0];
			}
		}
		
		return [ret, pos];
	}

	$.posAround = function(posElement, aroundElement, o){
		o = $.extend({}, $.posAround.defaults, o);
		posElement = $(posElement);
		var offset,
			css 			= {}
		;
		if(isFinite(aroundElement.pageX) && isFinite(aroundElement.pageY)){
			offset ={
				top: aroundElement.pageY,
				left: aroundElement.pageX
			};
			aroundElement.outerWidth = function(){
				return o.mouseWidth;
			};
			aroundElement.outerHeight = function(){
				return o.mouseHeight;
			};
		} else {
			aroundElement = $(aroundElement);
			
			offset = aroundElement.offset();
		}
		
		css.left = getPosition(aroundElement, posElement, offset, 'horizontal', o.horizontal, o.fitToView);
		css.top = getPosition(aroundElement, posElement, offset, 'vertical', o.vertical, o.fitToView);
		$.posAround.setPosClass(posElement, css);
		return css;

	};
	$.posAround.setPosClass = function(posElement, css){
		$.posAround.cleanUpPosClass(posElement);
		posElement.addClass('positionaround-'+css.left[1] +'-'+ css.top[1]);
		css.top = Math.max(0,css.top[0]);
//		css.top = css.top[0];
		css.left = css.left[0];
	};
	$.posAround.cleanUpPosClass = function(posElement){
		var classes = $.grep(posElement.attr('class').split(' '), function(classVal){
			return (classVal.indexOf('positionaround-') !== 0);
		});
		posElement.attr('class', classes.join(' '));
	};
	$.posAround.defaults = {
		horizontal: 'right', //left | center | right | same
		vertical: 'bottom', // bottom | middle | top | same
		fitToView: true,
		mouseWidth: 15,
		mouseHeight: 20
	};
})(jQuery);
