<commit_before>( function( mw, $ ) {"use strict";

mw.PlaylistHandlerKaltura = function( playlist, options ){
	return this.init( playlist, options );
};
// For players playlist that don't have layout information
mw.setConfig('KalturaSupport.PlaylistDefaultItemRenderer', '<HBox id="irCont" height="100%" width="100%" x="10" y="10" verticalAlign="top" styleName="Button_upSkin_default"><Image id="irImageIrScreen" height="48" width="72" url="{this.thumbnailUrl}" source="{this.thumbnailUrl}"/><VBox height="100%" width="100%" id="labelsHolder" verticalGap="0"><HBox id="nameAndDuration" width="100%" height="18"><Label id="irLinkIrScreen" height="18" width="100%" text="{this.name}" styleName="itemRendererLabel" label="{this.name}" prefix="" font="Arial"/><Label id="irDurationIrScreen" height="18" width="70" text="{formatDate(this.duration, \'NN:SS\')}" styleName="itemRendererLabel" prefix="" font="Arial"/></HBox><Label id="irDescriptionIrScreen" width="240" height="18" text="{this.description}" styleName="itemRendererLabel" prefix="" font="Arial"/></VBox></HBox>');

mw.PlaylistHandlerKaltura.prototype = {

	clipList: null,
	widget_id: null,
	playlist_id: null,
	mrssHandler: null,

	playlistSet : [],

	titleHeight : 0, // Kaltura playlist include title via player ( not playlist )

	// ui conf data
	$uiConf : null,
	includeInLayout: true,

	// flag to store the current loading entry
	loadingEntry: null,

	bindPostFix: '.playlistHandlerKaltura',

	// store any playlist loading errors:
	errorMsg: null,

	init: function ( playlist, options ){
		this.playlist = playlist;
		// set all the options:
		for( var i in options){
			this[i] = options[i];
		}
	},
	getConfig: function( key ){
		return this.playlist.embedPlayer.getKalturaConfig( 'playlistAPI', key );
	},
	loadPlaylist: function ( callback ){
		var _this = this;
		var embedPlayer = this.playlist.embedPlayer;
		var $uiConf = embedPlayer.$uiConf;

		mw.log( "mw.PlaylistHandlerKaltura:: loadPlaylist > ");

		// check if we have playlist data
		if( !embedPlayer.kalturaPlaylistData ) {
			mw.log('Error: no playlists were found in embedPlayer.kalturaPlaylistData.');
			return false;
		}

		_this.playlistSet = [];
		// Populate playlist set with kalturaPlaylistData
		for (var playlistId in embedPlayer.kalturaPlaylistData ) {
			if (embedPlayer.kalturaPlaylistData.hasOwnProperty(playlistId)) {
			   _this.playlistSet.push( embedPlayer.kalturaPlaylistData[ playlistId ] );
			}
		}
		// Check if we have playlists
		if( _this.playlistSet.length == 0 ){
			mw.log( "Error: could not find any playlists." );
			return false;
		}		

		var plConf = _this.playlist.embedPlayer.getKalturaConfig(
				'playlist',
				[ 'includeInLayout', 'width', 'height' ]
		);
		// Check for autoContinue
		_this.autoContinue = _this.getConfig( 'autoContinue' );
		mw.log("mw.PlaylistHandlerKaltura::loadPlaylist > autoContinue: " + _this.autoContinue );

		// Set autoPlay
		_this.autoPlay =_this.getConfig( 'autoPlay' );

		// Check for loop
		_this.loop =_this.getConfig( 'loop' );

		// Set width:
		_this.videolistWidth = ( plConf.width )?  plConf.width : $uiConf.find('#playlist').attr('width');
		_this.videolistWidth = _this.videolistWidth ? _this.videolistWidth : 300;

		// Set height:
		_this.videolistHeight = ( plConf.height )?  plConf.height : $uiConf.find('#playlist').attr('height');

		if( plConf.includeInLayout === false || parseInt( $uiConf.find( '#playlistHolder' ).attr('width') ) == 0 ){
			_this.includeInLayout = false;
		} else if( parseInt( _this.videolistWidth ) == 0 ){
			_this.videolistWidth  = 250;
		}

		// Store all the playlist item render information:
		_this.$playlistItemRenderer = $uiConf.find('#playlistItemRenderer');
		if( _this.$playlistItemRenderer.children().length == 0  ){
			// No layout info use default
			var itemRenderer =  mw.getConfig('KalturaSupport.PlaylistDefaultItemRenderer');
			if (mw.isIE8()){
				// for IE8, add xml name spaces for custom HTML tags so jQuery can identify them
				itemRenderer = itemRenderer.split("<HBox").join("<HBox xmlns='HBox'");
				itemRenderer = itemRenderer.split("<VBox").join("<VBox xmlns='VBox'");
			}
			_this.$playlistItemRenderer = $(itemRenderer );
		}

		mw.log( "PlaylistHandlerKaltura:: got  " +  _this.playlistSet.length + ' playlists ' );
		// Set the playlist to the first playlist
		_this.setPlaylistIndex( 0 );

		// Load playlist by Id
		_this.loadCurrentPlaylist(function(){
			// Check if clipIndex should be updated
			var initItemEntryId = _this.getConfig( 'initItemEntryId' );
			if( initItemEntryId ){
				$.each( _this.getClipList(), function( inx, clip ){
					if( clip.id == initItemEntryId ){
						// Update the clipInx
						_this.playlist.clipIndex = inx;
					}
				});
			}
			if( $.isFunction( callback ) ){
				callback();
			}
		});
	},
	getPlaylistSize: function() {
		var embedPlayer =  this.playlist.getEmbedPlayer();

		// Get Width
		var pWidth = embedPlayer.getKalturaConfig('playlistHolder', 'width');
		if( ! pWidth ) {
			pWidth = embedPlayer.getKalturaConfig('playlist', 'width');
		}
		// Get Height
		var pHeight = embedPlayer.getKalturaConfig('playlistHolder', 'height');
		if( ! pHeight ) {
			pHeight = embedPlayer.getKalturaConfig('playlist', 'height');
		}

		// Add px if not percentage
		if( typeof pWidth == 'string' && pWidth.indexOf('%') == -1 ) {
			pWidth = pWidth + 'px';
		}
		if( typeof pHeight == 'string' && pHeight.indexOf('%') == -1 ) {
			pHeight = pHeight + 'px';
		}

		return {
			width: pWidth,
			height: pHeight
		};
	},
	setupPlaylistMode: function( layout ) {
		var _this = this;
		var embedPlayer =  this.playlist.getEmbedPlayer();

		// Hide our player if not needed
		var playerHolder = embedPlayer.getKalturaConfig('PlayerHolder', ["visible", "includeInLayout"]);
		if( ( playerHolder.visible === false  || playerHolder.includeInLayout === false ) && !embedPlayer.useNativePlayerControls() ) {
			embedPlayer.displayPlayer = false;
		}

		var updateLayout = function() {
			mw.log( "PlaylistHandlerKaltura:: updateLayout:" );
			var playlistSize = _this.getPlaylistSize();
			if( layout == 'vertical' ){
				if( playlistSize.height == '100%' ) {
					var windowHeight = window.innerHeight; 
					if( mw.getConfig( 'EmbedPlayer.IsFriendlyIframe' ) &&  mw.isIOS() ){
						// iOS window.innerHeight return the height of the entire content and not the window so we get the iframe height if we can
						windowHeight = $( window.parent.document.getElementById( embedPlayer.id ) ).height()
					} 
					playlistSize.height = ( windowHeight - embedPlayer.getComponentsHeight() );
				}
				_this.playlist.setVideoWrapperHeight( playlistSize.height );
			} else {
				_this.playlist.getVideoListWrapper().width( playlistSize.width );
			}
		};
		updateLayout();
		embedPlayer.bindHelper( 'updateLayout' + this.bindPostFix, function(){
			updateLayout()
		});
	},
	hasMultiplePlaylists: function(){
		return ( this.playlistSet.length > 1 );
	},
	hasPlaylistUi: function(){
		return this.includeInLayout;
	},
	isNextButtonDisplayed: function(){
		return !!this.playlist.getEmbedPlayer().$uiConf.find( '#nextBtnControllerScreen' ).length;
	},
	isPreviousButtonDisplayed: function(){
		return !!this.playlist.getEmbedPlayer().$uiConf.find( '#previousBtnControllerScreen' ).length;
	},
	getPlaylistSet: function(){
		return this.playlistSet;
	},
	getVideoListWidth: function(){
		// we have to add a bit for spacing ( should fix css files )
		return parseInt( this.videolistWidth ) + 10;
	},
	setPlaylistIndex: function( playlistIndex ){
		this.playlist_id = this.playlistSet[ playlistIndex ].id;
		var embedPlayer =  this.playlist.getEmbedPlayer();
		// Update the player data ( if we can )
		if( embedPlayer.kalturaPlaylistData ){
			embedPlayer.kalturaPlaylistData.currentPlaylistId = this.playlist_id;
		}
	},
	setClipIndex: function( clipIndex ){
		var embedPlayer =  this.playlist.getEmbedPlayer();
		// Update the player data ( if we can )
		if( embedPlayer.kalturaPlaylistData ){
			embedPlayer.kalturaPlaylistData.currentPlaylistId = this.playlist_id;
			embedPlayer.setKalturaConfig( 'playlistAPI', 'dataProvider', {'selectedIndex' : clipIndex} );
		}
	},
	loadCurrentPlaylist: function( callback ){
		this.loadPlaylistById( this.playlist_id, callback );
	},
	loadPlaylistById: function( playlist_id, loadedCallback ){
		var _this = this;
		mw.log("PlaylistHandlerKaltura::loadPlaylistById> " + playlist_id );
		var embedPlayer = this.playlist.embedPlayer;

		if( ! embedPlayer.kalturaPlaylistData ) {
			embedPlayer.kalturaPlaylistData = {};
		}

		// Local ready callback  to trigger playlistReady
		var callback = function(){
			// Check if player is ready before issuing playlist ready event
			if( embedPlayer.playerReadyFlag ) {
				embedPlayer.triggerHelper( 'playlistReady' );
			} else {
				embedPlayer.bindHelper('playerReady.playlistReady', function(){
					$( embedPlayer ).unbind( 'playerReady.playlistReady' );
					embedPlayer.triggerHelper( 'playlistReady' );
				});
			}
			// Issue the callback if set:
			if( $.isFunction( loadedCallback ) ){
				loadedCallback();
			}
		};

		// Check for playlist cache
		if( embedPlayer.kalturaPlaylistData[ playlist_id ] 
			&& embedPlayer.kalturaPlaylistData[ playlist_id ].items
			&& embedPlayer.kalturaPlaylistData[ playlist_id ].items.length ){
			_this.clipList = embedPlayer.kalturaPlaylistData[ playlist_id ].items;
			embedPlayer.setKalturaConfig( 'playlistAPI', 'dataProvider', {'content' : _this.clipList} );
			callback();
			return ;
		}

		var playlistRequest = {
			'service' : 'playlist',
			'action' : 'execute',
			'id': playlist_id
		};
		this.getKClient().doRequest( playlistRequest, function( playlistDataResult ) {
			// Empty the clip list
			_this.clipList = [];
			var playlistData;
			// The api does strange things with multi-playlist vs single playlist
			if( playlistDataResult[0] && playlistDataResult[0].id ){
				playlistData = playlistDataResult;
			} else if( playlistDataResult[0] && playlistDataResult[0][0].id ){
				playlistData = playlistDataResult[0];
			} else {
				mw.log("Error: kaltura playlist:" + playlist_id + " could not load:" + playlistDataResult.code);
				_this.errorMsg = "Error loading playlist:" + playlistDataResult.code;
				callback();
				return ;
			}
			mw.log( 'PlaylistHandlerKaltura::Got playlist of length::' +   playlistData.length );
			if( playlistData.length > mw.getConfig( "Playlist.MaxClips" ) ){
				playlistData = playlistData.splice(0, mw.getConfig( "Playlist.MaxClips" ) );
			}
			// Add it to the cache:
			embedPlayer.kalturaPlaylistData[ playlist_id ].items = playlistData;
			embedPlayer.setKalturaConfig( 'playlistAPI', 'dataProvider', {'content' : playlistData} );
			// update the clipList:
			_this.clipList = playlistData;
			callback();
		});
	},

	getKClient: function(){
		if( !this.kClient ){
			this.kClient = mw.kApiGetPartnerClient( this.widget_id );
		}
		return this.kClient;
	},

	/**
	 * Get clip count
	 * @return {number} Number of clips in playlist
	 */
	getClipCount: function(){
		return this.getClipList().length;
	},

	getClip: function( clipIndex ){
		return this.getClipList()[ clipIndex ];
	},
	getClipList: function(){
		return this.clipList;
	},
	playClip: function( embedPlayer, clipIndex, callback, shouldPause ){
		var _this = this
		if( !embedPlayer ){
			mw.log("Error:: PlaylistHandlerKaltura:playClip > no embed player");
			if( $.isFunction( callback ) ){
				callback();
			}
			return ;
		}
		// Send notifications per play request
		if( clipIndex == 0 ) {
			embedPlayer.triggerHelper( 'playlistFirstEntry' );
		} else if( clipIndex == (_this.getClipCount()-1) ) {
			embedPlayer.triggerHelper( 'playlistLastEntry' );
		} else {
			embedPlayer.triggerHelper( 'playlistMiddleEntry' );
		}

		// Check if entry id already matches ( and is loaded )
		if( embedPlayer.kentryid == this.getClip( clipIndex ).id ){
			if( this.loadingEntry ){
				mw.log("Error: PlaylistHandlerKaltura is loading Entry, possible double playClip request");
			}else {
				embedPlayer.play();
			}
			if( $.isFunction( callback ) ){
				callback();
			}
			return ;
		}
		// Update the loadingEntry flag:
		this.loadingEntry = this.getClip( clipIndex ).id;
		var originalAutoPlayState = embedPlayer.autoplay;

		// Listen for change media done
		var bindName = 'onChangeMediaDone' + this.bindPostFix;
		$( embedPlayer).unbind( bindName ).bind( bindName, function(){
			mw.log( 'mw.PlaylistHandlerKaltura:: onChangeMediaDone' );
			_this.loadingEntry = false;
			// Sync player size
			/*embedPlayer.bindHelper( 'loadeddata', function() {
				embedPlayer.layoutBuilder.syncPlayerSize();
			});*/
			// restore autoplay state: 
			embedPlayer.autoplay = originalAutoPlayState;
			embedPlayer.play();
			if( $.isFunction( callback ) ){
				callback();
			}
		});
		mw.log("PlaylistHandlerKaltura::playClip::changeMedia entryId: " + this.getClip( clipIndex ).id);

		// Update the playlist data selectedIndex ( before issuing change media call )
	 	_this.setClipIndex( clipIndex );
		// Use internal changeMedia call to issue all relevant events
	 	
	 	// set autoplay to true to continue to playback:
		embedPlayer.autoplay = true;
		if (shouldPause && shouldPause === true){
			mw.log("PlaylistHandlerKaltura::playClip::shouldPause = true. Will pause next clip.");
			embedPlayer.autoplay = false;
			// in case we don't have a preroll - autoplay
			setTimeout(function(){
				if (!embedPlayer.isInSequence()){
					mw.log("PlaylistHandlerKaltura::playClip::shouldPause = true but not isInSequence - continue playback.");
					embedPlayer.play();
				}
			},3000);
		}

		embedPlayer.sendNotification( "changeMedia", {'entryId' : this.getClip( clipIndex ).id, 'playlistCall': true} );
	},
	drawEmbedPlayer: function( clipIndex, callback ){
		var _this = this;
		var $target = _this.playlist.getVideoPlayerTarget();
		mw.log( "PlaylistHandlerKaltura::drawEmbedPlayer:" + clipIndex );
		// Get the embed
		var embedPlayer = _this.playlist.getEmbedPlayer();
		embedPlayer.doUpdateLayout();
		// update the selected index:
		_this.setClipIndex( clipIndex );

		// check if player already ready:
		if( embedPlayer.playerReadyFlag ){
			callback();
		} else {
			// Set up ready binding (for ready )
			$( embedPlayer ).bind('playerReady' + this.bindPostFix, function(){
				callback();
			});
		}

		// Call changeMedia
		if( embedPlayer.kentryid != this.getClip( clipIndex ).id ){
			embedPlayer.sendNotification( 'changeMedia', { entryId: this.getClip( clipIndex ).id} );
		}

	},
	updatePlayerUi: function( clipIndex ){
		// no updates need since kaltura player interface components are managed by the player
	},
	addEmbedPlayerBindings: function( embedPlayer ){
		var _this = this;
		mw.log( 'PlaylistHandlerKaltura:: addEmbedPlayerBindings');
		// remove any old bindings;
		$( embedPlayer ).unbind( this.bindPostFix );
		// add the binding:
		$( embedPlayer ).bind( 'Kaltura_SetKDPAttribute' + this.bindPostFix, function( event, componentName, property, value ){
			mw.log("PlaylistHandlerKaltura::Kaltura_SetKDPAttribute:" + property + ' value:' + value);
			switch( componentName ){
				case "playlistAPI.dataProvider":
					_this.doDataProviderAction( property, value );
				break;
				case 'tabBar':
					_this.switchTab( property, value )
				break;
			}
		});

		$( embedPlayer ).bind( 'Kaltura_SendNotification'+ this.bindPostFix , function( event, notificationName, notificationData){
			switch( notificationName ){
				case 'playlistPlayNext':
				case 'playlistPlayPrevious':
					mw.log( "PlaylistHandlerKaltura:: trigger: " + notificationName );
					$( embedPlayer ).trigger( notificationName );
					break;
			}
		});

		if (_this.autoContinue && embedPlayer.selectedPlayer.library === 'Kplayer'){
			mw.setConfig( 'EmbedPlayer.HidePosterOnStart' , true );
		}
	},
	switchTab:function( property, value ){
		if( property == 'selectedIndex' ){
			this.playlist.switchTab( value );
		}
	},
	doDataProviderAction: function ( property, value ){
		 switch( property ){
		 	case 'selectedIndex':
		 		// Update the selected clip ( and actually play it )
		 		this.playlist.playClip( parseInt( value ) );
			break;
		 }
	},
	/**
	* Get an items poster image ( return missing thumb src if not found )
	*/
	getClipPoster: function ( clipIndex, size ){
		if( this.mrssHandler ){
			return this.mrssHandler.getClipPoster( clipIndex, size );
		}
		var clip = this.getClip( clipIndex );
		if( !size ){
			return clip.thumbnailUrl;
		}
		return kWidget.getKalturaThumbUrl({
			'width': size.width,
			'height': size.height,<commit_msg>#PS-1670 #time 2h #comment removed embedPlayer.autoPlay=true and moved hide poster logic to after first play (include JavaScript player as well)<commit_after>( function( mw, $ ) {"use strict";

mw.PlaylistHandlerKaltura = function( playlist, options ){
	return this.init( playlist, options );
};
// For players playlist that don't have layout information
mw.setConfig('KalturaSupport.PlaylistDefaultItemRenderer', '<HBox id="irCont" height="100%" width="100%" x="10" y="10" verticalAlign="top" styleName="Button_upSkin_default"><Image id="irImageIrScreen" height="48" width="72" url="{this.thumbnailUrl}" source="{this.thumbnailUrl}"/><VBox height="100%" width="100%" id="labelsHolder" verticalGap="0"><HBox id="nameAndDuration" width="100%" height="18"><Label id="irLinkIrScreen" height="18" width="100%" text="{this.name}" styleName="itemRendererLabel" label="{this.name}" prefix="" font="Arial"/><Label id="irDurationIrScreen" height="18" width="70" text="{formatDate(this.duration, \'NN:SS\')}" styleName="itemRendererLabel" prefix="" font="Arial"/></HBox><Label id="irDescriptionIrScreen" width="240" height="18" text="{this.description}" styleName="itemRendererLabel" prefix="" font="Arial"/></VBox></HBox>');

mw.PlaylistHandlerKaltura.prototype = {

	clipList: null,
	widget_id: null,
	playlist_id: null,
	mrssHandler: null,

	playlistSet : [],

	titleHeight : 0, // Kaltura playlist include title via player ( not playlist )

	// ui conf data
	$uiConf : null,
	includeInLayout: true,

	// flag to store the current loading entry
	loadingEntry: null,

	bindPostFix: '.playlistHandlerKaltura',

	// store any playlist loading errors:
	errorMsg: null,

	init: function ( playlist, options ){
		this.playlist = playlist;
		// set all the options:
		for( var i in options){
			this[i] = options[i];
		}
	},
	getConfig: function( key ){
		return this.playlist.embedPlayer.getKalturaConfig( 'playlistAPI', key );
	},
	loadPlaylist: function ( callback ){
		var _this = this;
		var embedPlayer = this.playlist.embedPlayer;
		var $uiConf = embedPlayer.$uiConf;

		mw.log( "mw.PlaylistHandlerKaltura:: loadPlaylist > ");

		// check if we have playlist data
		if( !embedPlayer.kalturaPlaylistData ) {
			mw.log('Error: no playlists were found in embedPlayer.kalturaPlaylistData.');
			return false;
		}

		_this.playlistSet = [];
		// Populate playlist set with kalturaPlaylistData
		for (var playlistId in embedPlayer.kalturaPlaylistData ) {
			if (embedPlayer.kalturaPlaylistData.hasOwnProperty(playlistId)) {
			   _this.playlistSet.push( embedPlayer.kalturaPlaylistData[ playlistId ] );
			}
		}
		// Check if we have playlists
		if( _this.playlistSet.length == 0 ){
			mw.log( "Error: could not find any playlists." );
			return false;
		}		

		var plConf = _this.playlist.embedPlayer.getKalturaConfig(
				'playlist',
				[ 'includeInLayout', 'width', 'height' ]
		);
		// Check for autoContinue
		_this.autoContinue = _this.getConfig( 'autoContinue' );
		mw.log("mw.PlaylistHandlerKaltura::loadPlaylist > autoContinue: " + _this.autoContinue );

		// Set autoPlay
		_this.autoPlay =_this.getConfig( 'autoPlay' );

		// Check for loop
		_this.loop =_this.getConfig( 'loop' );

		// Set width:
		_this.videolistWidth = ( plConf.width )?  plConf.width : $uiConf.find('#playlist').attr('width');
		_this.videolistWidth = _this.videolistWidth ? _this.videolistWidth : 300;

		// Set height:
		_this.videolistHeight = ( plConf.height )?  plConf.height : $uiConf.find('#playlist').attr('height');

		if( plConf.includeInLayout === false || parseInt( $uiConf.find( '#playlistHolder' ).attr('width') ) == 0 ){
			_this.includeInLayout = false;
		} else if( parseInt( _this.videolistWidth ) == 0 ){
			_this.videolistWidth  = 250;
		}

		// Store all the playlist item render information:
		_this.$playlistItemRenderer = $uiConf.find('#playlistItemRenderer');
		if( _this.$playlistItemRenderer.children().length == 0  ){
			// No layout info use default
			var itemRenderer =  mw.getConfig('KalturaSupport.PlaylistDefaultItemRenderer');
			if (mw.isIE8()){
				// for IE8, add xml name spaces for custom HTML tags so jQuery can identify them
				itemRenderer = itemRenderer.split("<HBox").join("<HBox xmlns='HBox'");
				itemRenderer = itemRenderer.split("<VBox").join("<VBox xmlns='VBox'");
			}
			_this.$playlistItemRenderer = $(itemRenderer );
		}

		mw.log( "PlaylistHandlerKaltura:: got  " +  _this.playlistSet.length + ' playlists ' );
		// Set the playlist to the first playlist
		_this.setPlaylistIndex( 0 );

		// Load playlist by Id
		_this.loadCurrentPlaylist(function(){
			// Check if clipIndex should be updated
			var initItemEntryId = _this.getConfig( 'initItemEntryId' );
			if( initItemEntryId ){
				$.each( _this.getClipList(), function( inx, clip ){
					if( clip.id == initItemEntryId ){
						// Update the clipInx
						_this.playlist.clipIndex = inx;
					}
				});
			}
			if( $.isFunction( callback ) ){
				callback();
			}
		});
	},
	getPlaylistSize: function() {
		var embedPlayer =  this.playlist.getEmbedPlayer();

		// Get Width
		var pWidth = embedPlayer.getKalturaConfig('playlistHolder', 'width');
		if( ! pWidth ) {
			pWidth = embedPlayer.getKalturaConfig('playlist', 'width');
		}
		// Get Height
		var pHeight = embedPlayer.getKalturaConfig('playlistHolder', 'height');
		if( ! pHeight ) {
			pHeight = embedPlayer.getKalturaConfig('playlist', 'height');
		}

		// Add px if not percentage
		if( typeof pWidth == 'string' && pWidth.indexOf('%') == -1 ) {
			pWidth = pWidth + 'px';
		}
		if( typeof pHeight == 'string' && pHeight.indexOf('%') == -1 ) {
			pHeight = pHeight + 'px';
		}

		return {
			width: pWidth,
			height: pHeight
		};
	},
	setupPlaylistMode: function( layout ) {
		var _this = this;
		var embedPlayer =  this.playlist.getEmbedPlayer();

		// Hide our player if not needed
		var playerHolder = embedPlayer.getKalturaConfig('PlayerHolder', ["visible", "includeInLayout"]);
		if( ( playerHolder.visible === false  || playerHolder.includeInLayout === false ) && !embedPlayer.useNativePlayerControls() ) {
			embedPlayer.displayPlayer = false;
		}

		var updateLayout = function() {
			mw.log( "PlaylistHandlerKaltura:: updateLayout:" );
			var playlistSize = _this.getPlaylistSize();
			if( layout == 'vertical' ){
				if( playlistSize.height == '100%' ) {
					var windowHeight = window.innerHeight; 
					if( mw.getConfig( 'EmbedPlayer.IsFriendlyIframe' ) &&  mw.isIOS() ){
						// iOS window.innerHeight return the height of the entire content and not the window so we get the iframe height if we can
						windowHeight = $( window.parent.document.getElementById( embedPlayer.id ) ).height()
					} 
					playlistSize.height = ( windowHeight - embedPlayer.getComponentsHeight() );
				}
				_this.playlist.setVideoWrapperHeight( playlistSize.height );
			} else {
				_this.playlist.getVideoListWrapper().width( playlistSize.width );
			}
		};
		updateLayout();
		embedPlayer.bindHelper( 'updateLayout' + this.bindPostFix, function(){
			updateLayout()
		});
	},
	hasMultiplePlaylists: function(){
		return ( this.playlistSet.length > 1 );
	},
	hasPlaylistUi: function(){
		return this.includeInLayout;
	},
	isNextButtonDisplayed: function(){
		return !!this.playlist.getEmbedPlayer().$uiConf.find( '#nextBtnControllerScreen' ).length;
	},
	isPreviousButtonDisplayed: function(){
		return !!this.playlist.getEmbedPlayer().$uiConf.find( '#previousBtnControllerScreen' ).length;
	},
	getPlaylistSet: function(){
		return this.playlistSet;
	},
	getVideoListWidth: function(){
		// we have to add a bit for spacing ( should fix css files )
		return parseInt( this.videolistWidth ) + 10;
	},
	setPlaylistIndex: function( playlistIndex ){
		this.playlist_id = this.playlistSet[ playlistIndex ].id;
		var embedPlayer =  this.playlist.getEmbedPlayer();
		// Update the player data ( if we can )
		if( embedPlayer.kalturaPlaylistData ){
			embedPlayer.kalturaPlaylistData.currentPlaylistId = this.playlist_id;
		}
	},
	setClipIndex: function( clipIndex ){
		var embedPlayer =  this.playlist.getEmbedPlayer();
		// Update the player data ( if we can )
		if( embedPlayer.kalturaPlaylistData ){
			embedPlayer.kalturaPlaylistData.currentPlaylistId = this.playlist_id;
			embedPlayer.setKalturaConfig( 'playlistAPI', 'dataProvider', {'selectedIndex' : clipIndex} );
		}
	},
	loadCurrentPlaylist: function( callback ){
		this.loadPlaylistById( this.playlist_id, callback );
	},
	loadPlaylistById: function( playlist_id, loadedCallback ){
		var _this = this;
		mw.log("PlaylistHandlerKaltura::loadPlaylistById> " + playlist_id );
		var embedPlayer = this.playlist.embedPlayer;

		if( ! embedPlayer.kalturaPlaylistData ) {
			embedPlayer.kalturaPlaylistData = {};
		}

		// Local ready callback  to trigger playlistReady
		var callback = function(){
			// Check if player is ready before issuing playlist ready event
			if( embedPlayer.playerReadyFlag ) {
				embedPlayer.triggerHelper( 'playlistReady' );
			} else {
				embedPlayer.bindHelper('playerReady.playlistReady', function(){
					$( embedPlayer ).unbind( 'playerReady.playlistReady' );
					embedPlayer.triggerHelper( 'playlistReady' );
				});
			}
			// Issue the callback if set:
			if( $.isFunction( loadedCallback ) ){
				loadedCallback();
			}
		};

		// Check for playlist cache
		if( embedPlayer.kalturaPlaylistData[ playlist_id ] 
			&& embedPlayer.kalturaPlaylistData[ playlist_id ].items
			&& embedPlayer.kalturaPlaylistData[ playlist_id ].items.length ){
			_this.clipList = embedPlayer.kalturaPlaylistData[ playlist_id ].items;
			embedPlayer.setKalturaConfig( 'playlistAPI', 'dataProvider', {'content' : _this.clipList} );
			callback();
			return ;
		}

		var playlistRequest = {
			'service' : 'playlist',
			'action' : 'execute',
			'id': playlist_id
		};
		this.getKClient().doRequest( playlistRequest, function( playlistDataResult ) {
			// Empty the clip list
			_this.clipList = [];
			var playlistData;
			// The api does strange things with multi-playlist vs single playlist
			if( playlistDataResult[0] && playlistDataResult[0].id ){
				playlistData = playlistDataResult;
			} else if( playlistDataResult[0] && playlistDataResult[0][0].id ){
				playlistData = playlistDataResult[0];
			} else {
				mw.log("Error: kaltura playlist:" + playlist_id + " could not load:" + playlistDataResult.code);
				_this.errorMsg = "Error loading playlist:" + playlistDataResult.code;
				callback();
				return ;
			}
			mw.log( 'PlaylistHandlerKaltura::Got playlist of length::' +   playlistData.length );
			if( playlistData.length > mw.getConfig( "Playlist.MaxClips" ) ){
				playlistData = playlistData.splice(0, mw.getConfig( "Playlist.MaxClips" ) );
			}
			// Add it to the cache:
			embedPlayer.kalturaPlaylistData[ playlist_id ].items = playlistData;
			embedPlayer.setKalturaConfig( 'playlistAPI', 'dataProvider', {'content' : playlistData} );
			// update the clipList:
			_this.clipList = playlistData;
			callback();
		});
	},

	getKClient: function(){
		if( !this.kClient ){
			this.kClient = mw.kApiGetPartnerClient( this.widget_id );
		}
		return this.kClient;
	},

	/**
	 * Get clip count
	 * @return {number} Number of clips in playlist
	 */
	getClipCount: function(){
		return this.getClipList().length;
	},

	getClip: function( clipIndex ){
		return this.getClipList()[ clipIndex ];
	},
	getClipList: function(){
		return this.clipList;
	},
	playClip: function( embedPlayer, clipIndex, callback, shouldPause ){
		var _this = this
		if( !embedPlayer ){
			mw.log("Error:: PlaylistHandlerKaltura:playClip > no embed player");
			if( $.isFunction( callback ) ){
				callback();
			}
			return ;
		}
		// Send notifications per play request
		if( clipIndex == 0 ) {
			embedPlayer.triggerHelper( 'playlistFirstEntry' );
		} else if( clipIndex == (_this.getClipCount()-1) ) {
			embedPlayer.triggerHelper( 'playlistLastEntry' );
		} else {
			embedPlayer.triggerHelper( 'playlistMiddleEntry' );
		}

		// Check if entry id already matches ( and is loaded )
		if( embedPlayer.kentryid == this.getClip( clipIndex ).id ){
			if( this.loadingEntry ){
				mw.log("Error: PlaylistHandlerKaltura is loading Entry, possible double playClip request");
			}else {
				embedPlayer.play();
			}
			if( $.isFunction( callback ) ){
				callback();
			}
			return ;
		}
		// Update the loadingEntry flag:
		this.loadingEntry = this.getClip( clipIndex ).id;

		// Listen for change media done
		var bindName = 'onChangeMediaDone' + this.bindPostFix;
		$( embedPlayer).unbind( bindName ).bind( bindName, function(){
			mw.log( 'mw.PlaylistHandlerKaltura:: onChangeMediaDone' );
			_this.loadingEntry = false;
			// Sync player size
			/*embedPlayer.bindHelper( 'loadeddata', function() {
				embedPlayer.layoutBuilder.syncPlayerSize();
			});*/
			// restore autoplay state:
			embedPlayer.play();
			if( $.isFunction( callback ) ){
				callback();
			}
		});
		mw.log("PlaylistHandlerKaltura::playClip::changeMedia entryId: " + this.getClip( clipIndex ).id);

		// Update the playlist data selectedIndex ( before issuing change media call )
	 	_this.setClipIndex( clipIndex );
		// Use internal changeMedia call to issue all relevant events
	 	
	 	// set autoplay to true to continue to playback:
		if (shouldPause && shouldPause === true){
			mw.log("PlaylistHandlerKaltura::playClip::shouldPause = true. Will pause next clip.");
			embedPlayer.autoplay = false;
			// in case we don't have a preroll - autoplay
			setTimeout(function(){
				if (!embedPlayer.isInSequence()){
					mw.log("PlaylistHandlerKaltura::playClip::shouldPause = true but not isInSequence - continue playback.");
					embedPlayer.play();
				}
			},3000);
		}

		if (_this.autoContinue){ // hide poster if autoContinue
			mw.setConfig( 'EmbedPlayer.HidePosterOnStart' , true );
		}

		embedPlayer.sendNotification( "changeMedia", {'entryId' : this.getClip( clipIndex ).id, 'playlistCall': true} );
	},
	drawEmbedPlayer: function( clipIndex, callback ){
		var _this = this;
		var $target = _this.playlist.getVideoPlayerTarget();
		mw.log( "PlaylistHandlerKaltura::drawEmbedPlayer:" + clipIndex );
		// Get the embed
		var embedPlayer = _this.playlist.getEmbedPlayer();
		embedPlayer.doUpdateLayout();
		// update the selected index:
		_this.setClipIndex( clipIndex );

		// check if player already ready:
		if( embedPlayer.playerReadyFlag ){
			callback();
		} else {
			// Set up ready binding (for ready )
			$( embedPlayer ).bind('playerReady' + this.bindPostFix, function(){
				callback();
			});
		}

		// Call changeMedia
		if( embedPlayer.kentryid != this.getClip( clipIndex ).id ){
			embedPlayer.sendNotification( 'changeMedia', { entryId: this.getClip( clipIndex ).id} );
		}

	},
	updatePlayerUi: function( clipIndex ){
		// no updates need since kaltura player interface components are managed by the player
	},
	addEmbedPlayerBindings: function( embedPlayer ){
		var _this = this;
		mw.log( 'PlaylistHandlerKaltura:: addEmbedPlayerBindings');
		// remove any old bindings;
		$( embedPlayer ).unbind( this.bindPostFix );
		// add the binding:
		$( embedPlayer ).bind( 'Kaltura_SetKDPAttribute' + this.bindPostFix, function( event, componentName, property, value ){
			mw.log("PlaylistHandlerKaltura::Kaltura_SetKDPAttribute:" + property + ' value:' + value);
			switch( componentName ){
				case "playlistAPI.dataProvider":
					_this.doDataProviderAction( property, value );
				break;
				case 'tabBar':
					_this.switchTab( property, value )
				break;
			}
		});

		$( embedPlayer ).bind( 'Kaltura_SendNotification'+ this.bindPostFix , function( event, notificationName, notificationData){
			switch( notificationName ){
				case 'playlistPlayNext':
				case 'playlistPlayPrevious':
					mw.log( "PlaylistHandlerKaltura:: trigger: " + notificationName );
					$( embedPlayer ).trigger( notificationName );
					break;
			}
		});

	},
	switchTab:function( property, value ){
		if( property == 'selectedIndex' ){
			this.playlist.switchTab( value );
		}
	},
	doDataProviderAction: function ( property, value ){
		 switch( property ){
		 	case 'selectedIndex':
		 		// Update the selected clip ( and actually play it )
		 		this.playlist.playClip( parseInt( value ) );
			break;
		 }
	},
	/**
	* Get an items poster image ( return missing thumb src if not found )
	*/
	getClipPoster: function ( clipIndex, size ){
		if( this.mrssHandler ){
			return this.mrssHandler.getClipPoster( clipIndex, size );
		}
		var clip = this.getClip( clipIndex );
		if( !size ){
			return clip.thumbnailUrl;
		}
		return kWidget.getKalturaThumbUrl({
			'width': size.width,
			'height': size.height,
{'fraction_non_alphanumeric': 0.1359281797915286, 'fraction_numerical': 0.004669518587696572, 'mean_word_length': 4.050205385668645, 'pattern_counts': {'":': 2, '<': 31, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2495083', 'n_tokens_mistral': 12046, 'n_tokens_neox': 10487, 'n_words': 2413}