var ScrollingText = (function() {
	
	function getOvershootInterpolation(t) {
	    t -= 1.0;
	    return t * t * ((2.0 + 1) * t + 2.0) + 1.0;   
	}
	
	function getDecelerateInterpolator(t) {
		if (1.0 == 1.0) {
			return (1.0 - (1.0 - t) * (1.0 - t));
		} else {
			return (1.0 - Math.pow((1.0 - t), 2 * mFactor));
		}
	}
	
	function getLinearInterpolator(t) {
	    return t;
	}
	
	var constructor = function() {
		this.canvasXSize = 1200;
		this.canvasYSize = 60;
		this.interval = 15; // amount to sleep per frame
		this.myText = "Replace this text...";
		
		this.dx = 2;
		this.x = 0;
		this.y = 30; // just a default..
		this.ctx;
		this.textSize = 0;
		
		this.gFontColor;

		this.slideDuration = 500;
		this.xDirection = 1.0;
		
		this.interpolator;
		this.terminate = false;
		this.currentIndex = 0;
		this.texts = new Array();
		
		this.myX = 0;

		this.startTs = undefined;
		this.startPos = undefined;
		this.amountToMove = undefined;
		this.stopPoint = undefined;
		
		this.isRunning = false;
	};
	
	constructor.prototype.start = function() {
		// Iterate over our list of texts indefinitely. For each text, perform:
		// 1) Slide in animation
		// 2) Display for (duration)
		// 3) Slide out.
		if(!this.isRunning) {
			console.log("IN start, BREAKING!");
			return;
		}
			
		this.textSize = this.ctx.measureText(this.texts[this.currentIndex]).width;
		if(this.xDirection == 1.0) {
			this.myX = 0-this.textSize*2;
		} else {
			this.myX = this.canvasXSize + this.textSize*2;
		}
		this.stopPoint = (this.canvasXSize / 2) - (this.textSize/2);
		this.ctx.shadowBlur = 8;
		this.slideIn();
	};
	
	constructor.prototype.slideIn = function() {
		
		this.startTs = new Date().getTime();
		this.startPos = this.myX;
		this.amountToMove = this.stopPoint - this.startPos;
	
		this.drawSlideIn();
	};
	
	constructor.prototype.drawSlideIn = function() {
		var that = this;
		
		//Clear Canvas
		this.ctx.clearRect(0, 0, this.canvasXSize, this.canvasYSize);
	    
	    // Calculate new position
	    var diff = new Date().getTime() - this.startTs;	
	    var currentAmount = diff/this.slideDuration;	    
	
	    var amountMoved = this.interpolator(currentAmount);
	    this.myX = this.startPos + (this.amountToMove * amountMoved);
	    
	    this.ctx.fillText(this.texts[this.currentIndex], this.myX, this.y);
		// Check if we should stop
	    if(currentAmount >= 1.0) {	    	
	    	this.ctx.shadowBlur = 3;
	    	this.stationary();
	    } else {
	    	setTimeout(function() {
	    		that.drawSlideIn();
	    	}, 15);
	    }
	};
	
	constructor.prototype.stationary = function() {
		var that = this;
		this.ctx.clearRect(0, 0, this.canvasXSize, this.canvasYSize);
		this.ctx.fillText(this.texts[this.currentIndex], this.myX, this.y);
		this.ctx.shadowBlur = 8;
	
		setTimeout(function() {
			that.slideOut();
			}
			, this.showDuration);
		
	};
	
	constructor.prototype.slideOut = function() {
		
		
		this.startTs = new Date().getTime();
		this.startPos = this.myX;
		this.stopPoint = undefined;
		if(this.xDirection == 1.0) {
			this.stopPoint = this.canvasXSize + this.textSize*2;
		} else {
			this.stopPoint = 0 - this.textSize*2
		}
		
		this.amountToMove = this.stopPoint - this.startPos;
		
		this.drawSlideOut();
		
	};
	
	constructor.prototype.drawSlideOut = function() {
		var that = this;
		
		//Clear Canvas
		this.ctx.clearRect(0, 0, this.canvasXSize, this.canvasYSize);
	    
	    // Calculate new position
	    var diff = new Date().getTime() - this.startTs;	
	    var currentAmount = diff/this.slideDuration;
	    var amountMoved = 1.0 - this.interpolator(1.0 - currentAmount); // Reverse the interpolator when sliding out.
	    this.myX = this.startPos + (this.amountToMove * amountMoved);
	    
	    // Draw the text
	    this.ctx.fillText(this.texts[this.currentIndex], this.myX, this.y);
	    
		if(currentAmount > 1.0) {
	    	if(this.currentIndex+1 == this.texts.length) {
	    		this.currentIndex = 0;
	    	} else {
	    		this.currentIndex++;
	    	}	    	
	    	// Restart animation with next text item
	    	this.start();
		} else {
			setTimeout(
					function() {
						that.drawSlideOut(); 
					}
					, 15);
		}	
	};
		
	constructor.prototype.initScrollingText = function(text, fontSize, fontColor, fontName, fontStyleStr, direction, width, height, pShowDuration, pSlideDuration, interpolatorName, canvasNumber) {
		this.showDuration = parseInt(pShowDuration);
		this.slideDuration = parseInt(pSlideDuration);
		
		if(interpolatorName == 'overshoot') {
			this.interpolator = getOvershootInterpolation;
		} else if(interpolatorName == 'decelerate') {
			this.interpolator = getDecelerateInterpolator;
		} else if(interpolatorName == 'linear') {
			this.interpolator = getLinearInterpolator;
		} else {
			this.interpolator = getDecelerateInterpolator;
		}
		
	    //Get Canvas Element
		this.ctx = document.getElementById('canvas_' + canvasNumber).getContext('2d');
		
	    // Set canvas width to iframe width - 1. The -1 is due to error occuring if we try to draw text with the start point outside of the canvas. 
		this.canvasXSize = parseInt(width);
	    document.getElementById('canvas_' + canvasNumber).setAttribute("width", width);
			
	    this.canvasYSize = parseInt(height);
		document.getElementById('canvas_' + canvasNumber).setAttribute("height", height);
			
		// y => where in vertical of the canvas to draw the text. Half the canvas + some padding based
		// on height in pixels of the font.
		var fontHeight = fontSize.substring(0, fontSize.length-2); // strip off the "px"
		this.y = (height / 2) + (fontHeight/4);
	    
		
		//dx = textSpeed * 4;
		
		if(direction == 'rtl') {
			this.xDirection = -1.0;
		}
		
		// Set font styling
		this.ctx.font = fontStyleStr + ' ' + fontSize + ' ' + fontName; 
		this.ctx.fillStyle = fontColor;
		this.ctx.shadowBlur = 5;
		this.ctx.shadowColor = 'lightgrey';

		if(!text) {
			text = 'This is the first text;This is the second text;This is the third text';
		}
		this.texts = text.split(';'); 
		
		this.isRunning = true;
		
		this.start();
	};
	
	return constructor;
	
})();