/*
    Encapsulates the media player functionality
    
    Parameters:
        comPropositionInstance  :  The instance of the ComPropositionInstance object.
        mediaPlayer             :  A reference to the media player object.
        view                    :  A reference to the web page.
        isOnline                :  A boolean indicating whether we are online or not (adverts will not be shown if offline).
        fromLibrary             :  A boolean indicating whether we are playing an item from the library, or whether we are streaming.
*/

function CliMediaPlayerController(clientController, mediaPlayer, view, isOnline, fromLibrary, hadLicenseDelivered) {


    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                          constants                                               //
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    /*  The name of the windows media player window  */
    var PLAYER_WINDOW_NAME = "mediaPlayer";
    /*  The name of the param element in the playlist that represents the media type  */
    var PARAM_MEDIATYPE = "MediaType";
    /*  The value of the param element in the playlist that represents the Advert media type  */
    var MEDIATYPE_ADVERT = "Advert";
    /*  The value of the param element in the playlist that represents the Video media type  */
    var MEDIATYPE_VIDEO = "Video";
    /*  Values for the media players playState property  */
    var PLAYSTATE_PAUSED = 2;
    var PLAYSTATE_PLAYING = 3;
    /*  The value for the PPV subscription type  */
    var SUBSCRIPTIONTYPE_PPV = "pay-per-view";
    
    
       
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                          members                                                 //
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    /*  A reference to the client controller  */
    var _clientController;
    /*  A reference to the com proposition instance  */
    var _comPropInstance;
    /*  A reference to the media player  */
    var _mediaPlayer;
    /*  A reference to the view (web page)  */
    var _view;
    /*  a flag to determine if the player is on online or offline mode  */
    var _isOnline;
    /*  true if playing form the library, false if streaming  */
    var _fromLibrary;
    /*  The kdx urn (to play from library)  */
    var _kdxUrn;
    /*  The url (to stream)  */
    var _url;
    /*  A reference to the ComLibraryItem for the current kdx urn */
    var _libraryItem;
    /*  timer used to store the current position if playing  */
    var _currentPositionTimer;        
    /*  indicates whether a license has been delivered as part of the curreent page request  */
    var _hadLicenseDelivered;
       
         
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                          initialise method                                       //
    //////////////////////////////////////////////////////////////////////////////////////////////////////   
    this.init = function CliMediaPlayerController_initialise (clientController, mediaPlayer, view, isOnline, fromLibrary, hadLicenseDelivered) {
        _clientController = clientController;
        _comPropInstance = clientController.getPropositionInstance();;
        _mediaPlayer = mediaPlayer;
        _view = view;
        _isOnline = isOnline;
        _fromLibrary = fromLibrary;
        _hadLicenseDelivered = hadLicenseDelivered;
    }
    
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                          Accessors                                               //
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    /*  Retrieves a reference to the media player  */
    this.getMediaPlayer = function() { return _mediaPlayer; }
    /*  Retrieves a reference to the ComLibraryItem for the current kdx urn */
    this.getLibraryItem = function() {
        if (_libraryItem==null) {
            _libraryItem = this.getPropInstance().VideoLibraryActions.GetItem( _kdxUrn);
        }
        return _libraryItem; 
    }
    /*  Retrieves a reference to the view  */
    this.getView = function() { return _view; }
    /*  Retrieves a reference to the current media item in the media players playlist  */
    this.getMedia = function() { return this.getMediaPlayer().currentMedia; }
    /*  A reference to the com proposition instance  */
    this.getPropInstance = function() { return _comPropInstance; }
  
    
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                          Methods                                                 //
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    /*  Retrieves the playlist for the current kdx urn.  If the app is online, adverts form part of the play list  */
    this._getPlaylist = function() {
        return this.getLibraryItem().GeneratePlaylist(_isOnline);    
    }
    
    /*  Plays the current kdx urn from the library  */        
    this.playMovieFromLibrary = function(kdxUrn) {
        _kdxUrn = kdxUrn;
        
        //  Load the playlist
        try {
            this.getMediaPlayer().URL = this._getPlaylist(); 
        }
        catch (e) { 
            CliDebug(e.description);
        }
        
        //  If a last position was stored, load the video and fast forward to that point in time 
        var secondsViewed = this.getLibraryItem().SecondsViewed;
        if (secondsViewed > 0) {
            var video = this._getVideoFromCurrentPlaylist();
            if (video!=null) {
                this.getMediaPlayer().controls.playItem(video);
                this.getMediaPlayer().controls.currentPosition = secondsViewed;
            }
        }
        
        // if online, automatically mark the item as completed as this is performed for us automatically by the player
        if (_isOnline && _fromLibrary) 
            this.getLibraryItem().CompletionRequired = false;

    }
    
    /*  Stream the current url */        
    this.playMovieFromStream = function(url, lastPosition) {
            
        _url = url;
        //  Load the playlist
        this.getMediaPlayer().URL = _url; 
        
        //  If a last position was provided, load the video and fast forward to that point in time 
        if (lastPosition!=null && lastPosition>0) {
            this.getMediaPlayer().controls.currentPosition = lastPosition;
        }
    }
    
    /*  Returns the main video from the currently loaded playlist  */
    this._getVideoFromCurrentPlaylist = function() {
        var playListCount = this.getMediaPlayer().currentPlaylist.count;
        for( var count = 0; count < playListCount; count++) {
            var mediaItem = this.getMediaPlayer().currentPlaylist.item(count);
            if ( this._isVideoMediaType(mediaItem))
                return mediaItem;
        }
    }
    
    /*  Stores the current position of the currently loaded media item in the kontiki cstore  */
    this._storeCurrentPosition = function() {
        if (this._isVideoMediaType(this.getMedia())) {
            var playState = this.getMediaPlayer().playState;
            if (playState == PLAYSTATE_PAUSED || playState == PLAYSTATE_PLAYING) {
                var currentPosition = Math.round(this.getMediaPlayer().controls.currentPosition);
                this.getLibraryItem().SecondsViewed = currentPosition;
            }
        }
    }
    
     /*  set up a timer to record the current position of the media  */
	this._initialiseCurrentPositionTimer = function() {
        if (this._isVideoMediaType(this.getMedia())) {
            if (this.getMediaPlayer().playState == PLAYSTATE_PLAYING) {
                var thisInstance = this;
                _currentPositionTimer = window.setTimeout( function() {
                    thisInstance._storeCurrentPositionInvokedFromTimer();
                    }, 10000);
            }
        }  
	}
	this._storeCurrentPositionInvokedFromTimer = function() {
	    this._storeCurrentPosition();
	    this._initialiseCurrentPositionTimer();
	}

    
    /*  Determines whether a media item is an Advert or Video media type  */
    this._isVideoMediaType = function(mediaItem) {
        if (mediaItem==null) return false;
        return ( mediaItem.getItemInfo(PARAM_MEDIATYPE) == MEDIATYPE_VIDEO);
    }
    
    /*  Increments the play count if the current media item is a Video media type.  Called from the MediaOpen OpenStateChange event  */
    this._incrementPlayCount = function() {
        if (this._isVideoMediaType(this.getMedia()))
            this.getLibraryItem().IncrementPlayCount();
    }
    
    /*  If the media item is PPV, set the license expired flag.  Called from the BeginLicenseAcquisition OpenStateChange event  */
    this._recordPpvLicenseExpired = function() {
        //TODO: remove references to this as its not needed
        //var libraryItem = this.getLibraryItem();
        //if (libraryItem.SubscriptionType==SUBSCRIPTIONTYPE_PPV)
        //    libraryItem.PpvLicenceExpired=true;       
    }
    
    /*  Encapsulates logic around having no license  */
    this._licenseExpired = function() {
        try {
            // close the media player to cancel the license acquisition message
		    this.getMediaPlayer().controls.stop();
		    this.getMediaPlayer().close();
		}
		catch (e) {}
		
		// if we have already had a license delivered in the current page request, refresh the page to attempt
		// to get a new license, else just display the license expired message
		if (_hadLicenseDelivered)
		    window.location.href = window.location.href;
		else
		    clientController.getKontikiHosted().launchNoLicenseMessage();
		
    }
     
    
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                          Events                                                 //
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    /*  Handles the OpenStateChange event of the media player  */
    this.handleMediaPlayerOpenStateChange = function(state) {
        /*
            0   Undefined Windows Media Player is in an undefined state. 
            1   PlaylistChanging        New playlist is about to be loaded. 
            2   PlaylistLocating        Windows Media Player is attempting to locate the playlist. The playlist can be local (Media Library or metafile with a .asx file name extension) or remote. 
            3   PlaylistConnecting      Connecting to the playlist. 
            4   PlaylistLoading         Playlist has been found and is now being retrieved. 
            5   PlaylistOpening         Playlist has been retrieved and is now being parsed and loaded. 
            6   PlaylistOpenNoMedia     Playlist is open. 
            7   PlaylistChanged         A new playlist has been assigned to currentPlaylist. 
            8   MediaChanging           A new media item is about to be loaded. 
            9   MediaLocating           Windows Media Player is locating the media item. The file can be local or remote. 
            10  MediaConnecting         Connecting to the server that holds the media item. 
            11  MediaLoading            Media item has been located and is now being retrieved. 
            12  MediaOpening            Media item has been retrieved and is now being opened. 
            13  MediaOpen               Media item is now open. 
            14  BeginCodecAcquisition   Starting codec acquisition. 
            15  EndCodecAcquisition     Codec acquisition is complete. 
            16  BeginLicenseAcquisition Acquiring a license to play DRM protected content. 
            17  EndLicenseAcquisition   License to play DRM protected content has been acquired. 
            18  BeginIndividualization  Begin DRM Individualization. 
            19  EndIndividualization    DRM individualization has been completed. 
            20  MediaWaiting            Waiting for media item. 
            21  OpeningUnknownURL       Opening a URL with an unknown type. 
        */
        
                
        switch( state )
        {
	        case 13: 
                if (!_fromLibrary)
                    return;
                this._incrementPlayCount();
                
                // is this in the correct place?
		        this._recordPpvLicenseExpired();
		        break;
		    case 16:
		        this._licenseExpired();
		        break;
        }
    }
    
    /*  Handles the PlayStateChange event of the media player  */
    this.handleMediaPlayerPlayStateChange = function (newState) {
        /*
            0   Undefined       Windows Media Player is in an undefined state. 
            1   Stopped         Playback of the current media item is stopped. 
            2   Paused          Playback of the current media item is paused. When a media item is paused, resuming playback begins from the same location. 
            3   Playing         The current media item is playing. 
            4   ScanForward     The current media item is fast forwarding. 
            5   ScanReverse     The current media item is fast rewinding. 
            6   Buffering       The current media item is getting additional data from the server. 
            7   Waiting         Connection is established, but the server is not sending data. Waiting for session to begin. 
            8   MediaEnded      Media item has completed playback.  
            9   Transitioning   Preparing new media item. 
            10  Ready           Ready to begin playing. 
            11  Reconnecting    Reconnecting to stream. 
        */
        
        if (!_fromLibrary) {
            return;
        }
                
	    switch( newState )
	    {
	        case 2 :  
                this._storeCurrentPosition();
                break;
            case 3  :
                this._initialiseCurrentPositionTimer();
                
                // the initialise timer is defined in playcontent.vm
                window.initialiseHeartBeatTimer();               
                break;
            case 8 :  
                this.getLibraryItem().SecondsViewed = 0;
                break;
	    }
    }
    
    /*  Handles the PositionChange event of the media player  */
    this.handleMediaPlayerPositionChange = function(oldPosition, newPosition) {
        
        if (!_fromLibrary)
            return;
            
        this._storeCurrentPosition();
    }
    
    /*  initialise  */
    this.init(clientController, mediaPlayer, view, isOnline, fromLibrary, hadLicenseDelivered);
    return true;
}


