/**
 * A class to generate a news ticker. It will draw each entry (a text string in
 *  an <a> link with a specified URL as its href) one character at a time, with
 *  a - or _ trailing the text as it is being drawn, then when each entry is
 *  fully drawn it will wait for a number of seconds before progressing onto the
 *  next entry. It will not progress onto the next entry if the mouse cursor is
 *  hovering over the ticker element. This class is used by calling
 *  Ticker.addEntry() a number of times to add the required entries, and then
 *  calling Ticker.display(), passing as an argument the HTML ID of the element
 *  (preferably a span or similar) in which the ticker will be drawn.
 *
 */
var Ticker = {
	/**
	 * The number of characters that will be written to the screen per second.
	 * There is a practical limit to this, because three functions have to be
	 *  called for every letter displayed (the _, the - and the character
	 *  itself), so higher values might not have as much of an effect as is
	 *  expected.
	 *
	 */
	Frequency : 15,

	/**
	 * The number of seconds to wait after displaying the final character of an
	 *  entry before starting the next entry
	 *
	 */
	Delay : 5,
	
	/**
	 * The number of seconds to wait before starting to display the first entry,
	 *  from the moment that Ticker.display() is called
	 *
	 */
	InitialDelay : 1,
	
	/**
	 * An array of entries (each an object with two members: text and url)
	 *
	 */
	Entries : [],
	
	/**
	 * The container element
	 *
	 */
	Container : null,
	
	/**
	 * The <a> element inside the container
	 *
	 */
	LinkElement : null,
	
	/**
	 * The currently displayed text, EXCLUDING a trailing _ or -, if one exists
	 *
	 */
	CurrentText : '',
	
	/**
	 * The array index of the currently displayed entry
	 *
	 */
	CurrentEntry : 0,
	
	/**
	 * The stage of the display cycle we're at, between 1 and 3
	 *
	 */
	CycleStage : 1,
	
	/**
	 * Whether the mouse is hovering over the ticker container or not
	 *
	 */
	MouseIsOver : false,
	
	/**
	 * Adds an entry to the ticker, with the text and link URL specified
	 *
	 * @param string Text to display
	 * @param string URL to link to
	 */
	addEntry : function(text, url) {
		Ticker.Entries.push({'text':text,'url':url});
	},
	
	/**
	 * Sets up the ticker to display inside the element (preferably a span) with
	 *  the specified ID
	 *
	 * @param string Container element ID
	 */
	display : function(elid) {
		Ticker.Container = document.getElementById(elid);
		Ticker.Container.onmouseover = Ticker.mouseOver;
		Ticker.Container.onmouseout = Ticker.mouseOut;
		Ticker.LinkElement = document.createElement('a');
		Ticker.Container.appendChild(Ticker.LinkElement);
		window.setTimeout(Ticker.runStage, Ticker.InitialDelay*1000);
	},
	
	/**
	 * Called every timeout, three times per character, and delegates work to
	 *  the runStage* methods, before setting a timeout to call itself again
	 *
	 */
	runStage : function() {
		var DelaySecs = 1/(Ticker.Frequency*3);
		if (!Ticker.MouseIsOver || Ticker.CurrentText.length < Ticker.Entries[Ticker.CurrentEntry].text.length) {
			switch (Ticker.CycleStage) {
				case 1:
					Ticker.runStage1();
					break;
				case 2:
					Ticker.runStage2();
					break;
				case 3:
					Ticker.runStage3();
					if (Ticker.CurrentText.length >= Ticker.Entries[Ticker.CurrentEntry].text.length) {
						DelaySecs = Ticker.Delay;
					}
					break;
			}
			if (Ticker.CycleStage < 3) {
				Ticker.CycleStage++;
			} else {
				Ticker.CycleStage = 1;
			}
		}
		window.setTimeout(Ticker.runStage, Math.round(DelaySecs*1000));
	},
	
	/**
	 * Runs stage 1, which displays an underscore character, resetting the
	 *  string to '' and proceeding to the next entry if necessary
	 *
	 */
	runStage1 : function() {
		//Display a _
		if (Ticker.CurrentText.length >= Ticker.Entries[Ticker.CurrentEntry].text.length) {
			Ticker.CurrentEntry++;
			if (Ticker.CurrentEntry >= Ticker.Entries.length) {
				Ticker.CurrentEntry = 0;
			}
			Ticker.CurrentText = '';
		}
		if (Ticker.CurrentText.length == 0) {
			Ticker.LinkElement.href = Ticker.Entries[Ticker.CurrentEntry].url;
		}
		Ticker.setText(Ticker.CurrentText + '_');
	},
	
	/**
	 * Runs stage 2, which displays a hyphen character
	 *
	 */
	runStage2 : function() {
		//Display a -
		Ticker.setText(Ticker.CurrentText + '-');
	},
	
	/**
	 * Runs stage 3, which displays the next character in this entry's text
	 *
	 */
	runStage3 : function() {
		//Display the character
		Ticker.CurrentText += Ticker.Entries[Ticker.CurrentEntry].text.substr(Ticker.CurrentText.length, 1);
		Ticker.setText(Ticker.CurrentText);
	},
	
	/**
	 * Sets the text of the ticker's link element to the supplied (HTML) string
	 *
	 */
	setText : function(s) {
		Ticker.LinkElement.innerHTML = s;
	},
	
	/**
	 * Handles the mouse hovering over the container, and remembers that the
	 *  mouse is hovering over it so we can prevent the progression onto the
	 *  next entry all the time the mouse is over the ticker
	 *
	 */
	mouseOver : function() {
		Ticker.MouseIsOver = true;
	},
	
	/**
	 * Handles the mouse moving away from the container, and resets the flag
	 *  that indicated it was hovering over, so that we can progress onto the next entry if necessary
	 *
	 */
	mouseOut : function() {
		Ticker.MouseIsOver = false;
	}
}