﻿/************************************** Splendid *************************************
 * Created By:		Steve Doggett
 * Creation Date:	26th September 2007
 * Edited ----------------------------------------------------------------------------
 *      By:               On:
 * Description -----------------------------------------------------------------------
 *      This file creates the functionality for the Silverlight audio player
 *      Requires the CreateSilverlight.js, AudioPlayer.xaml file and Silverlight.js
 *
 *      AudioPlayer:
 *          Public Methods:
 *              Initialise(xamlBase, playlist, autoPlay)
 *              InitPlaylist(playlist)
 *              Play()
 *              Pause()
 *              Next()
 *              Previous()
 *              SetTrack()
 *              ChangeTrack()
 *              VolumeUp()
 *              VolumeDown()
 *              SetVolume()
 *              Mute()
 *              UnMute()
 *              GetMuted()
 *              MediaLoaded()
 *              SeekTo()
 *              GetSliderValue()
 *              SetSliderValue()
 *
 *          Internal Methods:
 *              _updateTime()
 *              _setVolumeElements()
 *              _setTrackName(name)
 *      
 **************************************************************************************/

/****
 * script version, update every time this changes!
 ****/
var SCRIPT_VERSION		=   "0.5"

/****
 * Standard player XAML control names
 ****/
var XAMLELEMENT_MEDIA               = "Media";              // the media element
var XAMLELEMENT_PLAYBUTTON          = "PlayButton";         // the play button
var XAMLELEMENT_PAUSEBUTTON         = "PauseButton";        // the pause button
var XAMLELEMENT_NEXTBUTTON          = "NextButton";         // the next button (next chapter)
var XAMLELEMENT_PREVIOUSBUTTON      = "PreviousButton";     // the previous button (prev chapter)
var XAMLELEMENT_NEXTBUTTONOVER      = "NextButtonOver";     // the next button click canvas
var XAMLELEMENT_PREVIOUSBUTTONOVER  = "PreviousButtonOver"; // the previous button click canvas
var XAMLELEMENT_MUTEBUTTON          = "MuteButton";         // mute button
var XAMLELEMENT_MUTEBUTTONADORNMENT = "MuteLines";          // adornment to mute button to show muted status
var XAMLELEMENT_VOLUMESLIDER        = "VolumeSlider";       // the volume slider bar
var XAMLELEMENT_VOLUMETHUMB         = "VolumeThumb";        // the volume slider thumb control
var XAMLELEMENT_CURRENTTIMETEXT     = "CurrentTimeText";    // the text area for the current media time
var XAMLELEMENT_CURRENTTRACKTEXT    = "CurrentTrackText";   // the text area for the current media track name
var XAMLELEMENT_VOLUMEBAR1          = "VolumeBar1";         // The first volume bar
var XAMLELEMENT_VOLUMEBAR2          = "VolumeBar2";         // The second volume bar
var XAMLELEMENT_VOLUMEBAR3          = "VolumeBar3";         // The third volume bar
var XAMLELEMENT_VOLUMEBAR4          = "VolumeBar4";         // The fourth volume bar
var XAMLELEMENT_SLIDER              = "slider";             // The slider control/canvas
var XAMLELEMENT_SLIDERLINE          = "slider_line";        // The slider bar
var XAMLELEMENT_SLIDERLINEOVER      = "slider_lineOver";    // The slider bar overlay
var XAMLELEMENT_THUMB               = "slider_thumb";       // The slider handle
var XAMLELEMENT_HIDEF               = "HiDef";              // Hi Def Selector
var XAMLELEMENT_LODEF               = "LoDef";              // Lo Def Selector

var BasePlayer = {
    m_playlist: null,
    m_currTrackNum: 0,
    m_baseCanvas: null,
    m_control: null,
    m_mediaElem: null,
    m_currentlyPlaying: false,
    m_tickTimer: null,
    m_muted: false,
    m_volumeLevel: 0.5,
    m_sliderInit: false,

    Initialise: function( xamlBase, playlist, autoPlay, initSlider )
    {/* Initialises the audio player. Ties it to the Silverlight Object */
        BasePlayer.m_control = xamlBase.getHost();
        BasePlayer.m_baseCanvas = xamlBase;
        BasePlayer.m_mediaElem = BasePlayer.m_baseCanvas.findName(XAMLELEMENT_MEDIA);
        this.InitPlaylist( playlist);
        
        // Initialise to the first track
        BasePlayer.m_mediaElem.Source = BasePlayer.m_playlist[BasePlayer.m_currTrackNum].src;

        // initialise volume to 50%
        BasePlayer.m_mediaElem.Volume = 0.5
        BasePlayer.m_volumeLevel = 0.5;
        this.SetVolume(2);
        
        BasePlayer.m_sliderInit = initSlider;
        if( BasePlayer.m_sliderInit == true ) 
            this.SetSliderValue(0);

        // Initialise play state
        if( autoPlay == true )
        {
            BasePlayer.m_mediaElem.AutoPlay = true;
            this.Play();
            BasePlayer.m_muted = 'False';
        }      
    },
    
    InitPlaylist: function(playlist)
    {/* Creates the playlist and sets it up for the first track */
        if( BasePlayer.m_mediaElem == null)
            alert('The Audio Player has not been initialised. Call the Initialise method first.');
            
        if( playlist != null )
        {
            BasePlayer.m_playlist = playlist;
            if( BasePlayer.m_playlist.length == 1 )
            {
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PREVIOUSBUTTONOVER).Visibility = 'Collapsed';
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_NEXTBUTTONOVER).Visibility = 'Collapsed';
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PREVIOUSBUTTON).Opacity = '0.3';
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_NEXTBUTTON).Opacity = '0.3';
            } else
            {
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PREVIOUSBUTTONOVER).Visibility = 'Visible';
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_NEXTBUTTONOVER).Visibility = 'Visible';
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PREVIOUSBUTTON).Opacity = '1';
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_NEXTBUTTON).Opacity = '1';
            }
        } else
        {
            alert('You must provide a playlist before you can initialise it.');
        }
        
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTRACKTEXT).Text = 'Loading...';
    },
    
    Play: function()
    {/* Provides the play functionality */
        BasePlayer.m_mediaElem.play();
        BasePlayer.m_currentlyPlaying = true;
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PLAYBUTTON).Visibility = 'Collapsed';
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PAUSEBUTTON).Visibility = 'Visible';

        this._updateTime();
        BasePlayer.m_tickTimer = setInterval(this._updateTime, 500);
    },
    
    Pause: function()
    {/* Pause the currently playing track */
        clearInterval(BasePlayer.m_tickTimer);
        BasePlayer.m_mediaElem.pause();
        BasePlayer.m_currentlyPlaying = false;
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PLAYBUTTON).Visibility = 'Visible';
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PAUSEBUTTON).Visibility = 'Collapsed';
    },
    
    Stop: function()
    {/* Pause the currently playing track */
        clearInterval(BasePlayer.m_tickTimer);
        BasePlayer.m_mediaElem.stop();
        BasePlayer.m_currentlyPlaying = false;
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PLAYBUTTON).Visibility = 'Visible';
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_PAUSEBUTTON).Visibility = 'Collapsed';
    },
    
    Next: function()
    {/* Play the next track in the playlist */
        // Set the track to loading
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTRACKTEXT).Text = 'Loading...';
        
        // Increment the track counter
        BasePlayer.m_currTrackNum++;
        if( BasePlayer.m_currTrackNum > BasePlayer.m_playlist.length-1 )
            BasePlayer.m_currTrackNum = 0;
            
        // Set the new source for the media element
        BasePlayer.m_mediaElem.Source = BasePlayer.m_playlist[BasePlayer.m_currTrackNum].src;
        
        clearInterval(BasePlayer.m_tickTimer);
    },

    Previous: function()
    {/* Play the previous track in the playlist */
        // Set the track to loading
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTRACKTEXT).Text = 'Loading...';
        
        // Decrease the track counter
        BasePlayer.m_currTrackNum--;
        if( BasePlayer.m_currTrackNum < 0 )
            BasePlayer.m_currTrackNum = BasePlayer.m_playlist.length-1;
            
        // Set the new source for the media element
        BasePlayer.m_mediaElem.Source = m_playlist[BasePlayer.m_currTrackNum].src;
        
        clearInterval(BasePlayer.m_tickTimer);
    },
    
    SetTrack: function( trackIdx )
    {/* Just sets the track number and nothing else */
        BasePlayer.m_currTrackNum = trackIdx;
    }, 
    
    ChangeTrack: function( trackIdx )
    {/* Plays the track from the playlist specified by the track index */
        BasePlayer.m_currTrackNum = trackIdx;
        try
        {
            // Set the new source for the media element
            BasePlayer.m_mediaElem.Source = BasePlayer.m_playlist[BasePlayer.m_currTrackNum].src;
        } catch(e)
        {
            BasePlayer.m_currTrackNum = 0;
            
            // Set the new source for the media element
            BasePlayer.m_mediaElem.Source = BasePlayer.m_playlist[BasePlayer.m_currTrackNum].src;
        }
        clearInterval(BasePlayer.m_tickTimer);
    },
    
    VolumeUp: function()
    {
        switch( BasePlayer.m_volumeLevel )
        {
            case 0.25:
                BasePlayer.m_volumeLevel = 0.5;
                BasePlayer.m_mediaElem.Volume = 0.5;
                this._setVolumeElements();
                break;
            case 0.5:
                BasePlayer.m_volumeLevel = 0.75;
                BasePlayer.m_mediaElem.Volume = 0.75;
                this._setVolumeElements();
                break;
            case 0.75:
                BasePlayer.m_volumeLevel = 1.0;
                BasePlayer.m_mediaElem.Volume = 1.0;
                this._setVolumeElements();
                break;
        }
    },
    
    VolumeDown: function()
    {
        switch( BasePlayer.m_volumeLevel )
        {
            case 1.0:
                BasePlayer.m_volumeLevel = 0.75;
                BasePlayer.m_mediaElem.Volume = 0.75;
                this._setVolumeElements(0.75);
                break;
            case 0.75:
                BasePlayer.m_volumeLevel = 0.5;
                BasePlayer.m_mediaElem.Volume = 0.5;
                this._setVolumeElements(0.5);
                break;
            case 0.5:
                BasePlayer.m_volumeLevel = 0.25;
                BasePlayer.m_mediaElem.Volume = 0.25;
                this._setVolumeElements(0.25);
                break;
        }
    },   
    
    SetVolume: function( volume )
    {
        
        switch( volume )
        {
            case 1:
                BasePlayer.m_volumeLevel = 0.25;
                BasePlayer.m_mediaElem.Volume = 0.25;
                this._setVolumeElements(0.25);
                break
            case 2:
                BasePlayer.m_volumeLevel = 0.5;
                BasePlayer.m_mediaElem.Volume = 0.5;
                this._setVolumeElements(0.5);
                break
            case 3:
                BasePlayer.m_volumeLevel = 0.75;
                BasePlayer.m_mediaElem.Volume = 0.75;
                this._setVolumeElements(0.75);
                break
            case 4:
                BasePlayer.m_volumeLevel = 1.0;
                BasePlayer.m_mediaElem.Volume = 1.0;
                this._setVolumeElements(1.0);
                break
        }
    }, 
    
    Mute: function()
    {/* Mute the audio */
        // Change the mute symbol
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_MUTEBUTTONADORNMENT).Visibility = 'Collapsed';
        //m_mediaElem.SetMute(true);
        BasePlayer.m_mediaElem.IsMuted = 'True';
        BasePlayer.m_muted = true;
        
        // Need to reset the volume bars off too
        this._setVolumeElements(0);
    },
    
    UnMute: function()
    {/* UnMute the audio */
        // Change the mute symbol
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_MUTEBUTTONADORNMENT).Visibility = 'Visible';
        //m_mediaElem.SetMute(false);
        BasePlayer.m_mediaElem.IsMuted = 'False';
        BasePlayer.m_muted = false;
        
        // Reset the volume ars back too
        this._setVolumeElements(BasePlayer.m_volumeLevel);
    },
    
    GetMuted: function()
    {/* Returns whether the player is currently muted */
        return BasePlayer.m_muted;
    },

    MediaLoaded: function()
    {/* Handles the media loaded event */
        this._setTrackName(BasePlayer.m_playlist[BasePlayer.m_currTrackNum].name);

        // If auto play is selected, then will automatically play, so want to check
        // we have everything set up correctly as playing.
        // playOnLoad is a global variable set up elsewhere, so this needs looking at properly!
        if( BasePlayer.m_currentlyPlaying )
            this.Play();
        else    
            this.Pause();
    },
    
    SeekTo: function()
    {
        var thumb = BasePlayer.m_baseCanvas.findName(XAMLELEMENT_THUMB);
        var pos = thumb["Canvas.Left"];
        var slider= BasePlayer.m_baseCanvas.findName(XAMLELEMENT_SLIDER);
        var duration = Math.ceil(BasePlayer.m_mediaElem.NaturalDuration.Seconds);
        var step = pos/slider.width;
        var newPos = step*duration;
        var seconds = 0;
        var minutes = 0;
        
        // Set the track to loading
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTRACKTEXT).Text = 'Loading...';
        
        timeString = '00:';
        
        // Check for minutes 
        minutes = Math.floor(newPos / 60);
        if (minutes.length == 1)
	        minutes = '0' + minutes;
        	
        timeString += minutes+':';
        
        // Now work on the seconds
        seconds = Math.floor(newPos) % 60;
        if (seconds < 10)
	        timeString += '0';

        timeString += seconds;	

        BasePlayer.m_mediaElem.Position = timeString;
    },
    
    GetSliderValue: function() 
    {
        try
        {
            var thumb = BasePlayer.m_baseCanvas.findName(XAMLELEMENT_THUMB);
            return thumb["Canvas.Left"] + (thumb.width/2);
        }catch(e){}
    },

    SetSliderValue: function(newValue) 
    {
        try
        {
            var slider= BasePlayer.m_baseCanvas.findName(XAMLELEMENT_SLIDER);
            var overlay = BasePlayer.m_baseCanvas.findName(XAMLELEMENT_SLIDERLINEOVER);
            var backLine = BasePlayer.m_baseCanvas.findName(XAMLELEMENT_SLIDERLINE);
            var thumb = BasePlayer.m_baseCanvas.findName(XAMLELEMENT_THUMB);
            var newPos = 0;
          
            if (newValue > slider.width)
            {
                newValue = slider.width;
            }
            if (newValue < 7) 
            {
                newValue = 7;
            }

            newPos = newValue - (thumb.width/2);
            thumb["Canvas.Left"] = newPos;
            overlay["X1"] = newPos;
            backLine["X2"] = newPos;
        }catch(e){}
    },
    
    
    
    
    _updateTime: function( )
    {/* sets the time text */
        var timeString = '';
        var seconds = 0;
        var minutes = 0;
        var totalSeconds = 0;
        var currPosition = Math.floor(BasePlayer.m_mediaElem.position.seconds);
        var duration = Math.ceil(BasePlayer.m_mediaElem.NaturalDuration.Seconds);
        var slider= null;
        var step = 0;

        // Check for minutes 
        minutes += Math.floor(currPosition / 60);
        timeString += minutes;
        if (timeString.length == 1)
	        timeString = "0" + timeString;
        
        timeString += ":";
        
        // Now work on the seconds
        seconds = Math.floor(currPosition) % 60;
        if (seconds < 10)
	        timeString += "0";

        timeString += seconds;	
        
        // Write it out to the plugin
        BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTIMETEXT).Text = timeString;   
        
        // Now update the slider too...
        try
        {
            totalSeconds = parseInt((minutes*60) + seconds);
            slider= BasePlayer.m_baseCanvas.findName(XAMLELEMENT_SLIDER);
            step = slider.width/duration;
            BasePlayer.SetSliderValue(parseInt((step*totalSeconds)+7));
        }catch(e){}
    },
    
    _setVolumeElements: function( level )
    {
        switch( level )
        {
            case 0:
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR1).Fill = '#00FFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR2).Fill = '#00FFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR3).Fill = '#00FFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR4).Fill = '#00FFFFFF'
                break;
            case 0.25:
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR1).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR2).Fill = '#00FFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR3).Fill = '#00FFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR4).Fill = '#00FFFFFF'
                break;
            case 0.5:
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR1).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR2).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR3).Fill = '#00FFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR4).Fill = '#00FFFFFF'
                break;
            case 0.75:
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR1).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR2).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR3).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR4).Fill = '#00FFFFFF'
                break;
            case 1.0:
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR1).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR2).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR3).Fill = '#FFFFFFFF'
                BasePlayer.m_baseCanvas.findName(XAMLELEMENT_VOLUMEBAR4).Fill = '#FFFFFFFF'
                break;
        }
    },
        
    _setTrackName: function( name )
    {/* Utility function to format the track name, if too long */
        if( name.length > 13 )
            BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTRACKTEXT).Text = name.substr(0, 12)+'...';
        else
            BasePlayer.m_baseCanvas.findName(XAMLELEMENT_CURRENTTRACKTEXT).Text = name;
    }
    
};

