﻿/**************************************************************

	Script		: mooTicker
	Version		: 2.0
	Author		: David Walsh (modified by Liam Smart)
	Licence		: Open Source MIT Licence
	Usage		: window.addEvent('domready', function(){
					  //call mooTicker
					  var initTicker = new mooTicker({
						  container: $('mooTicker'),//where the data be taken from/or if empty, put into to?
						  delay: 100,//time before next character is added
						  variance: 50,//No one types at the same speed. Variance allows for random letter delay changes
						  backChar: '|',//Which character signifies a backspace?
						  backDelay: 30,//How quickly should the typewriter delete?
						  maxChars: null,//set a limit to amount of characters allowed (null = no limit)
						  nxtMsgDelay: null,//time between displaying next message in seconds (null =  auto calculate)
						  typoLength: 6,//max length you want typos to be
						  nextMsgPause: null//pause before showing next message (in seconds)
					  });
				  });

**************************************************************/

//start mooTicker class
var mooTicker = new Class({

	//implements
	Implements: [Options],

	//options
	options:{
		counter: 0,//which message to start at (default 0)
		delay: 50,//time before next character is added
		backDelay: 30,//How quickly should the typewriter delete?
		variance: 100,//No one types at the same speed. Variance allows for random letter delay changes
		message: 'This is output from the Typewriter class|||||||||||||||| modified Typewriter class that supports multiple strings',//default string
		backChar: '|',//Which character signifies a backspace?
		nxtMsgDelay: 0.5,//time between displaying next message in seconds (null =  auto calculate)
		maxChars: null,//set a limit to amount of characters allowed (null = no limit)
		strSplitter: '~',//what characters to split the string with
		//typoLength: 5,//max length you want typos to be
		nextMsgPause: 0.5//pause before showing next message (in seconds)
	},

	//initialization
	initialize: function(options){
		//set options
		this.setOptions(options);
		//set variables
		this.cursor = 0;
		this.initString;
		this.splitString;
		//start mooTicker
		if($$(this.options.container).length > 0){this.start();};
	},
	
	//start mooTicker
	start: function(){	
		//variable to hold string length of each string
		var strLength = 0;
		//retrieve/split/set new html
		this.initString = this.options.container.get('html');
		//reg exp check for link within string (thanks goes to daKmoR - mooforum.net)
		if(this.options.message.test(/url\=.*?\]/i) == true){
			var a = this.options.message;
			var b = a.replace(/url\=.*?\]/g, 'url]');//clever reg exp replace
			this.options.message = b;//replace old string with new one
		};
		//reg exp check for link within string (thanks goes to daKmoR - mooforum.net)
		if(this.initString.test(/url\=.*?\]/i) == true){
			var a = this.initString;
			var b = a.replace(/url\=.*?\]/g, 'url]');//clever reg exp replace
			this.initString = b;//replace old string with new one
		};
		//only split string if there is a string to be split, else use default option message
		if(this.initString && this.initString.contains(this.options.strSplitter)){
			//split the string
			this.splitString = this.initString.split(this.options.strSplitter);
			//checks if a maxcharacter was defined and then shortens string if true
			if(this.options.maxChars){
				for(i = 0; i<this.splitString.length; i++){
					if(this.splitString[i].length > this.options.maxChars){
						this.splitString[i] = this.splitString[i].substr(0,this.options.maxChars-3)+'...';
					};
				};
			};
			//calculate loop timing if not specified
			if(this.options.nxtMsgDelay == null){
				if(this.options.maxChars){
					//maxChars is provided
					this.options.nxtMsgDelay = (this.options.maxChars*(this.options.delay+this.options.variance+this.options.backDelay))/1000;
				}else{
					//maxChars is not provided so calculate from biggest string
					for(i=0; i<this.splitString.length; i++){
						if(this.splitString[i].length > strLength){
							strLength = this.splitString[i].length;
						}else{
							strLength = strLength;
						};
					};
					//the longest the pause needs to be so we dont loop before msg has been typed out
					this.options.nxtMsgDelay = (strLength*(this.options.delay+this.options.variance+this.options.backDelay))/1000;
				};
			};
			//remove 'cllpsHidden' class now that all calculations etc have been done
			if(this.options.container.hasClass('tckrHidden')){
				this.options.container.removeClass('tckrHidden');
			};
			//start displaying feed and install looping timer to change string
			this.display();
			var myTimer = this.display.periodical(((this.options.nxtMsgDelay+this.options.nextMsgPause)*1000),this);
		};
	},
	
	display: function(){
		//reset options
		this.cursor = 0;
		this.options.container.set('html','<span>Latest Offers: </span>');
		//set new news items from split string or from option
		if(this.splitString){
			this.options.message = this.splitString[this.options.counter];
			//check to see if there are any back-space character declared
			if(this.options.backChar){
				//declare variables
				var intTimes = null;
				var strCut = null;
				var strJoinedBackChar = "";
				var strRandomWord = "";
				//set variables
				intTimes = $random(0,this.options.typoLength);//typo will be 0(no typo) to specified chars long
				strCut = $random(0,this.options.message.length);//randomly choses where to inject this new 'typo'
				//add the characters together into one string
				for(x=0; x<=intTimes; x++){
					strJoinedBackChar = strJoinedBackChar+this.options.backChar;
					strRandomWord = strRandomWord+String.fromCharCode($random(65,122));
				};
				//inject the new typo string into my message
				this.options.message = this.options.message.substr(0,strCut)+strRandomWord+strJoinedBackChar+this.options.message.substr(strCut,this.options.message.length);
			};
			//check if counter has reached final string in array
			if(this.options.counter < this.splitString.length-1){
				this.options.counter++;
			}else{
				this.options.counter = 0;
			};
		};
		//for every letter
		for(x = 0; x<this.options.message.length; x++){
			//spits out characters at random pace
			var pace = (this.options.delay*x) + $random(0,this.options.variance);
			var current = this.options.message.charAt(x);
			//spit out the letter or delete one if backChar is encountered
			if(current != this.options.backChar){
				var go = this.setLetter.delay(pace,this);
			}else{
				//some people might add a stupid delete pace that will cause time overlap, so overide that here
				if(this.options.backDelay > pace){
					this.options.backDelay = (pace/2);
				};
				//send to delete function
				var go = this.deleteLetter.delay(pace + this.options.backDelay,this);
			};
		};
	},
	
	setLetter: function(){
		//push string into the link character by character
		this.options.container.set('html',this.options.container.get('html')+this.options.message.charAt(this.cursor));
		//increment cursor
		this.cursor++;	
	},
	
	deleteLetter: function(){
		//delete a letter if backChar is encountered
		this.options.container.set('html',this.options.container.get('html').substr(0,this.options.container.get('html').length - 1));
		//increment cursor
		this.cursor++;
	}
});