
bam.FlvPlayer = function(props){
		
	// private members
	var _swfObj; // will store SWFObject for this FlvPlayer
	var _fwSites = ["mlb","sny","yesnetwork","tigerwoods"]; // domains which support FreeWheel
	
	
	/**
	 * Private method for retrieving the domain using page URL, primarily for 
	 * non-MLB properties, as they don't have the "club" variable set. This method
	 * is called by _getDefaultSiteSectionArray when club value is unavailable.
	 * @return string
	 */
	function _getDomain(){
		var hostArr = document.location.hostname.toLowerCase().split("."), // for non-mlb properties which have no club var
				domain  = hostArr[hostArr.length-2] || "mlb";
		return domain;
	}
	
	
	/**
	 * Private method for retrieving ad network  based a on domain lookup.
	 * @return string "fw" or "dc"
	 */
	function _getAdNetwork(){
		return ($.inArray(_getDomain(), _fwSites)>-1) ? "fw" : "dc";
	}
	
	
	/** 
	* Private method for generating the default set of siteSection values. These values 
	* are ultimately joined with the pageComponent value and passed to the FlvPlayer as the 
	* siteSection string for use by the FreeWheel preroll Ad controller. If values cannot be 
	* generated (result of global variables not being available), a default string is returned.
	* @return string
	*/
	function _getDefaultSiteSectionArray(){
		var sectionArr = [];
		sectionArr.push(window.club    ? club    : _getDomain());
		sectionArr.push(window.section ? section : "");
		sectionArr.push(window.page_id ? page_id : (window.pageid) ?  pageid : "");  // some sites use pageid instead of page_id
		return (sectionArr.length) ? sectionArr : "not_available";
	};	


	var _swfProps = {
		// default props of SWFObject.
		file              : "/shared/flash/video/flvplayer_v3.swf",
		elemId            : "flvContainer_"+(new Date).getTime(),  // generate unique ID
		width             : 512,
		height            : 384,
		flashVersion      : "9",
		versionControl    : "4.2", // flv player version (includes freewheel stuff)
		allowScriptAccess : "always",
		allowFullScreen   : "true",
		salign            : "TL",
		videoAlign        : "top",
		volume            : 70,
		autoPlay          : true,
		autoHideSkin      : false,
		skinFadeDelay     : 1000,
		beginPosterPath   : null,
		endPosterPath     : null,
		menu              : "false",
		wmode             : "transparent",
		skin              : "/flash/video/y2009/skins/mlb_media_landing.swf",
		fullscreenSkin    : null,		
		debugMode         : false,
		playlist          : [],
		self              : null,
		scale             : "noScale",
		adConfig          : "/shared/flash/video/ad_config.xml",  //runtime dart configuration class
		
		// freewheel config
		adManager           : "http://adm.fwmrm.net/p/mlb_live/AdManager.swf", // beta:"http://adm.fwmrm.net/p/mlb_test/AdManager.swf", prod:"http://adm.fwmrm.net/p/mlb_live/AdManager.swf", local:"/shared/flash/ads/video/freewheel/AdManager.swf"
		adRenderXML         : "/shared/flash/ads/video/freewheel/renderers.xml",
		adNetwork           : "",
		adServer            : "",
		adProfile           : "",
		siteSectionArray    : _getDefaultSiteSectionArray(),
		pageComponent       : "embed", // default pageComponent
		fwTestNetwork       : false, // (typeof isProd!=="undefined") ? !isProd : false, // if not prod, test network is true
		fallbackNetwork     : null,
		fallbackNetworkTest : null,
		isFreeWheelSite     : (_getAdNetwork()==="fw"),
		
		companionSize     : "",  //companion ad size. format: 300x250, 728x90, etc. leave "" if there is no companion ad
		autoRewind        :	true 
	};
	$.extend(_swfProps, props);  // override defaults with passed params
	
	if (!_swfProps.siteSection){ // if siteSection wasn't set, set it
		_swfProps.siteSectionArray.push(_swfProps.pageComponent);
		_swfProps.siteSection = _swfProps.siteSectionArray.join("/");
	}
	
	
	/** 
	* _makeContainer() is a private method for creating a div which will serve
	* as the container for the SWF player.  It returns a referene to the created div.
	* @param {string} containerId
	*/ 
	var _makeContainer = function(containerId){
		$("<div id='"+containerId+"'></div>").appendTo("body");
		return $("#"+containerId)[0];
	};
	
	
	/** 
	* _getVersionSkin() is a private method for mapping the requested skin (path)
	* to the equivalent skin that's compatible with this version of the player.  While
	* hackish, this allows preserving existing references to skins while adding support
	* for the new player and skins compatible with it.  Also allows easy rollbacks.
	*/
	var _getVersionSkin = function(skinUrl){
		var skinRoot = "/flash/video/y2009/skins/";
		var skinMap  = {
			"/flash/video/y2008/skins/ads_countdown_skin.swf"   : skinRoot + "ad_countdown.swf",
			"/flash/video/y2008/skins/mlb_hpSkin.swf"           : skinRoot + "mlb_homepage.swf",
			"/flash/video/y2008/skins/mlb_mediaLandingSkin.swf" : skinRoot + "mlb_media_landing.swf",
			"/flash/video/y2008/skins/mlb_team_lookin.swf"      : skinRoot + "mlb_live_lookin.swf",
			"/flash/video/y2008/skins/mlb_teamHPmini.swf"       : skinRoot + "mlb_team_homepage.swf",
			
			"/flash/video/v2/skins/mlb_hpSkin.swf"              : skinRoot + "mlb_homepage.swf",
			"/flash/video/v2/skins/mlb_mediaLandingSkin.swf"    : skinRoot + "mlb_media_landing.swf",
			"/flash/video/v2/skins/mlb_teamHPmini.swf"          : skinRoot + "mlb_team_homepage.swf"
		};		
		var skin = skinMap[skinUrl] || _swfProps.skin; // use default if not in skinMap
		return skin;
	};
	
	
	/* priveledged methods */
	this.getPlaylist      = function(){ return _swfProps.playlist; }
	this.getDefaultVolume = function(){ return _swfProps.volume; }
	this.getStartObjSrc   = function(){ return this.startObjSrc; }
	this.getEndObjSrc     = function(){ return this.endObjSrc; }	
	this.getSiteSection   = function(){ return _swfProps.siteSection; } // for debuging
		

	/* public properties */
	this.swfElem;  // DOM element containing SWF for this instance of FlvPlayer
	this.elemId        = _swfProps.elemId; // needed to expose this to public methods
	this.self          = props.self;
	this.container     = document.getElementById(props.containerId) || _makeContainer(props.containerId);
	this.startObjSrc   = props.startObjSrc  || null;
	this.endObjSrc     = props.endObjSrc    || null;
	this.hideControls  = props.hideControls || true;
	this.debugMode     = props.debugMode    || false;	
	this.playerLoaded       = false;
	this.onPlayerLoaded     = props.onPlayerLoaded     || null;
	this.playlistBegin      = props.onPlaylistBegin    || null;	
	this.onPlaylistComplete = props.onPlaylistComplete || null;
	this.showCompanionAd    = props.showCompanionAd    || null;
	this.onCollapse         = props.onCollapse         || null;
	
	// ad playback events
	this.adPlaybackStart = props.adPlaybackStart || null;
	this.adPlaybackEnd   = props.adPlaybackEnd   || null;
	this.adOverlayStart  = props.adOverlayStart  || null;
	this.adOverlayEnd    = props.adOverlayEnd    || null;
	
	this.adPlatform = _swfProps.isFreeWheelSite ? "fw" : "dc"; // global preroll switch (fw/dc)
	

	/* initialize SWFObject */
	try { 
		_swfObj = new SWFObject(_swfProps.file, _swfProps.elemId, _swfProps.width, _swfProps.height, _swfProps.flashVersion);
		// add params
		_swfObj.addParam("allowScriptAccess", _swfProps.allowScriptAccess);	
		_swfObj.addParam("allowFullScreen",   _swfProps.allowFullScreen);
		_swfObj.addParam("menu",              _swfProps.menu);
		_swfObj.addParam("wmode",             _swfProps.wmode);
		_swfObj.addParam("scale",             _swfProps.scale);
		_swfObj.addParam("align",             "top");
		
		/* add variables */
		_swfObj.addVariable("versionControl", _swfProps.versionControl); // flv player version
		_swfObj.addVariable("isFreeWheelSite", _swfProps.isFreeWheelSite);
		
		if (_swfProps.salign != null)          _swfObj.addVariable("salign",          _swfProps.salign);
		if (_swfProps.videoAlign != null)      _swfObj.addVariable("videoAlign",      _swfProps.videoAlign);
		if (_swfProps.width != null)           _swfObj.addVariable("matchWidth",      _swfProps.width);
		if (_swfProps.height != null)          _swfObj.addVariable("matchHeight",     _swfProps.height);
		if (_swfProps.videoScaleMode != null)  _swfObj.addVariable("videoScaleMode",  _swfProps.videoScaleMode);
		if (_swfProps.volume != null)          _swfObj.addVariable("volume",          _swfProps.volume);
		if (_swfProps.autoPlay != null)        _swfObj.addVariable("autoPlay",        _swfProps.autoPlay);
		if (_swfProps.autoRewind != null)      _swfObj.addVariable("autoRewind",      _swfProps.autoRewind);
		if (_swfProps.autoHideSkin != null)    _swfObj.addVariable("autoHideSkin",    _swfProps.autoHideSkin);
		if (_swfProps.skinFadeDelay != null)   _swfObj.addVariable("skinFadeDelay",   _swfProps.skinFadeDelay);
		if (_swfProps.beginPosterPath != null) _swfObj.addVariable("beginPosterPath", _swfProps.beginPosterPath);
		if (_swfProps.endPosterPath != null)   _swfObj.addVariable("endPosterPath",   _swfProps.endPosterPath);
		if (_swfProps.skin != null)            _swfObj.addVariable("skin",            _getVersionSkin(_swfProps.skin));
		if (_swfProps.self != null)            _swfObj.addVariable("instanceName",    _swfProps.self);
		if (_swfProps.adConfig != null)        _swfObj.addVariable("adConfigXML",     _swfProps.adConfig);
		if (_swfProps.companionSize)           _swfObj.addVariable("companionSize",   _swfProps.companionSize);
		if (_swfProps.fullscreenSkin != null)  _swfObj.addVariable("fullscreenSkin",  _swfProps.fullscreenSkin);

		// freewheel support.  pass if set.
		if (_swfProps.adManager)               _swfObj.addVariable("adManager",       _swfProps.adManager);		
		if (_swfProps.adNetwork)               _swfObj.addVariable("adNetwork",       _swfProps.adNetwork);
		if (_swfProps.adServer)                _swfObj.addVariable("adServer",        _swfProps.adServer);
		if (_swfProps.adProfile)               _swfObj.addVariable("adProfile",       _swfProps.adProfile);
		if (_swfProps.siteSection)             _swfObj.addVariable("siteSection",     _swfProps.siteSection);

		if (_swfProps.fwTestNetwork)           _swfObj.addVariable("fwTestNetwork",       _swfProps.fwTestNetwork);
		if (_swfProps.fallbackNetwork)         _swfObj.addVariable("fallbackNetwork",     _swfProps.fallbackNetwork);
		if (_swfProps.fallbackNetworkTest)     _swfObj.addVariable("fallbackNetworkTest", _swfProps.fallbackNetworkTest);
		
		_swfObj.write(this.container.id);
	}
	catch(e){ 
		throw new Error("SWFObject could not be instantiated.");
	}
	
}


/* public static methods */
bam.FlvPlayer.prototype = {
	
	logError: function(msg){
		if (this.debugMode){
			if (typeof console!="undefined"){ console.log(msg); }
			if (typeof flash_debugger!="undefined"){ flash_debugger.log(msg); }
		}		
	},
	
	getInstance: function(){
		this.logError("retrieving specific instance of flvplayer (elemId: " + this.elemId + ")");
		this.swfElem = document.getElementById(this.elemId);
	},
	
	
	/** 
	* Generic handler for all supported swf (player) functions.
	* Currently, the following functions are known to be supported:
	* 	setPlaylist
	* 	startPlaylist
	* 	clearPlaylist
	* 	setPlaylistPostView
	* 	addToPlaylist
	* 	removeFromPlaylist
	* 	setBeginPoster
	* 	setEndPoster
	* @param {string} functionName
	* @param {anything} params
	*/
	execute: function(functionName, params){
		this.logError("bam.FlvPlayer."+functionName+"() was called.");
		if (this.swfElem[functionName]){
			if (typeof params != "undefined") this.swfElem[functionName](params);
			else this.swfElem[functionName]();
		}
		else throw new Error("bam.FlvPlayer.execute() was called with an invalid player function:" + functionName);
	},

	
	/** 
	* Provides backwards support for FlvPlayst 2.0 compatible playlist parameters.
	* @param {array} playlist
	*/ 	
	normalizePlaylist: function(playlist){
		this.logError("bam.FlvPlayer.normalizePlaylist()");
		var normalizedPlaylist = [],
				self = this;
		$.each(playlist, function(i, curItem){
			// skip newer playlist objects which shouldn't be normalized
			if (typeof curItem['stream']!=="undefined" || typeof curItem['content_id']!=="undefined"){ 
				self.logError("normalize added a stream or content_id equipped item.");
				normalizedPlaylist.push(curItem);
				return true; // if curItem was processed contine to avoid double processing
			}
			if (typeof curItem['prerollPath']!=="undefined"){
				curItem.path = curItem.prerollPath;
			}
			if (typeof curItem['videoPath']!=="undefined"){
				curItem.path = curItem.videoPath;
			}
			// do not normalize freewheelAd playlist items
			if ( (typeof curItem['type']!=="undefined")  && (curItem.type==="freewheelAd" || curItem.type==="video") ){
				self.logError("came accross freewheel ad or video. passing through.");				
				normalizedPlaylist.push(curItem);
				return true; // if curItem was processed contine to avoid double processing
			}
			else {
				self.logError("normalized current item.");
				normalizedPlaylist.push({type:curItem.type, path:curItem.path});
				return true; // if curItem was processed contine to avoid double processing
			}
		});
		return normalizedPlaylist;
	},


	/****************************************************************/	
	/** execute method aliases **************************************/
	setPlaylist    : function(playlist){ this.execute("setPlaylist",   this.normalizePlaylist(playlist)); },
	startPlaylist  : function(playlist){ this.execute("startPlaylist", this.normalizePlaylist(playlist)); },
	stopPlaylist   : function()        { this.execute("stopPlaylist"); },
	clearPlaylist  : function()        { this.execute("clearPlaylist"); },
	
	setBeginPoster : function(path){ this.execute("setBeginPoster", path); },
	setEndPoster   : function(path){ this.execute("setEndPoster",   path); }
};
