// setup nponline namespace to segregate our stuff
var nponline = nponline || {};

/*
 * countdown is the visible countdown timer - counts down to the service start time
 */
;nponline.countdown = (function($) {
	// wrap in return to expose these properties and functions
	return {
	
		// show the countdown inside the $container (jQuery object) and using the details of the given service
		show: function($container, service) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('countdown.show - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('countdown.show: service('+service.id+') video start in '+service.seconds_until_next_instance+' and service '+service.secs_until_start+' after that');
			// validate $container is a jq object
			$container.fadeIn(1000).countdown({until: service.seconds_until_next_instance + service.secs_until_start, compact: true, layout: $('#countdownlayout').html() });
			$("#countdownWrapper,#countdownLabel").fadeIn(1000);
		},
		
		hide: function($container) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('countdown.hide - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('countdown.hide');
			$container.countdown('destroy').fadeOut(1000);
			$("#countdownWrapper,#countdownLabel").fadeOut(1000);
		}
	
	};	
})(jQuery);

/*
 * flash video player
 */
;nponline.player = (function($) {
	
	var flashvars = { 
		baseurl: '/streams/', 
		autostart: 'true',
		themeColor: '0395d3',
		mode: 'sidebyside',
		scaleMode: 'fit',
		frameColor: '000000',
		fontColor: 'cccccc',
		link: '',
		embed: '',
		akamai_config_path: '/streams/config/beacon-1920.xml', // config path
		akamai_swf_plugin_path: 'http://79423.analytics.edgesuite.net/csma/plugin/csma.swf',
		retry_attempts: 7,
		retry_second_span: 4
	};
	
	var service = undefined;
	var quality = undefined;
	
	// map the bitrates to the quality for both sim and live
	var bitrates = new Array();
	bitrates['SIM'] = new Array();
	bitrates['SIM']['low'] = 300000;
	bitrates['SIM']['med'] = 650000;
	bitrates['SIM']['high'] = 1600000;
	bitrates['SIM']['auto'] = -1;
	
	bitrates['LIVE'] = new Array();
	bitrates['LIVE']['low'] = 300000;
	bitrates['LIVE']['med'] = 900000;
	bitrates['LIVE']['high'] = 1300000;
	bitrates['LIVE']['auto'] = -1;

	var params = {allowFullScreen: 'true'};
	var attributes = {id: 'akamaiPlayer',name: 'akamaiPlayer', wmode: 'transparent'};

	return {
		show: function ($container, svc) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('player.show - container is null or not jQuery');
				return;
			}
			service = svc;
			if (quality === undefined) quality = 'auto';
			nponline.logger.debug('player.show: schedid='+service.id+',  type='+service.type+', quality='+quality);
			$container.fadeIn(1000);

			$("#playerWindow").html('<div id="playerContainer"><div id="live_player"></div></div>');
						
			// Show quality controls in case they were hidden 
			$("#rightControls").fadeIn(500).find('.quality').show().removeClass("active").bind('click',nponline.player.change);
			$("#rightControls").find('a#'+quality).addClass("active");
			

			flashvars['schedid'] = service.id;
			/* TODO - only pass start time && stream if we are doing a test */			
			flashvars['simliveteststarttime'] = -1; // service.next_instance_date
			flashvars['teststream'] = -1; // service.streams[3].source_stream; ?? is [3] the right one? different if sim or live; iOS?
			flashvars['servicetype'] = service.type;

			swfobject.embedSWF('/includes/swf/AkamaiFlashPlayer.swf', 'playerContainer', '656', '402', '9.0.0', '/includes/swf/expressInstall.swf', flashvars, params, attributes);
		
			
		},
		
		hide: function($container,callback) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('player.hide - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('player.hide');
			$container.fadeOut(1000,callback);
		},
		
		change: function() {
			
			quality = $(this).attr('id');
			var br = bitrates[service.type][quality];
			nponline.logger.debug('set the quality to '+quality+' with a bitrate of '+br);
			
			var stream = -1;
			
			for (i=0;i < service.streams.length;i++) {
				var s = service.streams[i];
				if (s.bitrate == br) {
					stream = s.source_stream;
					break;
				}
			}
			flashvars['teststream'] = stream;
			nponline.logger.debug('the stream is '+stream);
			
			$("#playerWindow").html('<div id="playerContainer"><div id="live_player"></div></div>');
			$("#rightControls").find('.quality').removeClass("active")
			$("#rightControls").find('a#'+quality).addClass("active");
			
			//if (quality == 'audio') flashvars['audioonly'] = true;
			swfobject.embedSWF('/includes/swf/AkamaiFlashPlayer.swf', 'playerContainer', '764', '468', '9.0.0', '/includes/swf/expressInstall.swf', flashvars, params, attributes);
		}
		
	
	};

})(jQuery);


/*
 * slider
 */
;nponline.slider = (function($) {

	return {
		show: function($container) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('slider.show - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('slider.show');
			$container.fadeIn(1000).load( '/nponline/slider', null, function() {
				$(this).find('#slides').slides({
					preload: true,
					preloadImage: 'images/loading.gif',
					effect: 'slide, fade',
					slideSpeed: 1000,
					fadeSpeed: 500,
					generatePagination: false,
					play: 5000,
					hoverPause: false,
				    width: 656
				});
			
			});
		},
		
		hide: function($container,callback) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('slider.hide - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('slider.hide');
			$container.fadeOut(1000,callback);
		}
		
	};	

})(jQuery);

/*
 * counter
 */
;nponline.counter = (function($) {
	var $counterHtml;

	return {
		show: function($container) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('slider.show - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('counter.show');
			$container.fadeIn(1000);
			$container.html( $counterHtml );
		},
		
		hide: function($container,callback) {
			if (!$container || !$container.jquery) { 
				// how to handle the exception
				nponline.logger.debug('counter.hide - container is null or not jQuery');
				return;
			}
			nponline.logger.debug('counter.hide');
			$counterHtml = $container.html();
			$container.fadeOut(1000,callback);
		}
		
	};	

})(jQuery);



/*
 * timer is the master timer where the logic goes to show/hide all of the page elements based on when services stop or start
 */
;nponline.timer = (function($) {
	var currentService;
	var nextService;
	var $playerContainer;
	var $sliderContainer;
	var $countdownContainer;
	var $counterContainer;
	
	// wrap in return to expose these properties and functions
	return {
		init: function(service, $playerDiv, $sliderDiv, $countdownDiv,$counterDiv) {
			if (!service) {
				return;
			}
			currentService = service;
			$playerContainer = $playerDiv;
			$sliderContainer = $sliderDiv;
			$countdownContainer = $countdownDiv;
			$counterContainer = $counterDiv;
			
			nponline.logger.debug('timer initialized with service object: '+service.start_time+', video will start in '+service.seconds_until_next_instance+' seconds');
			if (service.seconds_until_next_instance > 15) { // grace period
				nponline.slider.show($sliderContainer);
				nponline.countdown.show($countdownContainer,service);
				// since the countdown is showing we need to set a timer on the video start	
				setTimeout("nponline.timer.video_start()",service.seconds_until_next_instance*1000);
			} else {
				nponline.logger.debug('hide countdown and show player');
				nponline.timer.video_start(true);
			}
		},
			
		video_start: function(showOnLoad) {
			nponline.logger.debug('nponline.timer.video_start');
			nponline.slider.hide($sliderContainer,function() {
				$.getJSON('/ajax/streams/' + currentService.id, function(json) {
					currentService.streams = json;
					nponline.player.show($playerContainer,currentService);
					nponline.logger.debug('gonna set a timeout until the service starts in '+currentService.secs_until_start+' seconds');
					if (showOnLoad) { // go ahead and do the service start, else set the timer to wait
						nponline.timer.service_start();
					} else {
						setTimeout("nponline.timer.service_start()", currentService.secs_until_start * 1000 );		
					}
				});
			});
			// todo - add people counter
			
			// have to take into account when this is called after the service time has started:
			//  - if so, use the seconds_until_next_instance_end that was set on the server
			//  - if not, then we counted down and just use the video length
			var secs = ( showOnLoad ) ? currentService.seconds_until_next_instance_end : currentService.video_length;
			setTimeout("nponline.timer.video_end()", secs * 1000);
			
			// set a random timer between now and the video end to go fetch the next service from the server
			var min = 1;
			var max = secs - 20; // don't want to be right up at the video end -- TODO - make it 60
			var secs2wait = Math.floor(Math.random() * (max - min + 1)) + min;
			nponline.logger.debug("waiting "+secs2wait+" seconds until getting next service & starting countdown");
			setTimeout("nponline.timer.get_next_service()", secs2wait * 1000 );
		},
		
		service_start: function() {
			nponline.logger.debug('inside service_start');
			nponline.countdown.hide($countdownContainer,function() {
				nponline.counter.show($counterContainer,currentService);				
			});

		},
		
		video_end: function() {
			nponline.logger.debug('nponline.timer.video_end: now we need to hide the player, show the gallery, and countdown to the NEXT service after ['+currentService.id+']');
			nponline.counter.hide($counterContainer,function() { } );
			nponline.player.hide($playerContainer,function() {
				nponline.slider.show($sliderContainer);
				if (!nextService) {
					// go fetch it
					nponline.timer.get_next_service();
				}
				currentService = nextService;
				nponline.countdown.show($countdownContainer,currentService);
				setTimeout("nponline.timer.video_start()",currentService.seconds_until_next_instance*1000);
				/*
				// randomize how quickly this happens so server doesn't get pegged all at once
				var min = 1;
				var max = 20; // TODO - set this for live
				var secs2wait = Math.floor(Math.random() * (max - min + 1)) + min;
				nponline.logger.debug("waiting "+secs2wait+" seconds until getting next service & starting countdown");
				setTimeout("nponline.timer.get_next_service()", secs2wait * 1000 );
				*/
			});
		},
		
		get_next_service: function() {
			$.getJSON('/ajax/nextService?current='+currentService.id,function(json) { 
				try {
					nextService = json; 
					nponline.logger.debug('timer.get_next_service: got the next one['+nextService.id+'] on '+nextService.weekday+' @ '+nextService.start_time+', has '+nextService.streams.length+' streams');
				} catch (e) {
					nponline.logger.debug("Exception parsing JSON: "+e);
				}			
			});		
		}
			
	};	

})(jQuery);

/*
 * custom logger 
 */
;nponline.logger = (function($) {
	
	// wrap in return to expose these properties and functions
	// WARNING: older browsers don't have console, and the following if statements don't hide it very well either; so comment out that line for production
	return {
		debug: function(msg) {
			//if (console !== undefined && console) console.log(msg);
			return;
		}
	};

})(jQuery);


