/**
 * tippy
 * GNU Public License v3
 * 
 * @author Shawn Haworth
 * @version 0.6
 **/

Prototype.Tippy = Class.create({
	
	initialize: function(options) {
		this.tippyOptions = options;
		this.tippyStack = new Hash();
		this.cleanTrigger;
		this.liveTrigger;
		this.activeTippy;
		this.mzOffsetTop 		= -85;
		this.mzOffsetLeft 		= 15;
		this.mzOffsetLeftFlipped	= 10;
		this.ieOffsetTop 		= -92;
		this.ieOffsetLeft 		= 12;
		this.tippyContentWidth 	= 298;
	},
	
	add: function(incomingTrigger, tipContent) {
		this.cleanTrigger = incomingTrigger;
		this.liveTrigger = this.sanitizeElement(incomingTrigger);
		tipContent = this.sanitizeElement(tipContent);
		Event.observe(this.liveTrigger, 'mouseover', this.fireUpTippy.bind(this));
		Event.observe(this.liveTrigger, 'mouseout', this.shutDownTippy.bind(this));
		this.tippyStack.set(this.liveTrigger.id, tipContent);
	},
	
	sweep: function() {
		var tipTriggers = $$('img[rel=tiptrigger]');
		for (var i = 0; i < tipTriggers.length; i++) {
			this.add(tipTriggers[i].id, tipTriggers[i].readAttribute('tipcontent'));
		}
	},
		
	fireUpTippy: function(_e) {
		Event.extend(_e);
		var tipper = _e.element();
		var pointerX = _e.pointerX();
		var pointerY = _e.pointerY();
		var dirtyTipper = tipper;
		var tipperPosition = tipper.cumulativeOffset('body');
		var tipperLeft = tipperPosition[0];
		var tipperTop = tipperPosition[1];
		var tipcontent = $(this.findTipContent(tipper.id));
		var tipOffsetLeft = 0;
		var tipOffsetTop = 0;
		var tipFlip = false;
		if (this.tippyOutOfBounds(dirtyTipper)) {
			tipcontent = this.flipTipperContent(tipcontent);
			if (util.getBrowserName() == 'MZ') {
				tipOffsetLeft = this.mzOffsetLeftFlipped - this.tippyContentWidth;
			} else {
				tipOffsetLeft = this.ieOffsetLeft - this.tippyContentWidth;
			}
			tipFlip = true;
		} else {
			tipcontent = this.resetTipperContent(tipcontent);
		}
		this.activeTippy = tipcontent;
		tipcontent.absolutize();
		if (tipFlip) {
			util.getBrowserName() == 'MZ' ? tipcontent.clonePosition(dirtyTipper, 
										{offsetTop: this.mzOffsetTop, offsetLeft: tipOffsetLeft}) 
										: 
										tipcontent.clonePosition(dirtyTipper, 
										{offsetTop: this.ieOffsetTop, offsetLeft: tipOffsetLeft});
		} else {
			util.getBrowserName() == 'MZ' ? tipcontent.clonePosition(dirtyTipper, 
										{offsetTop: this.mzOffsetTop, offsetLeft: this.mzOffsetLeft}) 
										: 
										tipcontent.clonePosition(dirtyTipper, 
										{offsetTop: this.ieOffsetTop, offsetLeft: this.ieOffsetLeft});
		}
		tipcontent.show();
		this.cleanUpTippys(tipper);
	},
	
	tippyOutOfBounds: function(tipper) {
		var tipperViewportPosition = tipper.viewportOffset();
		//var documentViewportWidth = document.viewport.getWidth();
		var documentViewportWidth = $(document.body).getWidth(); 
		var calculatedViewportWithTippy = (parseInt(tipper.getWidth()) + 
										   parseInt(tipperViewportPosition[0]) + 
										   this.tippyContentWidth);
		if (calculatedViewportWithTippy > documentViewportWidth) {
			return true;
		}
		return false;
	},
	
	flipTipperContent: function(tipcontent) {
		var contentDescendants = tipcontent.descendants();
		var contentWrapper = contentDescendants[3];
		var topSection = contentDescendants[1];
		var middleSection = contentDescendants[2];
		var bottomSection = contentDescendants.pop();
		contentWrapper.removeClassName('content_wrapper');
		contentWrapper.addClassName('content_wrapper_flipped');
		topSection.removeClassName('tippy_top');
		topSection.addClassName('tippy_top_flipped');
		middleSection.removeClassName('tippy_content');
		middleSection.addClassName('tippy_content_flipped');
		bottomSection.removeClassName('tippy_bottom');
		bottomSection.addClassName('tippy_bottom_flipped');
		return tipcontent;
	},
	
	resetTipperContent: function(tipcontent) {
		var contentDescendants = tipcontent.descendants();
		var contentWrapper = contentDescendants[3];
		var topSection = contentDescendants[1];
		var middleSection = contentDescendants[2];
		var bottomSection = contentDescendants.pop();
		contentWrapper.removeClassName('content_wrapper_flipped');
		contentWrapper.addClassName('content_wrapper');
		topSection.removeClassName('tippy_top_flipped');
		topSection.addClassName('tippy_top');
		middleSection.removeClassName('tippy_content_flipped');
		middleSection.addClassName('tippy_content');
		bottomSection.removeClassName('tippy_bottom_flipped');
		bottomSection.addClassName('tippy_bottom');
		return tipcontent;
	},
	
	shutDownTippy: function(_e) {
		Event.extend(_e);
		var tipper = _e.element();
		var tipcontent = $(this.findTipContent(tipper.id));
		var mouseTarget = _e.relatedTarget || _e.toElement;
		if (mouseTarget) {
			var mouseDescendantOfTippy = mouseTarget.descendantOf(tipcontent.id);
			if (!mouseDescendantOfTippy) {
				tipcontent.hide();
			} else {
				Event.observe(tipcontent, 'mouseout', this.shutDownTippyContent.bind(this));
			}
		}
	},
	
	shutDownTippyContent: function(_e) {
		Event.extend(_e);
		var mouseTarget = _e.relatedTarget || _e.fromElement;
		if (mouseTarget) {
			var mouseDescendantOfTippy = mouseTarget.descendantOf(this.activeTippy.id);
			if (!mouseDescendantOfTippy) {
				this.activeTippy.hide();
			}
		}
	},
	
	cleanUpTippys: function(tippyStays) {
		this.tippyStack.each(
			function (tippyItem) {
				if (tippyItem.key != tippyStays.id) {
					tippyItem.value.hide();
				}
			}
		);
	},
	
	findTipContent: function(tipperID) {
		return this.tippyStack.get(tipperID);
	},
		
	sanitizeStack: function() {
		
	},
	sanitizeElement: function(incoming) {
		return (typeof(incoming) == 'string')?$(incoming):incoming;
	}

});
