var CNN_PLAYER = "CNN_PLAYER";
var findPlayer = xmp.baseplayer.BasePlayer.findPlayer;
var playerInstances = new Array();
var currentPlayer = '';

function callControllerMethod(p_method, p_arg) {
	var returnVal;
	if (CNNPlaylistManager.getInstance().controller != null) {
		// we're using the DHTML control structure
		var cntl = CNNPlaylistManager.getInstance().controller;
		returnVal = cntl.handleXMPEvent(p_method, p_arg);
	} else {
		try {
			if ( CNNPlaylistManager.getInstance().activePlaylist == 'saplaylist' ) {
				returnVal = CNNPlaylistManager.getInstance().SAConfiguration.controlsHandler(p_method, p_arg);
			}
		} 
		catch(err) {
			// catch error and ignore, usually caused by xmp loading before controller plugin
		}
	}

	if ( typeof(returnVal) != "undefined" ) return returnVal;
}


function initAdServerCookies(docDomain)
{
	if (tkutils.Cookie.canUse()) // can the user read/write cookie values?
	{
		var cnnAdCookieIsSet = tkutils.Cookie.read('adDEon');
		if (!cnnAdCookieIsSet)
		{
			var imgSrc = 'http://gdyn.' + docDomain + '/1.1/1.gif';
			document.images['cookieCrumb'].src = imgSrc;
		}
	}		
}

function CNNPlayer(options, parameters) {
	initAdServerCookies('cnn.com');
	var categoryFilterArray = [/*'AjaxRequestManager', 'VideoContentMetaFileLoader'*/]; // allows filtering out of categories with too many messages.
	var parameters = [ ];
	CNNPlayer.ctor.call( this, CNN_PLAYER, options, parameters );	
}

xmp.DERIVE_CLASS( xmp.baseplayer.BasePlayer, CNNPlayer );

CNNPlayer.create = function() {

	var cnnIsIntl = (location.hostname.indexOf('edition.') > -1) ? true : false;
	var cnnIsIntlUS = (location.hostname.indexOf('us.') > -1) ? true : false;

	// if config.streamSize isn't defined, determine it based on slate size or use default
	var streamSize = CNNPlaylistManager.getInstance().SAConfiguration.streamSize;
	if (typeof(streamSize) == 'undefined') {
		streamSize = CNNPlayer.getStreamSize(CNNPlaylistManager.getInstance().SAConfiguration.slateSize)
	};

	var buildMap = {};
	buildMap['ad_pattern'] = CNNPlaylistManager.getInstance().SAConfiguration.adPattern;
	buildMap['slate_size'] = streamSize[0] + 'x' + streamSize[1];
	buildMap['omniture_trigger_command'] = CNNPlaylistManager.getInstance().SAConfiguration.omnitureTriggerCommand;

	if (cnnIsIntl) {
		buildMap['edition'] = 'edition';
		buildMap['omniture_account'] = 'cnnintl';
	} else if (cnnIsIntlUS) {
		buildMap['edition'] = 'us';
		buildMap['omniture_account'] = 'cnn2global';
	} else {
		buildMap['edition'] = 'www';
		buildMap['omniture_account'] = 'cnn2global';
	}		

	xmp.baseplayer.BasePlayer.configure([cnnXmpPrimaryJsonObj], buildMap);

	playerInstances[0] = new CNNPlayer({}, [ ]);
	playerInstances[0].bootStrap();
}

CNNPlayer.getStreamSize = function(slate) {
	var streams = CNNPlaylistManager.getInstance().SAConfiguration.availableStreamSizes;
	var ct = streams.length;
	for (var i=0; i<ct; i++) {
		if ((streams[i][0] == slate[0]) && (streams[i][1] == slate[1])) {
			return streams[i];
		}		
	}
	return CNNPlaylistManager.getInstance().SAConfiguration.defaultStreamSize;
}


CNNPlayer.prototype.callEnded = function() {
	CNNPlaylistManager.endOfVideoContent();
}
CNNPlayer.getInstance = function(id, context) {
	if (playerInstances[0] == null) {
	}
	return playerInstances[0];
}
CNNPlayer.setActivePlayer = function(str) { currentPlayer = str; }
CNNPlayer.getActivePlayer = function() {
	return playerInstances[0];
}
CNNPlayer.playlistContentItemCB = function() { }
CNNPlayer.secondsIntoMinutes = function(val) {
	minutes = Math.floor(val / 60);
	if (minutes > 0) seconds = val - (minutes * 60);
	else seconds = val;
	return (minutes + ':' + CNNPlayer.tenify(seconds));
}
CNNPlayer.tenify = function(val) {
	if (val - 0 < 10)
		return ("0"+val);
	return val;
}

CNNPlayer.prototype.serializerFactory = null;
CNNPlayer.prototype.playlist = null;
CNNPlayer.prototype.isSmall = false;
CNNPlayer.prototype.isScrubbing = false;
CNNPlayer.prototype.pluginError = null;
CNNPlayer.prototype.pluginErrorWindow = null;

CNNPlayer.prototype.handleLogMessage = function(level, category, message)
{
};

CNNPlayer.prototype.handleBootstrapped = function(success) {
	CNNPlaylistManager.isBootStrapped(success);
}

CNNPlayer.prototype.handleEvent = function(controllerEvent) {
	if (controllerEvent == 'playPressed') { this.playEx(); }
	if (controllerEvent == 'pausePressed') { this.pauseEx(); }
	if (controllerEvent == 'scrubStarted') { this.scrubStartedEx(); }
	if (controllerEvent == 'scrubComplete') { this.scrubCompleteEx(); }
	if (controllerEvent == 'volumeChanged') { this.volumeChangedEx(); }
	if (controllerEvent == 'sharePressed') { CNNPlaylistManager.getInstance().emailVideo(); }
}
CNNPlayer.prototype.volumeChangedEx = function() {
	this.setVolume( callControllerMethod('getVolume') );
}
CNNPlayer.prototype.pauseEx = function() {
	callControllerMethod('setScrubberEnabled',false);
	this.pause();
	callControllerMethod('togglePlay',false);
}
CNNPlayer.prototype.playEx = function() {
	this.play();
	callControllerMethod('setScrubberEnabled',true);
	callControllerMethod('togglePlay',true);
}
CNNPlayer.prototype.scrubStartedEx = function() {
	this.isScrubbing = true;
	callControllerMethod('togglePlay',false);
}
CNNPlayer.prototype.scrubCompleteEx = function() {
	this.isScrubbing = false;
	toVal = callControllerMethod('getTime');
	this.seek(toVal);
	callControllerMethod('togglePlay',true);
}
CNNPlayer.prototype.setPlaylist = function(idList,finalCallback) {

this.playlist = [];
this.serializerFactory = xmp.baseplayer.BasePlayer.createContentVideoMetaLoader(idList,
	this.playlist, CNNPlayer.playlistContentItemCB, finalCallback, this);
this.serializerFactory.load();

}
CNNPlayer.prototype.getPlaylist = function() {
	return this.playlist;
}
CNNPlayer.prototype.handleMediaPlayerReady = function(playerCtx) {
	if (playerCtx == this.getMainPlayerContext()) {
		callControllerMethod('setVolume',45);
		this.setVolume( 45 );
		this.setMute( false );
		this.setViewportConfig( xmp.FLASH_MIME_TYPE, xmp.DHTML_VIEWPORT );	
		this.setViewportConfig( xmp.WINDOWS_MEDIA_MIME_TYPE, xmp.DHTML_VIEWPORT );	
		this.setViewportConfig( xmp.IMAGE_MIME_TYPE, xmp.DHTML_VIEWPORT );	
		this.setViewportConfig( xmp.DHTML_MIME_TYPE, xmp.DHTML_VIEWPORT );	
	}
};

CNNPlayer.prototype.handleCreateViewport = function( type, name, parameters, settings ) {
	if ( type === xmp.DHTML_VIEWPORT ) {
		return this.createDHTMLViewport( type, name, parameters, settings );
	}
	return null;
};

CNNPlayer.prototype.handleFatalException = function( err ) {
	CNNPlaylistManager.getInstance().errorObject = err;
};

CNNPlayer.prototype.createDHTMLViewport = function( type, name, parameters, settings )  {
	o = 0;
	var viewport = document.createElement( "div" );
	viewport.setAttribute( xmp.ID_ATTRIBUTE, name );
	viewport.setAttribute( xmp.NAME_ATTRIBUTE, name );
	if (CNNPlaylistManager.getInstance().activePlaylist != 'saplaylist')
		var sample_container = document.getElementById( "cnnVPFlashLargeContainer" );
	else
		var sample_container = document.getElementById( CNNPlaylistManager.getInstance().SAConfiguration.videoDivId );
	viewport.style.width = CNNPlaylistManager.getInstance().SAConfiguration.slateSize[0]+"px";
	viewport.style.height = CNNPlaylistManager.getInstance().SAConfiguration.slateSize[1]+"px";
	viewport.style.backgroundColor = "#000000";	
										
	tkutils.insertDomChildBefore(sample_container, viewport);
	CNNPlaylistManager.getInstance().viewport = sample_container;
	CNNPlaylistManager.getInstance().atlasSlateSize = new Array(viewport.style.width, viewport.style.height);

	return viewport;
};


CNNPlayer.prototype.handleRegisterNodeListeners = function(playerCtx) {
	if (playerCtx == this.getMainPlayerContext()) {
		this._playerListener = new CNNPlayerListener('AllNodes', this);
		var listeners = [ {object: this._playerListener, nodes: ["*"]},
							{object: new AdNodeListener('Ad', this), nodes: ["PreRoll", "PostRoll", "SponsoredAd", "HouseAd", "AdInsertNotForSale"]},
							{object: new VideoNodeListener('Video', this), nodes: ["Content"]},
							{object: new GenericSlateNodeListener('GenericSlate', this), nodes: ["GenericSlate"]},
							{object: new xmp.baseplayer.listeners.DefaultSlateNodeListener('Slate', this), nodes: ["CustomSlate"]}
			              ];
			              
		for ( var i = 0; i < listeners.length; i++ ){
			this.registerNodeListener( listeners[i].object, listeners[i].nodes );	
		}						   
	}
};

CNNPlayer.prototype._findNextContentNode = function( ) {	
	var lookAhead = this.getLookAheadNodeArray();	
	for ( var i = 0; i < lookAhead.length; i++ ) {
		var node = lookAhead[i];
		if ( node.isContentType() ) {
			return node;
		}
	}	
	return null;
};
CNNPlayer.prototype._findPreviousContentNode = function( ) {	
	var lookBehind = this.getLookBehindNodeArray();
	for ( var i = 0; i < lookBehind.length; i++ )
	{
		var node = lookBehind[i];
		if ( node.isContentType() ) {
			return node;
		}
	}
	return null;
};

CNNPlayer.generateXMPErrorMessage = function(errorObjectCode) {
	switch (errorObjectCode) {
		case xmp.baseplayer.BasePlayer.getXmpErrorCodes().FATAL_PLATFORM:
			return "The web browser you are using to view this video is not supported.";
		case xmp.baseplayer.BasePlayer.getXmpErrorCodes().FATAL_PLUGIN:
			return "A plugin required to play your video could not be located.";
		case xmp.baseplayer.BasePlayer.getXmpErrorCodes().FATAL_PLUGIN_INIT:
			return "The video timed out attempting to play.";
		case xmp.baseplayer.BasePlayer.getXmpErrorCodes().CRITICAL_UNSPECIFIED_AJAX_ERROR:
			return "The video system was not able to establish connectivity due to a Proxy/Firewall or network connectivity.";
		case xmp.baseplayer.BasePlayer.getXmpErrorCodes().CRITICAL_PLAYER_CONNECTION:
			return "The video system was not able to establish connectivity due to a Proxy/Firewall or network connectivity.";
		default:
			return "Unspecified Fatal Error";
	}
}

CNNPlayer.prototype.renderAdResource = function(node, res, renderer)
{
	var resType = res.getType();
	var synchUnitLogger = xmp.baseplayer.BasePlayer.createCategoryLogger( 'loadSynchUnit' );
	if (res.isError())
	{
//		this._my_logger.warn('Error loading ' + resType + ': ' + res.getErrorMessage());
		return;
	}
	var data = res.getDataObject();
	var dataType = res.getDataType();
	var logData = (dataType === 'html') ? 'html' : data;

	synchUnitLogger.warn('Loading ' + resType + ' with tile ID: ' + res.getCompanionAdId() + ', url: ' + data);
	//alert('Loading ' + resType + ' with tile ID: ' + res.getCompanionAdId() + ', url: ' + data);
	
	var adDivId = 'banner_ad_div';
	var adIFrameId = 'banner_ad_iframe';
	
	if (resType.indexOf('_sponsored_ad') !== -1)
	{
		adDivId = 'sponsored_ad_div';
		adIFrameId = 'sponsored_ad_iframe';
	}
	
	synchUnitLogger.warn('Right before create banner ad');
    this._createBannerAd(adDivId, adIFrameId, data, dataType, res);
};

CNNPlayer.prototype._createBannerAd = function( adDivId, adIFrameId, data, dataType, resObj )
{
	CNNPlaylistManager.getInstance().SAConfiguration.loadSynchAd(data,resObj);
};

/*CNNPlayer.prototype.loadSynchUnit = function(node) {
	var resType = node.getPlayableData().getRuntimeMetadata('synch_unit_type', 'synch_unit');
	var res = node.getMetaResource(resType);
	var synchUnitLogger = new xmp.util.internals.CategoryLogger( 'loadSynchUnit' );

	if (!res) { return; }
	if (res.isError())
	{
		return;
	}

	// data will be the full URL of the banner ad call to the ad server
	var data = res.getDataObject();
	var dataType = res.getDataType();
	var logData = (dataType === 'html') ? 'html' : data;
	if (res.getMetadata('played_' + resType, false))
	{
		return;
	}
	res.setMetadata('played_' + resType, true);

  this._createBannerAd("banner_ad_iframe", data, dataType);
  this._playerListener.setStatus(node, xmp.SYNCH_UNIT);
};

// original version from cnn_adspaces.js (cnnad_createAd) - need to have a method that does not set the tile ID, we have already built it into the url.
CNNPlayer.prototype._createBannerAd = function( adId, data, dataType )
{
	CNNPlaylistManager.getInstance().SAConfiguration.loadSynchAd(data, adId);
};
*/

function StandAloneVideoConfiguration() {
	this.videoArray = new Array();
	this.vidString = 'SAVP';
	this.vidContext = 'SAVP';
	this.slateSize = new Array(384,216);

	this.availableStreamSizes = new Array([576,324], [384,216], [320,180], [256,144]);
	this.defaultStreamSize = new Array(384,216);
	this.syncDataArray = new Array();
	this.videoDivId = null;
	this.startPoint = 0;
	this.loadSynchUnit = false;
	this.overrideSynchUnit = null;
	this.synchUnitDiv = null;
	this.overrideVideoAd = true;
	this.playSponsoredAd = false;
	this.overridePostRoll = null;
	this.overridePreRoll = null;
	this.adList = null;
	this.adPattern = '/.element/js/2.0/video/widget/adPatterns/default.json';
	this.omnitureTriggerCommand = 'CNN.SpecialsOmnitureTriggerCommand';
	
	this.genericSlateHandler = function(slateType) {
		switch(slateType) {
			case 'startSlate':
				var backgroundImage = CNNPlaylistManager.findImageSize(CNNPlayer.getActivePlayer()._findNextContentNode().getPlayableData().getDataObject().images, CNNPlaylistManager.getInstance().slateSize)
				this.updateContentHandler(CNNPlayer.getActivePlayer()._findNextContentNode().getPlayableData().getDataObject());
				return this.startSlateHandler(backgroundImage);
				break;				
			case 'errorSlate':
				return this.errorSlateHandler(CNNPlaylistManager.getInstance().errorObject._code);
				break;				
			case 'nextSlate':
	  	  		var backgroundImage = CNNPlaylistManager.findImageSize(CNNPlayer.getActivePlayer()._findNextContentNode().getPlayableData().getDataObject().images, CNNPlaylistManager.getInstance().slateSize);
				return this.nextSlateHandler(backgroundImage,CNNPlayer.getActivePlayer()._findNextContentNode().getPlayableData().getDataObject());
				break;	
			case 'endSlate':
				var backgroundImage = CNNPlaylistManager.findImageSize(CNNPlayer.getActivePlayer()._findPreviousContentNode().getPlayableData().getDataObject().images, CNNPlaylistManager.getInstance().slateSize)
				return this.endSlateHandler(backgroundImage);
				break;				
			default: 	
				break;
		}
	}
	
	this.writeSyncIframe = function(h) {
		var ss = h + "";
		var adIter = ss.charAt(ss.indexOf('q=')+2) - 0;
		var b = document.getElementById(('adIter'+adIter+'Iframe'));
		var doc = b.contentDocument;
	    if (doc == undefined || doc == null)
	        doc = b.contentWindow.document;
	    doc.open();
	    doc.write(this.adList[adIter].data);
	    doc.close(); 						
	}

	this.adObject = function(divName, adName, dimensions) {
		this.divName = divName;
		this.adName = adName;
		this.dim = dimensions;
		this.data = null;
	}


	this.findAdObject = function(adName) {
		var ret = 0;
		for (var i = 0; i < this.adList.length; i++) {
			if (this.adList[i].adName == adName) {
				ret = i;
				return ret;
			}
		}
		return ret;
	}

	// handlers
	this.loadSynchAd = function(data,resObj) {
		var ll = data.toUpperCase();
		var adIter = this.findAdObject(resObj.getId());
		if (ll.indexOf('<SCRIPT') > -1) {
			this.adList[adIter].data = data;
			$(this.adList[adIter].divName).innerHTML = '<iframe hspace="0" vspace="0" marginHeight="0" marginWidth="0" src="/video/savp/iframeSync.html?q='+adIter+'" border="0" frameBorder="0" height="'+this.adList[adIter].dim[1]+'" width="'+this.adList[adIter].dim[0]+'" scrolling="no" id="adIter'+adIter+'Iframe" style="position: absolute;" ></iframe>';
		} else {
			$(this.adList[adIter].divName).innerHTML = data;
		}
	}
	this.bootErrorHandler = function() { }
	this.initHandler = function() { }
	this.controlsHandler = function() { }
	this.updateContentHandler = function() { }	
	this.errorSlateHandler = function() { }
	this.startSlateHandler = function() { }
	this.endSlateHandler = function() { }
}
