/********************************************************************************
 ** BaseNodeListener 
 ** - Superclass for other listeners
 *******************************************************************************/

function BaseNodeListener( name, player, disable_commands ) {
	BaseNodeListener.ctor.call( this, name, player );	
	this.disable_commands = disable_commands;
}

xmp.DERIVE_CLASS( xmp.baseplayer.listeners.AbstractNodeListener, BaseNodeListener );

BaseNodeListener.prototype.handleDynamicRules = function(node) { };
BaseNodeListener.prototype.handleRender = function( node ) {	
	this.getPlayer().getMediaPlayer().open( node );
};
BaseNodeListener.prototype.handleOpen = function( node ) {	
	this.setStatus( node, "Opened" );	
};
BaseNodeListener.prototype.handleConnecting = function( node ) { };
BaseNodeListener.prototype.handleConnected = function( node ) { };
BaseNodeListener.prototype.handlePlay = function( node ) { };
BaseNodeListener.prototype.handlePause = function( node ) { };
BaseNodeListener.prototype.handleStop = function( node ) { };
BaseNodeListener.prototype.handleRewind = function( node ) { };
BaseNodeListener.prototype.handleFastForward = function( node ) { };
BaseNodeListener.prototype.handleSeekable = function( node ) { };
BaseNodeListener.prototype.handleEnded = function( node ) {
	callControllerMethod('setEnabled',false);
	callControllerMethod('setEmailEnabled',true);
	callControllerMethod('setTime',0);
	callControllerMethod('togglePlay',false);	
	this.getPlayer().advance();	
};
BaseNodeListener.prototype.handleBuffering = function( node, buffStateObj ) {
	callControllerMethod('setLoadedPercent',(0.01*buffStateObj.percent));
};
BaseNodeListener.prototype.handleTimelineChange = function( node, position, duration ) {
	if (CNNPlayer.getActivePlayer().isScrubbing == false) {
		callControllerMethod('togglePlay',true);
		callControllerMethod('setTime',position);
	}
};
BaseNodeListener.prototype.handleError = function( node, err ) {
	this.getPlayer().advance();
};
BaseNodeListener.prototype.setStatus = function( node, status ) { };
BaseNodeListener.prototype._findNextContentNode = function( ) {	
	var lookAhead = this.getPlayer().getLookAheadNodeArray();	
	for ( var i = 0; i < lookAhead.length; i++ ) {
		var node = lookAhead[i];
		if ( node.isContentType() ) {
			return node;
		}
	}	
	return null;
};
BaseNodeListener.prototype._findPreviousContentNode = function( ) {	
	var lookBehind = this.getPlayer().getLookBehindNodeArray();
	for ( var i = 0; i < lookBehind.length; i++ )
	{
		var node = lookBehind[i];
		if ( node.isContentType() ) {
			return node;
		}
	}
	return null;
};
BaseNodeListener.prototype.loadSynchUnit = function( node ) {	
	var res = node.getMetaResource('synch_unit');
	if (!res) { return; }
	if (res.isError()) {
//  	this._bnl_logger.warn('Error loading synch unit: ' + res.getErrorMessage());
//		alert('Error loading synch unit: ' + res.getErrorMessage());
		return;
	}
	// data will be the full URL of the banner ad call to the ad server
	var data = res.getDataObject();
	if (res.getMetadata('played_synch_unit', false))
	{
//	  this._bnl_logger.info('NOT loading synch unit (already loaded) with tile ID: ' + res.getCompanionAdId() + ', url: ' + data);
//		alert('NOT loading synch unit (already loaded) with tile ID: ' + res.getCompanionAdId() + ', url: ' + data);
	  return;
	}
	res.setMetadata('played_synch_unit', true);
//	this._bnl_logger.info('Loading synch unit with tile ID: ' + res.getCompanionAdId() + ', url: ' + data);     
	this._createBannerAd("banner_ad_iframe", data);  

/*
	var loader = xmp.baseplayer.MetaFileLoaderFactory.getInstance().create('videoAdSynchUnit');
	if (!loader.hasSynchUnit(node))
	{
		return;
	}
	var synchUnitCallback = new xmp.util.Callback('synchUnitCB', this._gotSynchUnitCallback, this);
	loader.setNode(node, synchUnitCallback);	
	loader.load();	
*/
};
/*
BaseNodeListener.prototype._gotSynchUnitCallback = function( callback, node, data ) {	
	if (data.indexOf("ERROR") === 0)
	{
		this._logger.warn('Error loading synch unit: ' + data);
		return;
	}
	this._createBannerAd("banner_ad_iframe", data);
};
*/
BaseNodeListener.prototype._createBannerAd = function( adId, cnnad_url ) {
	if (CNNPlaylistManager.getInstance().playlistType == 'mos') {
		CNNPlaylistManager.getInstance().MOSCBannerAdWrite(cnnad_url,adId);
	} else { 
		bannerDiv = document.getElementById("cnnVPAd");
		var iFrameHTML = '<iframe hspace="0" vspace="0" marginHeight="0" marginWidth="0" src="' + cnnad_url + '&domId=' + adId + '" border="0" frameBorder="0" height="0" width="0" scrolling="no"  id="'+adId+'" style="position: absolute; visibility: hidden;" ></iframe>';
		bannerDiv.innerHTML = iFrameHTML;
	}
};

/********************************************************************************
 ** OverlayNodeListener
 ** - meant for non-dhtml overlays, not used
 *******************************************************************************/

function OverlayNodeListener( name, player ) {
	OverlayNodeListener.ctor.call( this, name, player, true );	
}

xmp.DERIVE_CLASS( BaseNodeListener, OverlayNodeListener );

OverlayNodeListener.prototype.handleRender = function( node ) {	};
OverlayNodeListener.prototype.handleInitialize = function( node ) {	};

/********************************************************************************
 ** SlateNodeListener
 ** - used for dhtml driven slates, parent class to other slates
 *******************************************************************************/

var SLATE_URL = "url";

function SlateNodeListener( name, player ) {
	SlateNodeListener.ctor.call( this, name, player, true );	
}

xmp.DERIVE_CLASS( BaseNodeListener, SlateNodeListener );

SlateNodeListener.prototype.handleInitialize = function( node ) {	
	node.setURI( node.getMetadata(SLATE_URL, "")  );
	node.setMimeType( xmp.DHTML_MIME_TYPE );
	node.setEndedFrame( xmp.LAST_FRAME );			
};

/********************************************************************************
 ** AdNodeListener
 ** - drives ad videos
 *******************************************************************************/

var AD_NODE_LISTENER = "Ad";

function AdNodeListener( player ) {
	AdNodeListener.ctor.call( this, AD_NODE_LISTENER, player, true );
	this._logger = new xmp.util.internals.CategoryLogger( 'AdNodeListener' );	
}

xmp.DERIVE_CLASS( BaseNodeListener, AdNodeListener );

AdNodeListener.prototype.canUserControl = function(node) {
	var canControl = xmp.util.SettingsManager.getInstance().getContextNode().getNodeForPath('BasePlayer').getBoolean('user can control ad', false);	
	return canControl;
};
AdNodeListener.prototype.handleInitialize = function( node ) {	 };
AdNodeListener.prototype.handlePlay = function( node ) {
	callControllerMethod('setScrubberEnabled',false);
};
AdNodeListener.prototype.handleOpen = function( node ) {
	if ( node.getNodeTypeId() != "AdInsertNotForSale" && CNNPlaylistManager.getInstance().activePlaylist != 'hottplaylist' && CNNPlaylistManager.getInstance().activePlaylist != 't1playlist' && CNNPlaylistManager.getInstance().activePlaylist != 'saplaylist') {
		if (CNNPlaylistManager.getInstance().doNotResetSynchOnPreroll == false || CNNPlaylistManager.getInstance().sensitiveSynchDisplaying == true) {
			CNNPlaylistManager.getInstance().sensitiveSynchDisplaying = false;
			this.loadSynchUnit(node);	
		} else {
			CNNPlaylistManager.getInstance().doNotResetSynchOnPreroll = false;
		}
	}
};
AdNodeListener.prototype.handleComplete = function( node ) {	
	CNNPlaylistManager.getInstance().mosSlateActive = false;
	var item = node.getPlayableData();
	var mimeType = item.getMimeTypeArray()[0]; 
	var ext = ".flv";
	if (mimeType === 'video/x-ms-wmv') { ext = ".wmv"; }
	var relativeUri = item.getPlayableId() + ext;
	
	node.setURI( this.getPlayer().getAbsoluteURI( relativeUri, 'adVideo' ) );
	node.setMimeTypes( [mimeType] );
	node.setStreamingMode( xmp.AD_STREAMING_MODE );	
	node.setEndedFrame( xmp.LAST_FRAME );
	
	callControllerMethod('setEnabled',true);
	callControllerMethod('setScrubberEnabled',false);
	callControllerMethod('setDuration', node.getPlayableData().getDataObject().trt);

	if (CNNPlaylistManager.getInstance().activePlaylist != 'hottplaylist' && CNNPlaylistManager.getInstance().activePlaylist != 't1playlist') {
		nextNode = this._findNextContentNode();
		if (nextNode != null) {
			if (CNNPlaylistManager.getInstance().playlistType == 'bvp') {
				if (CNNPlaylistManager.getInstance('bvpplayer').isSmall) { hideComments(); }
				//document.getElementById('commentHolder1').style.display = 'none';
				document.getElementById('cnnVPCHdr').style.display = 'none';
				//document.getElementById('commentHolder2').style.display = 'none';
				document.getElementById('videoComments').innerHTML = '';
				CNNPlaylistManager.getInstance().BVPMWriteContent(nextNode.getPlayableData().getDataObject());
				if (nextNode.getPlayableData().getDataObject().providedBy != null) {
					document.getElementById('providedByL').innerHTML = '<b>Source: '+CNNPlaylistManager.providedResponse(nextNode.getPlayableData().getDataObject().providedBy)+'</b>';
					document.getElementById('providedByS').innerHTML = '<b>Source: '+CNNPlaylistManager.providedResponse(nextNode.getPlayableData().getDataObject().providedBy)+'</b>';
				}
				else {
					document.getElementById('providedByL').innerHTML = ''; 
					document.getElementById('providedByS').innerHTML = ''; 
				}
				if (nextNode.getPlayableData().getDataObject().dateCreated != null) {
					document.getElementById('addedOnL').innerHTML = '<b>Added On</b> '+nextNode.getPlayableData().getDataObject().dateCreated;
					document.getElementById('addedOnS').innerHTML = '<b>Added On</b> '+nextNode.getPlayableData().getDataObject().dateCreated;
				}
				else {
					document.getElementById('addedOnL').innerHTML = ''; 
					document.getElementById('addedOnL').innerHTML = ''; 
				}
			} else if (CNNPlaylistManager.getInstance().playlistType == 'mos') {
				CNNPlaylistManager.getInstance().MOSContentWrite(nextNode.getPlayableData().getDataObject());
			} else if (CNNPlaylistManager.getInstance().activePlaylist == 'saplaylist') {
//				CNNPlaylistManager.getInstance().SAConfiguration.updateContentHandler(nextNode.getPlayableData().getDataObject());
			}
		} 
	}
};
AdNodeListener.prototype.handleDynamicRules = function(node) {
   var nodeTypeId = node.getNodeTypeId();
   if ((nodeTypeId === 'PreRoll') && !this.PreRollFound ) {
		this.PreRollFound = true;
		if ( CNNRules.DontPlayRule.isActive() ) {
		  var ruleContext = null;
		  this.getPlayer().registerRuleClass("DontPlayRule", "CNNRules.DontPlayRule");
		  ruleContext = xmp.playlistapi.RuleContext.createDynamic("DontPlayRule",null);
		  node.addRule(ruleContext);
		}
  }
};
AdNodeListener.prototype.handleOverrideAdResources = function(node, overrideContext) {
	var contextName = overrideContext.expandString('${player.context_name}');
	var nodeTypeId = node.getNodeTypeId();
	if (CNNPlaylistManager.getInstance().activePlaylist == 'mosplaylist') {
		if (nodeTypeId == 'PreRoll' || nodeTypeId == 'PostRoll') {	
			overrideContext.getResource('primary').setId(overrideVideoAd);
			overrideContext.getResource('synch_unit').setId(overrideSyncAd);
		}
	}
	if (CNNPlaylistManager.getInstance().activePlaylist == 'hottplaylist' || CNNPlaylistManager.getInstance().activePlaylist == 't1playlist') {
		if (nodeTypeId === 'PostRoll')
		{
			overrideContext.getResource('primary').setId(overrideVideoAd);
		}
	}
};
AdNodeListener.prototype.handleRender = function( node ) {           
            var res = node.getMetaResource('primary');
            if (res !== null)
            {
                        this._logger.info('Playing ad with tile ID: ' + res.getCompanionAdId());
            }
            // Allow base to open
            VideoNodeListener.base.handleRender.call( this, node );   
};
/********************************************************************************
 ** EndOverlayNodeListener
 ** - not used
 *******************************************************************************/

var END_OVERLAY_NODE_LISTENER = "EndOverlay";
var END_OVERLAY_OPTIONS_GROUP = "End";
var END_REPLAY_OVERLAY = "EndReplay";
var END_EMAIL_OVERLAY = "EndEmail";		
var END_RELATED_OVERLAY = "EndRelated";
var END_REPLAY_IMAGE_SRC = "replay.jpg";
var END_EMAIL_IMAGE_SRC = "email.jpg";

function EndOverlayNodeListener( player ) {
	EndOverlayNodeListener.ctor.call( this, END_OVERLAY_NODE_LISTENER, player );		
}

xmp.DERIVE_CLASS( OverlayNodeListener, EndOverlayNodeListener );

EndOverlayNodeListener.prototype.createOverlays = function() { };
EndOverlayNodeListener.prototype.createOverlay = function( name, location, html ) { };
EndOverlayNodeListener.prototype.render = function( node ) { };
EndOverlayNodeListener.prototype.handleComplete = function( node ) { };

/********************************************************************************
 ** ImageNodeListener
 ** - not used
 *******************************************************************************/

var IMAGE_NODE_LISTENER = "Image";

function ImageNodeListener( player ) {
	ImageNodeListener.ctor.call( this, IMAGE_NODE_LISTENER, player, true );		
}

xmp.DERIVE_CLASS( BaseNodeListener, ImageNodeListener );

ImageNodeListener.prototype.handleInitialize = function( node ) {	};
ImageNodeListener.prototype._getImageRelativeURL = function( imageType ) { };
ImageNodeListener.prototype._findContentNode = function( ) { };
ImageNodeListener.prototype.handleComplete = function( node ) {	};
ImageNodeListener.prototype.handlePlay = function( node ) { };

/********************************************************************************
 ** LowBandwidthNodeListener
 ** - will be used in future XMP release
 *******************************************************************************/

var START_SLATE_NODE_LISTENER = "LowBandwidth";
var IMAGE = "image";

function LowBandwidthNodeListener( player ) {
	LowBandwidthNodeListener.ctor.call( this, START_SLATE_NODE_LISTENER, player );
}  

xmp.DERIVE_CLASS( SlateNodeListener, LowBandwidthNodeListener );

LowBandwidthNodeListener.prototype.handleInitialize = function( node ) {	
	node.setMimeType( xmp.DHTML_MIME_TYPE );
	node.setEndedFrame( xmp.LAST_FRAME );			
};

/********************************************************************************
 ** NextupSlateNodeListener
 ** - drives DHTML object between video content pieces
 *******************************************************************************/

var NEXTUP_SLATE_NODE_LISTENER = "NextUpSlate";
var HEADLINE = "headline";

function NextUpSlateNodeListener( player ) {
	NextUpSlateNodeListener.ctor.call( this, NEXTUP_SLATE_NODE_LISTENER, player );
}  

xmp.DERIVE_CLASS( SlateNodeListener, NextUpSlateNodeListener );

NextUpSlateNodeListener.prototype.handleComplete = function( node ) {	
	CNNPlaylistManager.getInstance().mosSlateActive = true;
	NextUpSlateNodeListener.base.handleComplete.call( this, node );	
	nextNode = this._findNextContentNode();
	if (CNNPlaylistManager.getInstance().playlistType == 'bvp') {
		CNNPlaylistManager.getInstance().BVPMWriteContent(nextNode.getPlayableData().getDataObject());
		if (nextNode.getPlayableData().getDataObject().providedBy != null) {
			document.getElementById('providedByL').innerHTML = '<b>Source: '+CNNPlaylistManager.providedResponse(nextNode.getPlayableData().getDataObject().providedBy)+'</b>';
			document.getElementById('providedByS').innerHTML = '<b>Source: '+CNNPlaylistManager.providedResponse(nextNode.getPlayableData().getDataObject().providedBy)+'</b>';
		}
		else {
			document.getElementById('providedByL').innerHTML = ''; 
			document.getElementById('providedByS').innerHTML = ''; 
		}
		if (nextNode.getPlayableData().getDataObject().dateCreated != null) {
			document.getElementById('addedOnL').innerHTML = '<b>Added On</b> '+nextNode.getPlayableData().getDataObject().dateCreated;
			document.getElementById('addedOnS').innerHTML = '<b>Added On</b> '+nextNode.getPlayableData().getDataObject().dateCreated;
		}
		else {
			document.getElementById('addedOnL').innerHTML = ''; 
			document.getElementById('addedOnL').innerHTML = ''; 
		}
	} else if (CNNPlaylistManager.getInstance().playlistType == 'mos') {
		CNNPlaylistManager.getInstance().MOSContentWrite(nextNode.getPlayableData().getDataObject());
	} else if (CNNPlaylistManager.getInstance().activePlaylist == 'saplaylist') {
//		CNNPlaylistManager.getInstance().SAConfiguration.updateContentHandler(nextNode.getPlayableData().getDataObject());
	}
	node.setMetadata( HEADLINE, this._findNextContentNode().getPlayableData().getDataObject().headline );		
	node.setMetadata( 'trt', CNNPlayer.secondsIntoMinutes(this._findNextContentNode().getPlayableData().getDataObject().trt) );		

	var images = this._findNextContentNode().getPlayableData().getDataObject().images;
	var imageCount = images.length;
	var sizes = [];
	var sizeToResource = {};
		
	for ( var i = 0; i < imageCount; i++ ) {
		sizes.push( images[i].id );
		sizeToResource[ images[i].id ] = images[i].resource;
	}

	node.setMetadata( 'bgimage', CNNPlaylistManager.findImageSize(this._findNextContentNode().getPlayableData().getDataObject().images, CNNPlaylistManager.getInstance().slateSize) );
	node.setMetadata( 'smbgimage', CNNPlaylistManager.findImageSize(this._findNextContentNode().getPlayableData().getDataObject().images, '384x216'));
};

/********************************************************************************
 ** ErrorSlateNodeListener
 ** - shown if an error occurs in a video or if a video is expired
 *******************************************************************************/

var ERROR_SLATE_NODE_LISTENER = "ErrorSlate";

function ErrorSlateNodeListener( player ) {
	ErrorSlateNodeListener.ctor.call( this, ERROR_SLATE_NODE_LISTENER, player );
}  

xmp.DERIVE_CLASS( SlateNodeListener, ErrorSlateNodeListener );

ErrorSlateNodeListener.prototype.handleComplete = function( node ) {	
	CNNPlaylistManager.getInstance().mosSlateActive = true;
	ErrorSlateNodeListener.base.handleComplete.call( this, node );	
};

/********************************************************************************
 ** StartSlateNodeListener
 ** - drives the initial slab/slate
 *******************************************************************************/

var START_SLATE_NODE_LISTENER = "StartSlate";
var IMAGE = "image";

function StartSlateNodeListener( player ) {
	StartSlateNodeListener.ctor.call( this, START_SLATE_NODE_LISTENER, player );
}  

xmp.DERIVE_CLASS( SlateNodeListener, StartSlateNodeListener );

StartSlateNodeListener.prototype.handleComplete = function( node ) {	
	CNNPlaylistManager.getInstance().mosSlateActive = true;
	StartSlateNodeListener.base.handleComplete.call( this, node );	

	var images = this._findNextContentNode().getPlayableData().getDataObject().images;
	var imageCount = images.length;
	var sizes = [];
	var sizeToResource = {};
		
	for ( var i = 0; i < imageCount; i++ ) {
		sizes.push( images[i].id );
		sizeToResource[ images[i].id ] = images[i].resource;
	}

	node.setMetadata( IMAGE, CNNPlaylistManager.findImageSize(images, CNNPlaylistManager.getInstance().slateSize)); 
	if (CNNPlaylistManager.getInstance().activePlaylist != 'hottplaylist' && CNNPlaylistManager.getInstance().activePlaylist != 't1playlist') {
		this.loadSynchUnit(node);	
	}
};
StartSlateNodeListener.prototype.handleRender = function( node ) {
	if (CNNPlaylistManager.skipStartSlateButLoadSynch == true || CNNPlaylistManager.getInstance().vidString == 'CNNMosaicSingleVideoNonDefault' ||  CNNPlaylistManager.getInstance().vidString == 'CNNMosaicMultiVideoNonDefault') { // skip the start slate completely for these two
		this.getPlayer().advance();
	}
	else {
		this.getPlayer().getMediaPlayer().open( node );
	}
};
StartSlateNodeListener.prototype.handleOverrideAdResources = function(node, overrideContext) {
	if (CNNPlaylistManager.getInstance().activePlaylist != 'hottplaylist' && CNNPlaylistManager.getInstance().activePlaylist != 't1playlist') {
		houseAd = new xmp.playlistapi.Resource('/fn_adspaces/house/cnn_video/video.336x280_house.ad', 'synch_unit', {});
		var lookAheadArray = this.getPlayer().getLookAheadNodeArray();
		var foundOne = null;
		for (var i = 0; i < lookAheadArray.length; i++) {
			var testNode = lookAheadArray[i];
			if (testNode.getNodeTypeName() == 'Content') {
				// okay, we've got a content node, now figure if it's useable
				if (testNode.getPlayableData().getDataObject().trt >= 45) { // okay, this is valid, let's see if it's "sensitive"
					if (testNode.getPlayableData().getDataObject().isAdSensitive == false) { // it's not sensitive, here's our sign
						var sponsoredAdNode = null;
						var prerollAdNode = null;
						var postrollAdNode = null;
						for (var j = i+1; j < lookAheadArray.length; j++) {
							var nextNode = lookAheadArray[j];
							if (nextNode.getNodeTypeName() == 'Content') { break; }
							if (nextNode.getNodeTypeName() == 'PreRoll') { foundOne = nextNode; break; }
							if (nextNode.getNodeTypeName() == 'SponsoredAd') { foundOne = nextNode; break; }
							if (nextNode.getNodeTypeName() == 'PostRoll') { foundOne = nextNode; break; }
						}
						for (var j = i-1; j >= 0; j--) {
							var preNode = lookAheadArray[j];
							if (preNode.getNodeTypeName() == 'Content') { break; }
							if (preNode.getNodeTypeName() == 'PreRoll') { foundOne = preNode; }
							if (preNode.getNodeTypeName() == 'SponsoredAd') { foundOne = preNode; break; }
						}
						break;
					} else { // it is sensitive, break the for loop and go use a house ad
						break;
					}	
				}
			}
		}
		foundOne = null;
		if (foundOne != null) {
			CNNPlaylistManager.getInstance().doNotResetSynchOnPreroll = true;
			overrideContext.copyMetaResourceBundleRefFrom(foundOne);
			if (CNNPlaylistManager.getInstance().activePlaylist == 'mosplaylist' && foundOne.getNodeTypeName() != 'SponsoredAd') {
				overrideContext.getResource('primary').setId(overrideVideoAd);
				overrideContext.getResource('synch_unit').setId(overrideSyncAd);
			}
		} else { 
			CNNPlaylistManager.getInstance().sensitiveSynchDisplaying = true;
			overrideContext.addResource(houseAd); 
		}
	}
};

/********************************************************************************
 ** EndSlateNodeListener
 ** - drives the final slate
 *******************************************************************************/

var END_SLATE_NODE_LISTENER = "EndSlate";
var IMAGE = "image";

function EndSlateNodeListener( player ) {
	EndSlateNodeListener.ctor.call( this, END_SLATE_NODE_LISTENER, player );
}  

xmp.DERIVE_CLASS( SlateNodeListener, EndSlateNodeListener );

EndSlateNodeListener.prototype.handleComplete = function( node ) {	
	CNNPlaylistManager.getInstance().mosSlateActive = true;
	EndSlateNodeListener.base.handleComplete.call( this, node );	

	var images = this._findPreviousContentNode().getPlayableData().getDataObject().images;
	var imageCount = images.length;
	var sizes = [];
	var sizeToResource = {};
	
	for ( var i = 0; i < imageCount; i++ ) 	{
		sizes.push( images[i].id );
		sizeToResource[ images[i].id ] = images[i].resource;
	}

	node.setMetadata( IMAGE, CNNPlaylistManager.findImageSize(images,CNNPlaylistManager.getInstance().slateSize)); 
	node.setMetadata( 'smbgimage', CNNPlaylistManager.findImageSize(images, '384x216'));
};

/********************************************************************************
 ** VideoNodeListener
 ** - drives all video content nodes
 *******************************************************************************/

var VIDEO_NODE_LISTENER = "Video";

// Live video overlay group.
var LIVE_VIDEO_OVERLAY_GROUP = "LiveVideo";

// Connecting overlay.
var CONNECTING_OVERLAY = "Connecting";

// Connecting overlay image.
var CONNECTING_OVERLAY_IMAGE = "Connecting";


function VideoNodeListener( player ) {
	VideoNodeListener.ctor.call( this, VIDEO_NODE_LISTENER, player, false );		
	this.connectingOverlay = null;	
}

xmp.DERIVE_CLASS( BaseNodeListener, VideoNodeListener );

VideoNodeListener.prototype.showConnectingOverlay = function( )
{	
	// Validate connecting overlay.
	if ( !this.connectingOverlay )
	{
		// Create connecting overlay.
		this.connectingOverlay = this.getPlayer().getMediaPlayer().getViewport().createOverlay( LIVE_VIDEO_OVERLAY_GROUP, xmp.SLATE_OVERLAY, CONNECTING_OVERLAY );

		// Set connecting overlay html.
		this.connectingOverlay.setHTML( "<div><img src='http://money.cnn.com/video/globalforum/connecting.gif' class='cnnLivePlayer' alt='' border='0' /></div>" );							
	}
	
	// Show connecting overlay.
	this.connectingOverlay.show();	
};

VideoNodeListener.prototype.hideConnectingOverlay = function( )
{
	// Validate connecting overlay.
	if ( this.connectingOverlay )
	{
		// Hide connecting overlay.
		this.connectingOverlay.hide();
	}
};

VideoNodeListener.prototype.handleEnded = function( node ) {
	callControllerMethod('setEnabled',false);
	callControllerMethod('setTime',0);
	callControllerMethod('togglePlay',false);	
	CNNPlayer.getActivePlayer().callEnded();
}
VideoNodeListener.prototype.handleInitialize = function( node ) {	
	var item = node.getPlayableData();
	node.setMimeTypes( item.getMimeTypeArray() );
	node.setSizes( item.getDataObject().sizes );
	node.setURI( item.getDataObject().location );
	node.setStreamingMode( item.getDataObject().streamingMode );
	node.setEndedFrame( xmp.LAST_FRAME );			
};
var globalVideoInit = 0;
VideoNodeListener.prototype.handlePlay = function( node ) { };
VideoNodeListener.prototype.handleComplete = function( node ) {	
	CNNPlaylistManager.getInstance().mosSlateActive = false;
	if ("true" != node.getPlayableData().getDataObject().isLiveDelay) { 
		callControllerMethod('setEnabled', true);
		callControllerMethod('setScrubberEnabled',true);
		callControllerMethod('setDuration', node.getPlayableData().getDataObject().trt);
	} else {
		callControllerMethod('setEnabled', false);
		callControllerMethod('setScrubberEnabled',false);
		callControllerMethod('setTime',0);
		callControllerMethod('setDuration',0);
		callControllerMethod('togglePlay',false);	
	}
	if (CNNPlaylistManager.getInstance().playlistType == 'bvp') {
		CNNPlaylistManager.getInstance().BVPMWriteContent(node.getPlayableData().getDataObject());
		if (node.getPlayableData().getDataObject().providedBy != null) {
			document.getElementById('providedByL').innerHTML = '<b>Source: '+CNNPlaylistManager.providedResponse(node.getPlayableData().getDataObject().providedBy)+'</b>';
			document.getElementById('providedByS').innerHTML = '<b>Source: '+CNNPlaylistManager.providedResponse(node.getPlayableData().getDataObject().providedBy)+'</b>';
		}
		else {
			document.getElementById('providedByL').innerHTML = ''; 
			document.getElementById('providedByS').innerHTML = ''; 
		}
		if (node.getPlayableData().getDataObject().dateCreated != null) {
			document.getElementById('addedOnL').innerHTML = '<b>Added On</b> '+node.getPlayableData().getDataObject().dateCreated;
			document.getElementById('addedOnS').innerHTML = '<b>Added On</b> '+node.getPlayableData().getDataObject().dateCreated;
		}
		else {
			document.getElementById('addedOnL').innerHTML = ''; 
			document.getElementById('addedOnL').innerHTML = ''; 
		}
		if (node.getPlayableData().getDataObject().hasComments != null) {
			if (node.getPlayableData().getDataObject().hasComments == 'yes') {
				document.getElementById('commentHolder1').style.display = 'block';
				document.getElementById('cnnVPCHdr').style.display = 'block';
				document.getElementById('commentHolder2').style.display = 'block';
				ppp = CNNPlaylistManager.getInstance().playlists[CNNPlaylistManager.getInstance().activePlaylist];
				ppp = ppp.jsonList[ppp.pointer];
				slc = ppp.slice(ppp.lastIndexOf('/')+1,ppp.indexOf('.json'));
				document.commentsForm.threadName.value = slc;
				CSIManager.getInstance().call('http://'+cnnCommentDomain+'/comments/rss/rssmessages.jspa','full=true&outputType=JSON_BOXED&forumName=bvpvideo&threadName='+slc+'&numItems=50','objectid', iterateComments);	
			}
		}
	} else if (CNNPlaylistManager.getInstance().playlistType == 'mos') {
		CNNPlaylistManager.getInstance().MOSContentWrite(node.getPlayableData().getDataObject());
	} else if (CNNPlaylistManager.getInstance().activePlaylist == 'saplaylist') {
//		CNNPlaylistManager.getInstance().SAConfiguration.updateContentHandler(node.getPlayableData().getDataObject());
	}

	if (CNNPlaylistManager.getInstance().activePlaylist != 'hottplaylist' && CNNPlaylistManager.getInstance().activePlaylist != 't1playlist') {
		if (node.getPlayableData().getDataObject().isAdSensitive == true || 
				CNNPlaylistManager.getInstance().forceSensitive == true ||
				node.getPlayableData().getDataObject().trt < 45) { // we have a sensitive  video or a short video
			CNNPlaylistManager.getInstance().forceSensitive = false;
			if (CNNPlaylistManager.getInstance().sensitiveSynchDisplaying == false) { // we don't already have a house ad displaying
				CNNPlaylistManager.getInstance().sensitiveSynchDisplaying = true;
				this.loadSynchUnit(node);
			}
		} else {
			if (CNNPlaylistManager.getInstance().sensitiveSynchDisplaying) {
				CNNPlaylistManager.getInstance().sensitiveSynchDisplaying = false;
			}
		}
	}
};
VideoNodeListener.prototype.handleFirstFrameRendered = function( node )
{
	// Hide connecting overlay.
	this.hideConnectingOverlay();	

	// Allow base to handle first frame rendered.
	VideoNodeListener.base.handleFirstFrameRendered.call( this, node );		
};
VideoNodeListener.prototype.handleRender = function( node ) {
	if (node.getPlayableData().getDataObject().isLiveDelay != null) {
		this.showConnectingOverlay();		
	}
	if ("Expired" == node.getPlayableData().getDataObject().isExpired || 
			( "true" == node.getPlayableData().getDataObject().isLiveDelay && "true" == node.getPlayableData().getDataObject().isLiveDelayStreamOff )
			) { 
		callControllerMethod('setEnabled',false);
		callControllerMethod('setTime',0);
		callControllerMethod('togglePlay',false);	
		CNNPlaylistManager.getInstance().isVideoError = true;
		if ("true" == node.getPlayableData().getDataObject().isLiveDelay && "true" == node.getPlayableData().getDataObject().isLiveDelayStreamOff ) {
			CNNPlaylistManager.getInstance().slateMessage = node.getPlayableData().getDataObject().liveDelaySlateMessage;
		}
		this.getPlayer().advance();
	}
	else {
		this.getPlayer().getMediaPlayer().open( node );
	}
};
VideoNodeListener.prototype.handleError = function( node, err ) {
	callControllerMethod('setEnabled',false);
	callControllerMethod('setTime',0);
	callControllerMethod('togglePlay',false);	
	CNNPlaylistManager.getInstance().isVideoError = true;
	CNNPlaylistManager.getInstance().errorObject = err;
	this.getPlayer().advance();
};
VideoNodeListener.prototype.handleOverrideAdResources = function(node, overrideContext) {
        houseAd = new xmp.playlistapi.Resource('/fn_adspaces/house/cnn_video/video.336x280_house.ad', 'synch_unit', {});
        if (CNNPlaylistManager.getInstance().forceSensitive == true) {
                overrideContext.addResource(houseAd);
        } else {

	if (CNNPlaylistManager.getInstance().activePlaylist != 'hottplaylist' && CNNPlaylistManager.getInstance().activePlaylist != 't1playlist') {
		if (node.getPlayableData().getDataObject().isAdSensitive == true) {
			houseAd = new xmp.playlistapi.Resource('/fn_adspaces/house/cnn_video/video.336x280_house.ad', 'synch_unit', {});
			overrideContext.addResource(houseAd);
		}
		else {
			if (CNNPlaylistManager.getInstance().sensitiveSynchDisplaying) {
				// only need to run this case if sensitive is displaying and this node happens to be short
				// because otherwise, a preroll'd ad would've taken care of everything by now
				if (node.getPlayableData().getDataObject().trt < 45) {
					// iterate forward until we find the next valid pre, post or sponsored ad
					var lookAheadArray = this.getPlayer().getLookAheadNodeArray();
					var foundOne = null;
					for (var i = 0; i < lookAheadArray.length; i++) {
						var testNode = lookAheadArray[i];
						if (testNode.getNodeTypeName() == 'Content') {
							// okay, we've got a content node, now figure if it's useable
							if (testNode.getPlayableData().getDataObject().trt >= 45) { // okay, this is valid, let's see if it's "sensitive"
								if (testNode.getPlayableData().getDataObject().isAdSensitive == false) { // it's not sensitive, here's our sign
									var sponsoredAdNode = null;
									var prerollAdNode = null;
									var postrollAdNode = null;
									for (var j = i+1; j < lookAheadArray.length; j++) {
										var nextNode = lookAheadArray[j];
										if (nextNode.getNodeTypeName() == 'Content') { break; }
										if (nextNode.getNodeTypeName() == 'PreRoll') { foundOne = nextNode; break; }
										if (nextNode.getNodeTypeName() == 'SponsoredAd') { foundOne = nextNode; break; }
										if (nextNode.getNodeTypeName() == 'PostRoll') { foundOne = nextNode; break; }
									}
									for (var j = i-1; j >= 0; j--) {
										var preNode = lookAheadArray[j];
										if (preNode.getNodeTypeName() == 'Content') { break; }
										if (preNode.getNodeTypeName() == 'PreRoll') { foundOne = preNode; }
										if (preNode.getNodeTypeName() == 'SponsoredAd') { foundOne = preNode; break; }
									}
									break;
								} else { // it is sensitive, break the for loop and go use a house ad
									break;
								}	
							}
						}
					}
					foundOne = null;	
					if (foundOne != null) {
						CNNPlaylistManager.getInstance().doNotResetSynchOnPreroll = true;
						var newRes = new xmp.playlistapi.Resource(res.getId(), res.getType(), {});
						overrideContext.copyMetaResourceBundleRefFrom(testNode);
						if (CNNPlaylistManager.getInstance().activePlaylist == 'mosplaylist' && foundOne.getNodeTypeName() != 'SponsoredAd') {
							overrideContext.getResource('primary').setId(overrideVideoAd);
							overrideContext.getResource('synch_unit').setId(overrideSyncAd);
						}
					} else { 
						overrideContext.addResource(houseAd); 
					}			
				}
			}
		}
	} }
};

/********************************************************************************
 ** PromoNodeListener
 ** - new slate exclusively for promo content pieces
 *******************************************************************************/

var PROMO_NODE_LISTENER = "Promo";
 
function PromoNodeListener( player ) {
  PromoNodeListener.ctor.call( this, PROMO_NODE_LISTENER, player, false );            
}
 
xmp.DERIVE_CLASS( BaseNodeListener, PromoNodeListener );
 
PromoNodeListener.prototype.handleComplete = function( node ) {     
      var item = node.getPlayableData();
      node.setMimeTypes( item.getMimeTypeArray() );
      node.setSizes( item.getDataObject().sizes );
      node.setURI( item.getDataObject().location );
      node.setStreamingMode( item.getDataObject().streamingMode );
      node.setEndedFrame( xmp.LAST_FRAME );                 
};
 
PromoNodeListener.prototype.handleError = function( node, e ) {
      if (e instanceof xmp.util.LoadableDataException)
      {
            // TODO - temporary error handling code
      }
      PromoNodeListener.base.handleError.call( this, node, e );   
};



