/**
 * @author Shannon Carey
 */
var Const = {
	LETTER_IMAGE_FOLDER: 'images/gifs/',
	LETTER_FOLDER: 'mp3/letters/',
	WORD_FOLDER: 'mp3/words/',
	SOUND_ON_KEY_DELAY: 770,
	SOUND_OFF_KEY_DELAY: 500,
    GENERIC_PAUSE: 600
};

var Pages = {
	BLOG_: '/blog',
	PROJ_: 'page.php?page=tech',
	TABS_: 'page.php?page=tabs',
	CLIPS_: 'page.php?page=clips',
	ABOUT_: 'page.php?page=author'
};

var Words = [
		'abscess','already','ancient','anything','brother',
		'bullet','bureau','bushel','butcher','calf','caravan',
		'carry','circuit','corsage','courage','danger',
		'discover','dungeon','early','earnest','ferret','flood',
		'freight','front','greater','guess','haste',
		'jealous','journey','language','laugh','learn',
		'leisure','lettuce','machine','minute','ocean','one',
		'oven','pierce','pint','pleasure','plunger','poultry',
		'quiet','reindeer','remove','rural','schedule',
		'scissors','search','serious','shoulder','shovel',
		'ski','someone','spell','squad','stomach','stranger',
		'surgeon','swap','tomorrow','treasure','wolves',
		'workman','worth','yacht','yield',
		'above','answer','armies','army','axe','axes','bench',
		'built','camel','camels','canaries','candy','canoe',
		'canoes','cheese','cheeses','chimneys','choruses',
		'couldn\'t','cousin','diamond','diamonds','does',
		'dollar','dollars','earth','echo','elf','elves',
		'enough','extra','feather','finger','four','glories',
		'glory','guard','gypsies','half','health','healthy',
		'heavy','hoof','hooves','inch','instead','iron','life',
		'lilies','lily','men\'s','mercy','mother','niece',
		'once','outdoor','period','plague','poem','poems',
		'poets','police','ponies','pony','potato','promise',
		'pull','puppies','puppy','quotient','range','relief',
		'rhythm','says','scarf','scarves','shield','source',
		'statue','sure','talk','terror','theif\'s','theives',
		'three','touch','trouble','typists','view','village',
		'villages','warm','wash','welcome','wife','wives',
		'women\'s','wonder','word','zero'
	];

var Beeps = [
		'92-4653','2315','4537','9273'
	];

var SpeakNSpell = function(){
	var myString = '';
	var screen = [];
	var isSoundOn = false;
	var isAcceptingKeys = true;
	var controller;
	
	//updates the screen
	var Updater = function() {
		var lastString = '';
		
		return {
			update: function(){
				if(lastString == myString)
				{
					return;
				}
				var parent = screen[0].parentNode;
				parent.removeChild(screen[0]);
				
				for(var i = 1; i < screen.length; i++) {
					screen[0].removeChild(screen[i]);
				}
				screen.length = 1;
				var appearing = [];
				for(i = 0; i < myString.length && i < 8; i++)
				{
					var o = lastString.charAt(i);
					var n = myString.charAt(i);
					var img;
					if(n != o)
					{
						img = new LetterImage(n, i, false);
						appearing.push(img);
					} else {
						img = new LetterImage(n, i, true);
					}
					screen[0].appendChild(img);
					screen[i + 1] = img;
				}
				parent.appendChild(screen[0]);
				Effect.multiple(appearing, Effect.Opacity, { from: 0.1, to: 1.0, duration: 0.5, speed: 0 });
				
				lastString = myString;
			}
		}
	};
	var updater = new Updater();
	
	var keyAccepted = function()
	{
		isAcceptingKeys = false;
		setTimeout(
			function()
			{
				isAcceptingKeys = true;
			},
			isSoundOn ? Const.SOUND_ON_KEY_DELAY : Const.SOUND_OFF_KEY_DELAY
		);
	};
	
	var LetterImage = function(s, depth, visible)
	{
		var padding = depth * 7;
		
		var imgName = s == ' ' ? 'space' : s;
		var img = Builder.node('img', {src : Const.LETTER_IMAGE_FOLDER + imgName + '.gif', style : (visible ? '' : 'filter:alpha(opacity=0);-moz-opacity:0;opacity:0;zoom: 1;') + 'padding-top:' + padding + 'px;'});
		return img;
	};
	
	var toggleSound = function()
	{
		isSoundOn = !isSoundOn;
		updateSound();
	};
	
	var updateSound = function()
	{
		if(isSoundOn)
		{
			$('soundon').style.visibility = '';
			Sound.enable();
		} else {
			$('soundon').style.visibility = 'hidden';
			Sound.disable();
		}
	};
	
	var randomBeep = function()
	{
		var beep = Beeps[Math.floor(Math.random() * Beeps.length)];
		Sound.play(Const.WORD_FOLDER + beep + '.mp3');
	};
	
	function Controller(){
		this.addLetter = function(s){
			this.doAddLetter(s);
			keyAccepted();
		};
		this.backspace = function(){
			this.doBackspace();
			keyAccepted();
		};
		//this.go = function(){
		//	this.doGo();
		//}
		this.enter = function(){
			this.doEnter();
		}
	}
	
	function NormalController(){
		var secretString = '';
		myString = 'SPELL A';
		updater.update();
		Sound.play(Const.WORD_FOLDER + '92-4653.mp3', {replace: true});
			
		this.doAddLetter = function(s){
			if (myString.length < 9) {
				Sound.play(Const.LETTER_FOLDER + s + '.mp3', {
					replace: true
				});
				//myString = myString.substring(0, myString.length - 1) + s + '_';
				//updater.update();
				secretString += s;
				var new_page = Pages[secretString];
				if (new_page != null) {
					myString = secretString;
					updater.update();
					setTimeout(function(){
						Sound.play(Const.WORD_FOLDER + 'you_win.mp3', {
							replace: true
						});
						setTimeout(function(){
							window.location = new_page;
						}, Const.GENERIC_PAUSE * 2);
					}, Const.GENERIC_PAUSE);
				}
				if(secretString == 'FERRET')
				{
					Lightbox.create();
				}
			}
		};
		this.doBackspace = function(){
			if (myString.length > 0) {
				myString = myString.substring(0, myString.length - 2) + '_';
				updater.update();
				keyAccepted();
			}
		};
		this.doEnter = function(){
			//TODO: ?
		};
		this.go = function(){
			//can't do it this way.
			controller = new SpellItController();
			controller.go();
		};
	}
	NormalController.prototype = new Controller();
	
	
	function MysteryWordController() {
		var badGuesses = 0;
		var mysteryWord = Words[Math.floor(Math.random() * Words.length)].toUpperCase();
		myString = '________';
		myString = myString.substr(0, mysteryWord.length);
		updater.update();
		randomBeep();
		
		this.doAddLetter = function(s){
			Sound.play(Const.LETTER_FOLDER + s + '.mp3', {replace: true});
			
			if(myString == mysteryWord)
			{
				return;
			}
			
			var pos = mysteryWord.indexOf(s);
			if(pos == -1 || myString.indexOf(s) != -1)
			{
				badGuesses++;
			} else {
				while(pos != -1)
				{
					myString = myString.substring(0, pos) + s + myString.substring(pos + 1, myString.length);
					pos = mysteryWord.indexOf(s, pos + 1);
				}
				if (myString == mysteryWord) {
					setTimeout(function(){
							Sound.play(Const.WORD_FOLDER + 'you_win.mp3');
						}, Const.GENERIC_PAUSE);
				} else {
					setTimeout(function(){
							randomBeep();
						}, Const.GENERIC_PAUSE);
				}
			}
			if(badGuesses == 7)
			{
				myString = mysteryWord;
				setTimeout(function(){
							Sound.play(Const.WORD_FOLDER + 'i_win.mp3');
						}, Const.GENERIC_PAUSE);
			}
			updater.update();
		};
		this.doBackspace = function(){
		};
		this.doEnter = function(){
			//TODO: ?
		};
		this.go = function(){};
	}
	MysteryWordController.prototype = new Controller();
	
	function SpellItController(){
		var wins;
		var losses;
		var currentWord;
		var triesOnCurrentWord;
		var playCurrentWord = function() {
			Sound.play(Const.WORD_FOLDER + currentWord.toLowerCase() + '.mp3');
		};
		var chooseNewWord = function() {
			myString = '_';
			updater.update();
			currentWord = Words[Math.floor(Math.random() * Words.length)].toUpperCase();
			triesOnCurrentWord = 0;
		};
		
		this.go = function(){
			wins = 0;
			losses = 0;
			
			isAcceptingKeys = false;
		
			chooseNewWord();
			
			// play the starting found for this mode
			Sound.play(Const.WORD_FOLDER + 'spell.mp3');
			setTimeout(
				function()
				{
					playCurrentWord();
					isAcceptingKeys = true;
				},
				isSoundOn ? Const.SOUND_ON_KEY_DELAY : Const.SOUND_OFF_KEY_DELAY
			);
		};
		
		this.doAddLetter = function(s){
			if (myString.length < 9) {
				Sound.play(Const.LETTER_FOLDER + s + '.mp3', {
					replace: true
				});
				myString = myString.substring(0, myString.length - 1) + s + '_';
				updater.update();
			}
		};
		
		this.doBackspace = function(){
			if(myString.length > 0) {
				myString = myString.substring(0, myString.length - 2) + '_';
				updater.update();
				keyAccepted();
			}
		};
		
		this.doEnter = function(){
			isAcceptingKeys = false;
			
			if(myString.substring(0, currentWord.length) == currentWord)
			{
				wins++;
				myString = currentWord;
				updater.update();
				var waitLength = 1600;
				switch(wins + losses)
				{
					case 1:
					Sound.play(Const.WORD_FOLDER + '1you_are_right_try.mp3');
					waitLength = 1600;
					break;
					case 2:
					Sound.play(Const.WORD_FOLDER + '2that_is_right_now_try.mp3');
					waitLength = 1900;
					break;
					case 3:
					Sound.play(Const.WORD_FOLDER + '3you_are_correct_next_spell.mp3');
					waitLength = 1900;
					break;
					case 4:
					Sound.play(Const.WORD_FOLDER + '4that_is_correct_now_spell.mp3');
					waitLength = 1900;
					break;
				}
				//The display is blanked before it says "next spell" or "now try" etc.
				//So those have to be separate sound files
				
				chooseNewWord();
				setTimeout(
					function()
					{
						playCurrentWord();
						isAcceptingKeys = true;
					},
					waitLength
				);
			} else {
				triesOnCurrentWord++;
				if(triesOnCurrentWord <= 1)
				{
					myString = myString.substring(0, myString.length - 1);
					updater.update();
					Sound.play(Const.WORD_FOLDER + 'wrong_try_again.mp3');
					setTimeout(function(){
						myString = '_';
						updater.update();
						playCurrentWord();
						isAcceptingKeys = true;
					}, 2000);
				} else {
					losses++;
					myString = 'LOSS';
					updater.update();
					Sound.play(Const.WORD_FOLDER + 'that_is_incorrect_the_correct_spelling_of.mp3');
					setTimeout(function(){
						playCurrentWord();
						setTimeout(function(){
							//is
							//spell word, adding letters to screen as it goes
							//now spell
							}, 50);
					}, 3000);
				}
			}
		};
	}
	SpellItController.prototype = new Controller();
	
	return {
		keyDown : function(event){
			var kc = event.keyCode;
			if(!isAcceptingKeys)
				return;
			
			if(Event.KEY_BACKSPACE == kc)
			{
				controller.backspace();
				Event.stop(event);
			} else {
				if (kc >= 65 && kc <= 90) {
					controller.addLetter(String.fromCharCode(kc));
				}
			}
		},
		enter : function(){
			controller.enter();
		},
		attach : function(){
			screen[0] = $('screen');
			$('soundtoggle').observe('click', toggleSound);
			updateSound();
			controller = new NormalController();
		},
		mysteryWord : function() {
			controller = new MysteryWordController();
		},
		go : function() {
			controller.go();
		},
		on : function() {
			controller = new NormalController();
		}
	}
};

var sns = new SpeakNSpell();

Event.observe(window, 'load', 
		function()
		{
			sns.attach();
			Event.observe(document, 'keydown',
					function(event){  
						sns.keyDown(event);
					}
				);
			$('enter').observe('click', sns.enter);
			$('mysteryWord').observe('click', sns.mysteryWord);
			$('go').observe('click', sns.go);
			$('on').observe('click', sns.on);
		}
	);
