$(document).ready(function() { 
	
	/*** Config ***/
	
	// Make sure that the app is hidden. Fixes for ios weirdness
	$(".app").hide().removeClass("hidden");
	
	// Config Object
	var config = {
		duration: 8*60,						// The total default duration of the workout
		countdown: { time: 3 },				// The countdown time (in seconds)
		rest: { name: "Rest", time: 10 },	// The name and time for the rest period
		finished: { name: "DONE" },
		current: 0,							// Current exercise. DO NOT CHANGE
		sounds: {							// The sounds used in the app. These will preloaded
			tick: "tick.wav",
			done: "done.wav",
			swit: "switch.wav",
			comp: "completed.wav",
		},
		exe: [								// The names and slugs for each exercise. These are used to load images/sounds as needed
			{ name: "Jumping Jacks", slug: "jumping-jack" },
			{ name: "Wall Sit", slug: "wall-sit" },
			{ name: "Push-Up", slug: "push-up" },
			{ name: "Abdominal Crunch", slug: "crunch" },
			{ name: "Step-Up onto Chair", split: 2, slug: "step-up" },
			{ name: "Squat", slug: "squat" },
			{ name: "Triceps Dip on Chair", slug: "triceps-dip" },
			{ name: "Plank", slug: "plank" },
			{ name: "High Knees Running", slug: "running" },
			{ name: "Lunge", split: 2, slug: "lunge" },
			{ name: "Push-up and Rotation", split: 2, slug: "push-up-rotate" },
			{ name: "Side Plank", split: 2, slug: "side-plank" }
		]
	};
	
	
	
	/*** Events ***/
	
	// Registered when user clicks on .duration text box
	$(".duration").focus(function () {
	
		config.duration = $(this).val(""); 
		ga('send', 'event', 'general', 'focus', 'duration', true);
		
	});
	
	// Registered when user edits .duration text box
	$(".duration").keyup(function () {
		
		// Calculates the value based on the value in the .duration textbox
		if ($(this).val() > 1) {
			config.duration = $(this).val()*60; 
		} else { 
			config.duration = ($(this).val()+3)*60; 
		}
		
		// Google analytics change to event
		ga('send', 'event', 'general', 'change', 'duration', true); 
		ga('send', 'event', 'general', 'change', 'duration to', config.duration);
		
	});
	
	// Registered when user clicks start button
	$(".start").click(function() { 
		
		// Sets up the loader object for images and sounds (May need to switch back to traditional loader to get sounds on iOS)
		config.loader = new loader();
		
		// Preloads images 
		for (files in config.exe) { 
			config.exe[files].image = config.loader.image("images/"+config.exe[files].slug+".png");
		}
		
		// Preloads Sounds
		for (sound in config.sounds) { 
			config.sounds[sound] = config.loader.sound("sounds/"+config.sounds[sound]);
		}
		
		// Callback triggered when all files are loaded
		config.loader.load(function () { 
			countdown();
		});
		
		return false;
	});


	/*** Classes & Helpers ***/
	
	// This is the loader class. Preloads images and sounds and calls callback when loaded
	function loader(files) { 
		
		this.files = [];
		this.loadedCnt = 0;
		
		this.callback = function () { }
		
		// This sets up the image load
		this.image = function (url) { 
		    var img = new Image();
		    img.src = url;
		    img.onload = this.loaded();
		    this.files.push(img);
		    return img;
		}
		
		// This sets up the sound load
		this.sound = function (url) {
		    var audio = new Audio(url);
		    audio.addEventListener('canplaythrough', this.loaded(), false);
		    audio.load();
		    this.files.push(audio);
		    return audio;	
		}
		
		// This sets the callback and calls loaded, which 
		this.load = function (callback) { 
			this.callback = callback;
			this.loaded();
		}
		
		// This function gets called each time an item loads, and also when the Load() function is called
		this.loaded = function () { 
			this.loadedCnt++;
			if (this.loadedCnt >= (this.files.length-1)) {
				if (this.callback) { 
					this.callback();
				}
			}
		}
	}
	
	// This is the countdown action. When called this function completes the countdown and then calls the ex() function to start the app
	function countdown() { 
	
		// Google analytics tracking
		ga('send', 'event', 'general', 'click', 'button', true);
		ga('send', 'event', 'general', 'select', 'duration', config.duration);	
		
		// Set countdown time. Could be factored out
		var cdTime = config.countdown.time;
		
		// Hides the title page on countdown
		$(".title-elements").slideUp();
		
		// Select Countdown button and start changing
		var countdown = $(".start-button");
		
		countdown.html(cdTime);
		
		// Countdown Timer.
		var cd = window.setInterval(function() { 
			if (cdTime > 0) { 
				cdTime--;
				countdown.text(cdTime);
			} else { 
				countdown.hide();
				$(".app").fadeIn(500);
				for (i in config.exe) { 
					$("#balls.row-fluid").append("<div class='span1 ball' id='ball"+i+"'><img src='images/ball.png' /></div>");
				}
				clearInterval(cd);
				ex();
			}
		}, 1000);	
	}
	
	// This is the main app function
	function ex() {
		
		config.sounds.tick.play();
		
		// This hides the content when the routine is complete
		if (config.current+1 > config.exe.length) { 
			$("#timer").text(config.finished.name);
			$("#picture").hide();
			$("#activity").hide();
			$("#balls").hide();
			return true;
		}
		
		// This calculates the various increments needed
		var exetime = Math.round((config.duration-(config.rest.time*config.exe.length))/config.exe.length)
		var split = Math.round(exetime/config.exe[config.current].split);
		var rest = config.rest.time;

		// This loads the image for this exercise and sets the times and activity
		$("#picture").attr("src", "images/"+(config.exe[config.current].slug)+".png");
		$("#timer .nums").text(exetime);
		$("#activity").text(config.exe[config.current].name);
		
		// This is the counter
		var clock = window.setInterval(function () { 
			
			// Counts down the timer based on time and plays
			if (exetime > 1) {
				exetime--;
				config.sounds.tick.play();
				if (exetime == (split+1)) { 
					config.sounds.swit.play();
				}
				$("#timer .nums").text(exetime);
			} 
			
			// Counts down the rest period and changes the screen accordingly
			else if (rest > 1) {
				rest--;
				
				// Plays the exercise finished sound
				if (rest == 9) { 
					config.sounds.done.play(); 
				}
				
				// Changes the screen accordingly
			 	$("#ball"+(config.current-1)).addClass("ball-fade");
				$("body, #timer, #image").removeClass("go").addClass("rest");
				$("#timer .nums").text(rest);
				$("#activity").text(config.rest.name);
				$("#picture").hide();
				$("#next").text("("+config.exe[config.current].name+")").fadeIn();
			} 
			
			// Runs at the end of the exercise cycle
			else {
				
				// Clears interval and starts everything over
				clearInterval(clock);
				
				// Changes the screen accordingly
				ga('send', 'section', 'sections', 'complete', 'section-'+config.current, 1);
				$("#picture").show();
				$("#next").fadeOut();
				$("body, #timer, #image").removeClass("rest").addClass("go");
				
				// Recursively calls the ex() function to start over again
				ex();
			}
		}, 1000);
		
		// Sets the next exercise
		config.current++;
	}
});