/*
	Based on text reflection effect by Román Cortés
	See http://www.romancortes.com/ficheros/textreflection.html
	
	Author: Matt Barry
	URL: www.rakacreative.com
*/
(function($) {
	
	ReflectedText = function(el, options) {
		this.el = $(el);
		$.extend(this.options, options);
		this.render();
	};
	
	ReflectedText.prototype = {
		options: {
			// class name (prefix) for all the elements created
			className: 'text_reflection',
			// manually set the reflection text
			reflectionText: null,
			// use either html or text
			useTextOnly: true,
			// show waves, or ripples in the reflection
			wavesOnHover: true,
			// wave size
			waveHeight: 2,
			// wave length
			waveLength: 10,
			// speed of the animation
			intervalSpeed: 100
		},
		el: null,
		textWrapper: null,
		reflectWrapper: null,
		wavesInterval: null,
		stopWavesInterval: null,
		counter: 0,
		waveHeight: null,
		waveLength: null,
		create: function() {
			this.textWrapper = $("<div class=\"" + this.options.className + "_text_wrapper\"></div>");
			this.reflectWrapper = $("<div class=\"" + this.options.className + "\"></div>");
			this.reflectWrapper.css({
				display: 'inline-block',
				position: 'relative'
			});
			
			this.el.css({
				position: 'relative',
				zIndex: 3000
			}).wrap(this.reflectWrapper).after(this.textWrapper);
			
			this.reflectWrapper = this.el.parent();
			
			if (this.options.wavesOnHover) {
				var fn = this;
				this.el.hover(function() {
					fn.startWaves();
				}, function() {
					fn.stopWaves();
				});
			}
			return this;
		},
		render: function() {
			if (this.textWrapper === null) {
				this.create();
			};
			
			var text = this.options.reflectionText || this.el[(this.options.useTextOnly ? 'text' : 'html')]();
			var lineHeight = parseInt(this.el.css("lineHeight"), 10);
			this.textWrapper.html("");
			
			// This is assuming the line height is in pixels.
			for (var i=0; i < lineHeight; i++) {
				var subSpan = $("<div class=\"" + this.options.className + "_text_field\"> \
					<div class=\"" + this.options.className + "_text_field_inner\">" + text + "</div> \
				</div>");
				this.textWrapper.append(subSpan);
				subSpan.css({
					height: 1,
					left: 0,
					overflow: 'hidden',
					position: 'absolute',
					marginTop: i,
					whiteSpace: 'nowrap'
				});
				subSpan.find("div").css({
					marginTop: -(lineHeight - i)
				});
			};
			
			this.textWrapper.width(subSpan.width());
			this.reflectWrapper.width(subSpan.width());
			
			this.textWrapper.css({
				position: 'absolute',
				top: lineHeight,
				left: 0,
				height: lineHeight
			});
			
			return this;
		},
		destroy: function() {
			this.el.parent().find("." + this.options.className + "_text_wrapper").remove();
			this.el.unwrap();
			
			clearInterval(this.wavesInterval);
			clearInterval(this.stopWavesInterval);
			
			return this;
		},
		changeText: function(text) {
			this.el.html(text);
			this.render();
			return this;
		},
		startWaves: function() {
			var fn = this;
			this.counter = 0;
			
			var divs = fn.textWrapper.find("> div");
			this.waveLength = this.options.waveLength;
			this.waveHeight = this.options.waveHeight;
			
			clearInterval(fn.wavesInterval);
			clearInterval(fn.stopWavesInterval);
			
			this.wavesInterval = setInterval(function() {
				divs.each(function(indx) {
					var ml = Math.sin((fn.counter / fn.waveLength) * Math.PI * 2) * fn.waveHeight;
					$(this).css({
						marginLeft: Math.round(ml)
					})
					fn.counter += 1;
				});
			}, this.options.intervalSpeed);
		},
		stopWaves: function() {
			var fn = this;
			this.stopWavesInterval = setInterval(function() {
				fn.waveHeight *= 0.94;
				
				if (fn.waveHeight < 0.5) {
					clearInterval(fn.wavesInterval);
					clearInterval(fn.stopWavesInterval);
					var divs = fn.textWrapper.find("> div");
					divs.css("marginLeft", 0);
				}
			}, this.options.intervalSpeed);
		}
	};
	
	$.fn.reflectText = function(options) {
		$(this).each(function() {
			$(this).data('reflectedText', new ReflectedText(this, options));
		});
		return this;
	}
	
	$.fn.unreflectText = function() {
		$(this).each(function() {
			var reflectedText = $(this).data('reflectedText');
			if (reflectedText !== undefined) {
				reflectedText.destroy();
			};
		});
		return this;
	}
	
})(jQuery);
