﻿/**************************************************************

	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:{
		cursor: 0,//used as global variable (do not change)
		counter: 0,//which message to start at (default 0)
		delay: 130,//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: null,//time between displaying next message in seconds (null =  auto calculate)
		initString: null,//used a global variable
		splitString: null,//used a global variable
		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: 2//pause before showing next message (in seconds)
	},

	//initialization
	initialize: function(options)
	{
		//set options
		this.setOptions(options);
		
		//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.options.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.options.initString.test(/url\=.*?\]/i) == true){
			var a = this.options.initString;
			var b = a.replace(/url\=.*?\]/g, 'url]');//clever reg exp replace
					
			this.options.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.options.initString != null && this.options.initString.contains(this.options.strSplitter)){
			//split the string
			this.options.splitString = this.options.initString.split(this.options.strSplitter);
		
			//checks if a maxcharacter was defined and then shortens string if true
			if(this.options.maxChars != null){
				for(i = 0; i<this.options.splitString.length; i++){
					if(this.options.splitString[i].length > this.options.maxChars){
						this.options.splitString[i] = this.options.splitString[i].substr(0,this.options.maxChars-3)+'...';
					};
				};
			};
			
			//calculate loop timing if not specified
			if(this.options.nxtMsgDelay == null){
				if(this.options.maxChars != null){
					//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.options.splitString.length; i++){
						if(this.options.splitString[i].length > strLength){
							strLength = this.options.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.options.cursor = 0;
		this.options.container.set('html','<span>Latest: </span>');
		
		//set new news items from split string or from option
		if(this.options.splitString != null){
			this.options.message = this.options.splitString[this.options.counter];
			
			if(this.options.backChar != null){
				//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 6 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.options.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);
			};
		};
	},
	
	//place the newest letter in the container
	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.options.cursor));
			
		//increment cursor
		this.options.cursor++;	
	},
	
	//deletes a letters
	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.options.cursor++;
	}
});