nfl.namespace('combine');
nfl.combine.VideoChannel = (function () {
	var ESCAPED_DELIMITER   = /#%7B([^%]+)%7D/g;
	var RESULTS_PER_REQUEST = 48;
	var AJAX_URL            = '/ajax/videos';
	var LIS_PER_COLUMN      = 6;
	var COLUMNS_PER_PAGE    = 2;
	var LIS_PER_PAGE        = LIS_PER_COLUMN * COLUMNS_PER_PAGE;
	var OL_PADDING          = 12;
	var OL_BORDER			= 0;
	var PARAM               = {
		CATEGORY: 'categoryId', PAGE: 'pageNum', FILTER: 'filter',
		SEASON: 'seasonFilter', AUTO_SEASON: 'autoSeason'
	};
	var CLASS               = {
		PAGINATION: 'pagination',
		FIRST:      'pagination-first',
		LAST:       'pagination-last'
	};
	
	function templatize(ref) {
		var el, t;
		el = $(ref);
		t = new Template(el.innerHTML.replace(ESCAPED_DELIMITER, "#{$1}"));
		el.setStyle({ opacity: 0 });
		return t; 
	}

	function onHashChange (e) {
		var page, video, params = window.location.hashparams.get();
		
		console.log( 'onHashChange(): ' + params.inspect() );
		page  = parseInt( params.get('page') || 1 );
		video = params.get('video');
		if ( page && this.page !== page ) { this.viewPage( page ); }
		if ( video ) {
			this.loadVideo( video, true );
		}
	}
	
	function onVideoAvailable(){

	};
	
	function onAjaxSuccess ( transport ) {
		console.log( 'onAjaxSuccess()', transport );
		var page, videos, response = transport.responseJSON.videoGallery;

		this.resultsLoaded = transport.request.parameters[ PARAM.PAGE ];
		this.pagesLoaded   = Math.floor( RESULTS_PER_REQUEST * this.resultsLoaded / LIS_PER_PAGE );

		try {
			videos   = response.pages.flatten();
			videos.each( cleanVideoData( this.resultsLoaded ) );
		}
		catch(e) {
			videos   = [];
			console.log( 'error: ' + e );
		}
		this.total       = parseInt( response.videoCount );
		this.videos      = this.videos.concat ( videos );
		this.totalPages  = Math.ceil( this.total / LIS_PER_PAGE );
		if ( this.goalPage > this.totalPages ) {
		  this.goalPage = 1;
		}
		if ( this.pagesLoaded < this.goalPage ) {
			this.getVideos();
		}
	}

	function onAjaxFailure ( transport ) {
		console.log('onAjaxFailure()', transport );
	}
	
	function onAjaxComplete ( transport ) {
		var list;
		console.log( 'onAjaxComplete()', this.resultsLoaded, this.page );

		// Render the page
		this.render();

		// If we're loading the current page, scroll to it
		if ( this.goalPage && this.pagesLoaded >= this.goalPage ) {
			this.viewPage( this.goalPage );
			this.goalPage = null;
		}
	}
	
	function cleanVideoData ( _serverPage ) {
		var startIndex = ( _serverPage - 1 ) * RESULTS_PER_REQUEST + 1;
		var evenOrOdd;
		
		return function( _video, _index ) {
			_video.mediumThumbnailImg = '<img src="' + _video.mediumThumbnail + '" alt="" />';
			_video.evenOrOdd = evenOrOdd = (evenOrOdd === 'odd') ? 'even' : 'odd';
			_video.page      = Math.ceil( ( startIndex + _index ) / LIS_PER_PAGE );
			_video.captionBlurb	= (""+_video.captionBlurb).truncateAtLastWord(72);
		};
	}
	
	function getVideoHTML ( _acc, _video, _index ) {
		if ( _index % ( LIS_PER_COLUMN * COLUMNS_PER_PAGE ) === 0 && _index ) {
			_acc += '</ol><ol style="width:' + (this.olWidth+this.olPadding) + 'px; padding-right: 0px">';
		}
		_acc += this.template.evaluate( _video );
		return _acc;
	}
	
	function getPageFromLeft ( ref, _width ) {
		var left = parseInt( $( ref ).getStyle('left') || 0 );
		return ( -1 * left / _width ) + 1;
	}
	function getLeftFromPage ( page, _width ) {
		return -1 * ( page - 1 ) * _width + 'px';
	}
	
	function updatePagination ( pair ) {
		var el, classNames, template;
		
		el           = $( pair.key );
		el.update( pair.value.evaluate( this ) );
		
		classNames = [ CLASS.PAGINATION ];
		
		if ( this.previous === 0 ) { classNames.push( CLASS.FIRST ); }
		if ( this.next > this.totalPages ) { classNames.push( CLASS.LAST ); }
		el.className = classNames.join(' ');
		el.appear();
	}
	
	function onItemClick (_e) {
		var contentid, li = _e.findElement('li');
		
		_e.stop();

		if ( ! li ) { return; }
		
		contentid = li.getAttribute('data-contentid');

		window.location.hash = '#' + li.select('a').first().href.split('#')[1];
		
		// Force things in case the hash is already set.
		if ( this.video === contentid ) {
			this.loadVideo( contentid, true );
		}
	}
	function onItemOver (_e) {
		var li, from;
		_e.stop();
		li   = _e.findElement('li');
		from = $( _e.relatedTarget || _e.fromElement );
		if ( (! li) || ( from && from.descendantOf && from.descendantOf( li ) ) ) { return; }
		// Tricks Prototype into setting opacity as 1
		//li.setOpacity(0.9999999);
	}

	function onItemOut (_e) {
		var li, to;
		_e.stop();
		li   = _e.findElement( 'li' );
		to   = $( _e.relatedTarget || _e.toElement );
		// Make sure the mouse out is not happening inside the LI
		if ( ( !li ) || ( to  && ( to === li || ( to.descendantOf && to.descendantOf( li ) ) ) ) ) { return }
		// Tricks Prototype into removing the opacity style, back to default.
		//li.setOpacity(1);
	}
	
	// waits until the external interface is available before loading the video
	function loadVideoWhenReady () {
		var test = false;
		if($(this.player)){
			/* player exists */
			nfl.log('loadVideoWhenReady: player exists.');
			this.player	= this.player;
			this.playerParent = Element.up($(this.player),2).identify();
			try{
				test	= $( this.player ).ready();
			}catch(e){}
		}else{ 
			if(!this.timeout && document.loaded){
				this.timeout	= true;
				this.epicfail	= false;
				setTimeout(function(){this.epicfail = true; nfl.log('EPIC FAIL. '+this.player+' does not exist.'); }.bind(this), 5000 );
			}
		}
		if(test){
			nfl.log('loadVideoWhenReady: player is ready to load video');
			document.fire('mediaplayer:loaded');
			if(this.video){ this.loadVideo(this.video); }
		}else{
			if(!this.epicfail){ (loadVideoWhenReady.bind(this)).defer();}
		}
	}
	
	return Class.create({
		initialize: function( config ) {
			var el, pagination, list, li, params, parent, player;
			
			list           = $(config.list);
			li             = list.select('li').first();
			params         = new Hash();

			// Ajax Parameters
			if (config.season) {
				params.set( PARAM.SEASON, config.season );
			}
			else {
				params.set( PARAM.AUTO_SEASON, 'true' );
			}
			params.set( PARAM.CATEGORY, config.category )
			params.set( PARAM.FILTER, config.filter );
			
			// TEST ONLY
			// params.set( PARAM.FILTER, 'playoffs');
			this.config    = config;
			this.liWidth   = li.offsetWidth;
			this.liHeight  = li.offsetHeight;
			this.olWidth   = this.liWidth * COLUMNS_PER_PAGE;
			this.olPadding = config.olPadding || OL_PADDING;
			this.olBorder  = config.olBorder || OL_BORDER;
			this.goalPage  = parseInt(config.page || 1);
			this.page      = 1;
			this.next      = this.page + 1;
			this.previous  = this.page - 1;
			this.resultsLoaded  = 0;
			this.videoPermalink = '';
			this.channel   = config.channel;
			this.list      = list.identify();
			this.player    = config.player;
			this.playerId  = config.player;
			this.playerParent = config.playerParent || false;
			this.video     = config.video || '';
			this.loading   = false;
			this.total     = 0;
			this.videos    = [];
			this.template  = templatize( list );
			this.options   = {
				method:    'get',
				onSuccess: onAjaxSuccess.bind(this),
				onFailure: onAjaxFailure.bind(this),
				onComplete: onAjaxComplete.bind(this),
				parameters: params
			};
			// Set the event listeners
			try{
				list.observe('click', onItemClick.bind(this));
				list.observe('mouseover', onItemOver);
				list.observe('mouseout', onItemOut);
			}catch(e){}
			
			// Set up pagination
			pagination = new Hash();
			if ( Object.isArray(config.pagination) ) {
				config.pagination.each(function(p) {
					var el = $(p);
					if (el) { 
						pagination.set( el.identify(),  templatize( el ) );
					}
				});
			}
			else if ( config.pagination ) {
				el = $(config.pagination);
				pagination.set( el.identify(), templatize( el ) );
			}
			this.pagination = pagination;
			this.getVideos();
			
			document.observe('window:hashchange', onHashChange.bind(this));
			this.loadVideoWhenReady(this.player,this.video);
		},
		getVideos: function() {
			this.options.parameters.set( PARAM.PAGE, this.resultsLoaded + 1 );
			
			new Ajax.Request( AJAX_URL, this.options );
		},
		loadVideoWhenReady: function(_player,_video){
			this.player       = _player;
			this.video        = _video;
			(loadVideoWhenReady.bind(this))();
		},
		viewPage: function( _page ) {
			var list, currentPage;
			list = $(this.list);
			currentPage = getPageFromLeft( list, this.olWidth + (this.olPadding) );
			if (currentPage === _page) { return; }
			if ( _page > this.pagesLoaded && _page <= this.totalPages ) {
				this.goalPage = _page;
				return this.getVideos();
			}
			if ( _page <= this.pagesLoaded ) {
				list.morph('left: ' + getLeftFromPage( _page, this.olWidth + (this.olPadding) ));
				this.page = _page;
				this.next = this.page + 1;
				this.previous = this.page - 1;
				this.paginate();
				return;
			}
		},
		loadVideo: function( _contendId, _autoplay ) {
			var player, autoplay;
			player              = $(this.player);
			autoplay            = _autoplay || false;
			this.video          = _contendId;
			
			if ( _autoplay ) {
				this.videoPermalink = '/video:' + this.video;
				//alert('10:this.playerParent='+this.playerParent+'\n\rthis.player='+this.player+'');
				Effect.ScrollTo( this.playerParent );
			}
			
			try{
				if(player){
					player.loadVideo( _contendId, autoplay );
				}
			}catch(e){ /* alert('EPIC FAIL. player method loadVideo threw error. '+e.message); */ }
		},
		render: function() {
			var i, l, list, currentPage, targetLeft;
			
			list = $(this.list);
			list.setStyle({ width: Math.ceil( this.videos.length / LIS_PER_PAGE ) * ( this.olWidth + this.olPadding + this.olBorder) + 'px' });
			list.update( '<ol style="width: '+ (this.olWidth+this.olPadding) + 'px; padding-right: 0px">' + this.videos.inject('', getVideoHTML, this) + '</ol>' );
			
			if ( this.resultsLoaded === 1 ) {
				// Paginate if it's the first load
				this.paginate();
				// once the first list gets populated we can set the parent height
				list.appear({ onComplete: function() {
					list.up().setStyle({ height: list.offsetHeight + 'px' } );
					list = null;
				}});
				if ( this.videos.length && ! this.video ) {
				  this.loadVideoWhenReady(this.player, this.videos[0].chronicleId );
				}
			}
		},
		paginate: function() {
			this.pagination.each( updatePagination, this );
		}
	});
})();
