﻿// ------------ player content panel helper class ------------ //
Ext.ux.PlayerContentPanelHelper = Ext.extend(Ext.ux.ContentPanelHelper, {

    // internal fields
    m_gridPanel: null,
    m_pagingBar: null,
    m_store: null,
    m_settings: null,
    m_flashPlayer: null,
    m_buttons: null,
    m_isPlaying: false,
    m_currentPlaylistEntryId: null,
    m_playlistEntryIdArray: [],
    m_ignoreVolumeSliderEvent: false,
    m_ignorePositionSliderEvent: false,
    m_allowSetPositionSliderPosition: true,
    m_lastPositionSliderUpdateTime: 0.00,


    // standard constructor
    constructor: function(
        contentElementId, footerElementId,
        volumeSliderElementId, positionSliderElementId,
        referralButtonLinkElementId, referralButtonImageElementId,
        infoWrapperElementId, infoNameElementId, infoArtistElementId, infoAlbumElementId,
        infoPositionElementId, infoTimeElementId,
        bufferingIndicatorImageId, bufferingImageStopped, bufferingImageRunning,
        trackReferralUrl,
        trackReferralBuySmallInactiveImageUrl, trackReferralBuySmallHoverImageUrl,
        trackReferralMoreSmallInactiveImageUrl, trackReferralMoreSmallHoverImageUrl,
        trackReferralBuyLargeInactiveImageUrl, trackReferralBuyLargeHoverImageUrl,
        trackReferralMoreLargeInactiveImageUrl, trackReferralMoreLargeHoverImageUrl) {

        this.m_volumeSliderElementId = volumeSliderElementId;
        this.m_positionSliderElementId = positionSliderElementId;
        this.m_referralButtonLinkElementId = referralButtonLinkElementId;
        this.m_referralButtonImageElementId = referralButtonImageElementId;

        this.m_infoWrapperElementId = infoWrapperElementId;
        this.m_infoNameElementId = infoNameElementId;
        this.m_infoArtistElementId = infoArtistElementId;
        this.m_infoAlbumElementId = infoAlbumElementId;
        this.m_infoPositionElementId = infoPositionElementId;
        this.m_infoTimeElementId = infoTimeElementId;

        this.m_bufferingIndicatorImageId = bufferingIndicatorImageId;
        this.m_bufferingImageStopped = bufferingImageStopped;
        this.m_bufferingImageRunning = bufferingImageRunning;

        this.m_trackReferralUrl = trackReferralUrl;
        this.m_trackReferralBuySmallInactiveImageUrl = trackReferralBuySmallInactiveImageUrl;
        this.m_trackReferralBuySmallHoverImageUrl = trackReferralBuySmallHoverImageUrl;
        this.m_trackReferralMoreSmallInactiveImageUrl = trackReferralMoreSmallInactiveImageUrl;
        this.m_trackReferralMoreSmallHoverImageUrl = trackReferralMoreSmallHoverImageUrl;

        this.m_trackReferralBuyLargeInactiveImageUrl = trackReferralBuyLargeInactiveImageUrl;
        this.m_trackReferralBuyLargeHoverImageUrl = trackReferralBuyLargeHoverImageUrl;
        this.m_trackReferralMoreLargeInactiveImageUrl = trackReferralMoreLargeInactiveImageUrl;
        this.m_trackReferralMoreLargeHoverImageUrl = trackReferralMoreLargeHoverImageUrl;

        // add custom events
        //this.addEvents('initiateplay');

        Ext.ux.PlayerContentPanelHelper.superclass.constructor.call(this, contentElementId, footerElementId, null, this.listeners);
    },

    // standard initializer
    initComponent: function() {
        Ext.ux.PlayerContentPanelHelper.superclass.initComponent.apply(this, arguments);

        // extra args have to go here as base class initComponent doesn't get called for some reason
        var config = {};

        Ext.apply(this, config);
        Ext.apply(this.initialConfig, config);
    },


    // general initialization
    initialize: function(settings, flashPlayer) {
        this.m_settings = settings;
        this.m_flashPlayer = flashPlayer;

        this.initializeFlashPlayer();
    },

    // flash player intialization
    initializeFlashPlayer: function() {
        // set initial volume
        $("#" + this.m_volumeSliderElementId + "").slider("value", g_playerInitialVolumePercent);
        this.setVolume(g_playerInitialVolumePercent);

        this.addListeners();
    },

    // add event listeners
    addListeners: function() {
        if (this.m_flashPlayer) {
            this.m_flashPlayer.addModelListener("STATE", "playerContentPanelHelper.stateListener");
            this.m_flashPlayer.addModelListener('TIME', "playerContentPanelHelper.timeListener");
            this.m_flashPlayer.addModelListener('ERROR', "playerContentPanelHelper.errorListener");
        }
        else {
            this.setTimeout("playerContentPanelHelper.addListeners", 100);
        }
    },

    // listner for following events: IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED
    stateListener: function(obj) {
        if (obj.newstate == "BUFFERING") {
            this.onBufferingStarted();
        }
        else if (obj.newstate == "COMPLETED") {
            this.playNextTrack();
        }

        // separate case - called whenever we're not buffering for good measure
        if ((obj.oldstate == "BUFFERING") && (obj.newstate != "BUFFERING")) {
            this.onBufferingComplete();
        }
    },

    // pad a sting with zeros to make it length 2
    pad: function(num) {
        num = num + "";
        if (num.length == 1) {
            num = "0" + num;
        }
        return num;
    },

    // listener for changes in position
    timeListener: function(obj) {
        var totalSeconds;
        var positionSecondsString;
        var durationSeconds;
        var positionPercent;
        var positionString;
        var minutes;
        var seconds;

        totalSeconds = Math.floor(obj.position);
        minutes = Math.floor(totalSeconds / 60);    // minutes
        seconds = totalSeconds % 60;                // balance of seconds
        positionString = this.pad(minutes) + ":" + this.pad(seconds);
        $("#" + this.m_infoPositionElementId + "").html(positionString);

        // convert from time to %
        playlist = this.m_flashPlayer.getPlaylist();
        if (typeof (playlist[0]) != "undefined") {
            if (playlist[0].duration > 0) {

                // don't update the position of the slider more than every 3 seconds to reduce interference between auto and manual position setting
                if ((obj.position < this.m_lastPositionSliderUpdateTime) || (obj.position > (this.m_lastPositionSliderUpdateTime + 2))) {
                    this.m_lastPositionSliderUpdateTime = obj.position;

                    positionPercent = (obj.position * 100) / playlist[0].duration;

                    // only change position if the user isn't currently changing it themselves
                    if (this.m_allowSetPositionSliderPosition) {
                        // flag to ignore events sent back by the slider when position changed
                        this.m_ignorePositionSliderEvent = true;
                        $("#" + this.m_positionSliderElementId + "").slider("value", positionPercent);
                        this.m_ignorePositionSliderEvent = false;
                    }
                }
            }
        }
    },

    // listener for errors
    errorListener: function(message) {
        this.m_isPlaying = false;
        this.setPlayButtonImage();
    },

    // button initialization
    initializeButtons: function(buttons) {
        this.m_buttons = buttons;
        for (var i = 0; i < this.m_buttons.length; i++) {
            $("#" + this.m_buttons[i].linkId + "").bind("click", this.m_buttons[i], window[this.m_buttons[i].handler]);
            $.preloadImages(this.m_buttons[i].activeImagePath, this.m_buttons[i].inactiveImagePath);

            // bind hover images
            $.bindHoverImages(
                this.m_buttons[i].imageId,
                this.m_buttons[i].hoverImagePath,
                this.m_buttons[i].inactiveImagePath,
                null, null, null, null, null, null, null);
        }

        // bind the slider & position value changers
        $('#volume_slider_control').slider('option', 'step', 5);
        $("#volume_slider_control").bind("slide", player_handleVolumeChanged);
        $("#position_slider_control").bind("slidechange", player_handlePositionChanged);
    },

    // set the play button image
    setPlayButtonImage: function() {

        var playButton = this.m_buttons[1];
        var pauseButton = this.m_buttons[2];
        var hoverImagePath;
        var inactiveImagePath;

        if (this.m_isPlaying) {
            // pause images
            hoverImagePath = pauseButton.hoverImagePath;
            inactiveImagePath = pauseButton.inactiveImagePath;
        }
        else {
            // play images
            hoverImagePath = playButton.hoverImagePath;
            inactiveImagePath = playButton.inactiveImagePath;
        }

        // set current image
        $("#" + playButton.imageId + "").attr("src", inactiveImagePath);

        // bind new images
        $.bindHoverImages(
            playButton.imageId,
            hoverImagePath,
            inactiveImagePath,
            null, null, null, null, null, null, null);
    },

    // load data into the tracks grid
    loadData: function() {
        this.loadGridData(g_playerTracksAsyncUrl);
        this.configurePlayerDragDrop(this.m_gridPanel);
        this.m_gridPanel.configureDragDrop(g_dragDropGroup_playerInternal);
        this.showFooter(true);
    },

    // load data into the grid
    loadGridData: function(url) {
        this.m_store = extJsStore_createStore(
            this.m_store,
            url,
            g_playerGrid_defaultSortField,
            g_extjsGrid_defaultSortDirection);

        this.m_pagingBar = extJsPagingBar_createPagingBar(
            this.m_pagingBar,
            "player_paging_single",
            "player_cp_paging_single",
            this.m_store,
            g_resourceStrings['Js_TracksGrid_DetailPagingBar_Track']);

        // create new gridPanel if necessary
        if (this.m_gridPanel === null) {
            this.m_gridPanel = new Ext.ux.PlayerGridPanel({
                store: this.m_store,
                autoHeight: true,
                enableDragDrop: true,
                renderTemp: "player_cp_grid_temp",
                renderTarget: "player_cp_grid",
                dragDropHighlightType: g_dragDropHighlightType_betweenRows,
                trackReferralUrl: this.m_trackReferralUrl,
                trackReferralBuySmallInactiveImageUrl: this.m_trackReferralBuySmallInactiveImageUrl,
                trackReferralBuySmallHoverImageUrl: this.m_trackReferralBuySmallHoverImageUrl,
                trackReferralMoreSmallInactiveImageUrl: this.m_trackReferralMoreSmallInactiveImageUrl,
                trackReferralMoreSmallHoverImageUrl: this.m_trackReferralMoreSmallHoverImageUrl
            });

            // hook up listeners
            this.m_store.on('load', this.onLoad, this);
            this.m_gridPanel.on('rowdblclick', this.onGridRowDblClick, this);

            // hook up callback
            this.m_gridPanel.setPlayClickCallback(delegate(this, this.onGridPlayClick));

            player_extJsStore_hookUpStoreEventHandlers(this.m_store); // custom hookup redirecting to custom error handlers
            extJsGrid_hookUpStoreEventHandlers(this.m_gridPanel, this.m_store);
        }

        extJsStore_loadData(this.m_store);
    },

    // configure grid drag/drop
    configurePlayerDragDrop: function(grid) {
        var ddAddGroups;

        if (grid === null)
            return;

        var gridView = grid.getView();
        if (gridView === null)
            return;

        var gridDragZone = gridView.dragZone;
        if (gridDragZone === null)
            return;

        // cann't drop onto grid
        gridDragZone.isTarget = false;

        // can only ever drop on player
        ddAddGroups = new Array(
            g_dragDropGroup_playerInternal);

        grid.setDdAddGroups(ddAddGroups);
    },

    // refresh the grid
    refresh: function() {
        if (this.m_gridPanel !== null) {
            this.m_gridPanel.getView().refresh(true);
        }
    },

    // reload the grid
    reload: function() {
        if (this.m_gridPanel !== null) {
            this.m_gridPanel.reload();
        }
    },

    // reload the grid
    reloadAndPlayTrack: function(playlistEntryId) {
        // hook up a load listener for the next firing of the event only
        // call a delegate because we need to prepopulate the argument
        this.m_store.on('load',
            delegateWithArguments(this, this.onReloadAndPlayTrack, playlistEntryId),
            this,
            { single: true });

        if (this.m_gridPanel !== null) {
            this.m_gridPanel.reload();
        }
    },

    // called when store has loaded
    onReloadAndPlayTrack: function(playlistEntryId) {
        // find the index of the specified record, set it as the current row index & initial playing of the track
        var rowIndex = this.m_store.findExact("id", playlistEntryId);

        this.m_gridPanel.setCurrentRowIndex(rowIndex);
        this.initiatePlay();
    },

    // called when store has loaded
    onLoad: function() {
        if (this.m_store.getCount() === 0) {
            // no playlist entry ids to store

            this.m_gridPanel.setCurrentRowIndex(g_default_xPOPropertyId);
            this.initiateReset();
            return;
        }

        var rowIndex = this.m_gridPanel.getCurrentRowIndex();
        if (rowIndex == g_default_xPOPropertyId) {
            // store the array of playlist entry ids
            this.m_playlistEntryIdArray = [];
            this.m_store.each(this.appendRecordIdToPlaylistEntryIdArray, this);

            // not currently playing anything (i.e. just opened) so play the first track if there is one
            this.m_gridPanel.setCurrentRowIndex(0);
            this.initiatePlay();
            return;
        }

        var currentEntryRowIndex = this.getCurrentEntryRowIndexInNewStore();
        if (currentEntryRowIndex != g_default_xPOPropertyId) {
            // store the array of playlist entry ids
            this.m_playlistEntryIdArray = [];
            this.m_store.each(this.appendRecordIdToPlaylistEntryIdArray, this);

            // currently playing entry is still in the playlist so highlight it
            this.m_gridPanel.setCurrentRowIndex(currentEntryRowIndex);
            this.m_gridPanel.autoHighlightCurrentRow();
            return;
        }

        // currently playing entry doesn't exist so look for the next one
        var nextEntryRowIndex = this.getNextEntryRowIndexInNewStore();
        if (nextEntryRowIndex != g_default_xPOPropertyId) {
            // store the array of playlist entry ids
            this.m_playlistEntryIdArray = [];
            this.m_store.each(this.appendRecordIdToPlaylistEntryIdArray, this);

            // a subsequent entry still exists so play it
            this.m_gridPanel.setCurrentRowIndex(nextEntryRowIndex);
            this.initiatePlay();
            return;
        }

        // no subsequent entries, so look for a previous one
        var previousEntryRowIndex = this.getPreviousEntryRowIndexInNewStore();
        if (previousEntryRowIndex != g_default_xPOPropertyId) {
            // store the array of playlist entry ids
            this.m_playlistEntryIdArray = [];
            this.m_store.each(this.appendRecordIdToPlaylistEntryIdArray, this);

            // a previous entry exists so play it
            this.m_gridPanel.setCurrentRowIndex(previousEntryRowIndex);
            this.initiatePlay();
            return;
        }

        // no entries still exist, so look for the first one
        if (this.m_store.getCount() > 0) {
            // store the array of playlist entry ids
            this.m_playlistEntryIdArray = [];
            this.m_store.each(this.appendRecordIdToPlaylistEntryIdArray, this);

            // first one exists so play it
            this.m_gridPanel.setCurrentRowIndex(0);
            this.initiatePlay();
            return;
        }
    },

    // append the id to the m_playlistEntryIdArray
    appendRecordIdToPlaylistEntryIdArray: function(record) {
        this.m_playlistEntryIdArray.push(record.data.id);
    },

    // retrieve the rowIndex of the current entry if it exists in the new store
    getCurrentEntryRowIndexInNewStore: function() {
        return this.m_store.findExact("id", this.m_currentPlaylistEntryId);
    },

    // retrieve the rowIndex of the next entry which exists in the new store (if any)
    getNextEntryRowIndexInNewStore: function() {
        var oldCurrentEntryRowIndex = this.m_playlistEntryIdArray.indexOf(this.m_currentPlaylistEntryId);
        var nextEntryRowIndex = g_default_xPOPropertyId;

        if (oldCurrentEntryRowIndex != g_default_xPOPropertyId) {
            // loop through previous entries, attempting to find one in the current store
            for (var i = oldCurrentEntryRowIndex + 1; i < this.m_playlistEntryIdArray.length; i++) {
                nextEntryRowIndex = this.m_store.findExact("id", this.m_playlistEntryIdArray[i]);

                if (nextEntryRowIndex != g_default_xPOPropertyId) {
                    break;
                }
            }
        }

        return nextEntryRowIndex;
    },

    // retrieve the rowIndex of a previous entry which exists in the new store (if any)
    getPreviousEntryRowIndexInNewStore: function() {
        var oldCurrentEntryRowIndex = this.m_playlistEntryIdArray.indexOf(this.m_currentPlaylistEntryId);
        var previousEntryRowIndex = null;

        if (oldCurrentEntryRowIndex != g_default_xPOPropertyId) {
            // loop through subsequent entries, attempting to find one in the current store
            for (var i = oldCurrentEntryRowIndex - 1; i >= 0; i--) {
                previousEntryRowIndex = this.m_store.findExact("id", this.m_playlistEntryIdArray[i]);

                if (previousEntryRowIndex != g_default_xPOPropertyId) {
                    break;
                }
            }
        }

        return previousEntryRowIndex;
    },

    // retrieve the id of the current playlist entry
    getCurrentPlaylistEntryId: function() {
        return this.m_currentPlaylistEntryId;
    },

    // row double-click event handler
    onGridRowDblClick: function(grid, rowIndex, e) {
        this.m_gridPanel.setCurrentRowIndex(rowIndex);
        this.initiatePlay();
    },

    // play context menu callback
    onGridPlayClick: function(rowIndex) {
        this.m_gridPanel.setCurrentRowIndex(rowIndex);
        this.initiatePlay();
    },

    // initiate the reset sequence
    initiateReset: function() {
        this.m_currentPlaylistEntryId = g_default_xPOPropertyId;

        this.m_isPlaying = false;
        this.setPlayButtonImage();

        this.populateInfoSubpanel("", "", "", "00:00");
        this.configureReferralButton(g_streamingAccessType_full, g_default_xPOPropertyId); // hide 'buy button'

        this.resetPlayer();
    },

    // initiate the play sequence
    initiatePlay: function() {
        var playlistEntry = this.m_gridPanel.getCurrentRecord();
        if (playlistEntry) {
            this.m_currentPlaylistEntryId = playlistEntry.data.id;
            this.m_gridPanel.autoHighlightCurrentRow();

            this.m_isPlaying = true;
            this.setPlayButtonImage();

            this.populateInfoSubpanel(playlistEntry.data.name, playlistEntry.data.artist, playlistEntry.data.album, playlistEntry.data.time);
            this.configureReferralButton(playlistEntry.data.useraccesslevel, playlistEntry.data.trackid);
            //this.onInitiatePlay(playlistEntry.data.name, playlistEntry.data.artist, playlistEntry.data.album, playlistEntry.data.referralurl);
            this.getStreamTrackData(playlistEntry);
        }
        else {
            this.m_isPlaying = false;
            this.setPlayButtonImage();
        }
    },

    // play previous track
    playPreviousTrack: function() {
        var playlistEntry = this.m_gridPanel.getPreviousRecord();
        if (playlistEntry) {
            this.m_currentPlaylistEntryId = playlistEntry.data.id;
            this.m_gridPanel.autoHighlightCurrentRow();

            this.m_isPlaying = true;
            this.setPlayButtonImage();

            this.populateInfoSubpanel(playlistEntry.data.name, playlistEntry.data.artist, playlistEntry.data.album, playlistEntry.data.time);
            this.configureReferralButton(playlistEntry.data.useraccesslevel, playlistEntry.data.trackid);
            //this.onInitiatePlay(playlistEntry.data.name, playlistEntry.data.artist, playlistEntry.data.album, playlistEntry.data.referralurl);
            this.getStreamTrackData(playlistEntry);
        }
        else {
            this.m_isPlaying = false;
            this.setPlayButtonImage();
        }
    },

    // play next track
    playNextTrack: function() {
        var playlistEntry = this.m_gridPanel.getNextRecord();
        if (playlistEntry) {
            this.m_currentPlaylistEntryId = playlistEntry.data.id;
            this.m_gridPanel.autoHighlightCurrentRow();

            this.m_isPlaying = true;
            this.setPlayButtonImage();

            this.populateInfoSubpanel(playlistEntry.data.name, playlistEntry.data.artist, playlistEntry.data.album, playlistEntry.data.time);
            this.configureReferralButton(playlistEntry.data.useraccesslevel, playlistEntry.data.trackid);
            //this.onInitiatePlay(playlistEntry.data.name, playlistEntry.data.artist, playlistEntry.data.album, playlistEntry.data.referralurl);
            this.getStreamTrackData(playlistEntry);
        }
        else {
            this.m_isPlaying = false;
            this.setPlayButtonImage();
        }
    },

    // retrieve stream info for specified record
    getStreamTrackData: function(record) {

        // call the callback with the trackid
        if (record) {
            // post ajax request to server
            $.ajax({
                url: g_streamTrackDataAsyncUrl, // note: global url
                type: g_method_get,
                dataType: g_dataType_json,
                data: "trackId=" + record.data.trackid,
                contentType: g_contentType_form,
                success: delegate(this, this.onGetStreamTrackData),
                error: player_jQuery_ajaxRequestFailed
            });
        }
    },

    // called when stream url has been retrieved
    onGetStreamTrackData: function(response, textStatus) {
        if (response !== null) {
            if ((response.url !== "") && (response.streamlength !== null)) {
                // we have a valid stream
                this.loadTrack(response.url, response.streamlength);

                if (this.m_isPlaying) {
                    this.playTrack();
                }
            }
            else {
                // stream not valid - pause
                this.m_isPlaying = false;
                this.setPlayButtonImage();
            }
        }
    },

    // load a track from the specified url
    loadTrack: function(url, streamlength) {

        // supply the duration if we know it
        if (streamlength !== 0) {
            this.m_flashPlayer.sendEvent("LOAD", { "file": url, "type": "sound", duration: streamlength });
        }
        else {
            this.m_flashPlayer.sendEvent("LOAD", { "file": url, "type": "sound" });
        }
    },

    // play the currently loaded track
    playTrack: function() {
        this.m_flashPlayer.sendEvent("PLAY");
    },

    // toggle play / pause if the current stream is valid
    playToggle: function() {
        this.m_isPlaying = !this.m_isPlaying;
        this.setPlayButtonImage();
        this.m_flashPlayer.sendEvent("PLAY"); // toggle (broken in v5)
    },

    // reset
    resetPlayer: function() {
        this.m_flashPlayer.sendEvent("STOP");
        this.m_flashPlayer.sendEvent("LOAD", { "file": "", "type": "sound" });
    },

    // set min volume
    setMinVolume: function() {
        this.m_ignoreVolumeSliderEvent = true;
        $("#" + this.m_volumeSliderElementId + "").slider("value", 0);
        this.m_flashPlayer.sendEvent("VOLUME", 0); // MUTE broken in v5
        this.m_ignoreVolumeSliderEvent = false;
    },

    // set max volume
    setMaxVolume: function() {
        this.m_ignoreVolumeSliderEvent = true;
        $("#" + this.m_volumeSliderElementId + "").slider("value", 100);
        this.m_flashPlayer.sendEvent("VOLUME", 100);
        this.m_ignoreVolumeSliderEvent = false;
    },

    // set volume (0..100)
    setVolume: function(volume) {
        if (!this.m_ignoreVolumeSliderEvent) {
            volume = Math.max(volume, 0);
            volume = Math.min(volume, 100);
            this.m_flashPlayer.sendEvent("VOLUME", volume);
        }
    },

    // skip to position (0..100)
    setPosition: function(position) {
        var durationSeconds;
        var playlist;
        var positionTime;

        if (!this.m_ignorePositionSliderEvent) {
            // prevent the position of the slider being set automatically and interfering with the user changing
            this.m_allowSetPositionSliderPosition = false;

            position = Math.max(position, 0);
            position = Math.min(position, 100);
            position = position / 100;

            // convert from % to time
            playlist = this.m_flashPlayer.getPlaylist();
            if (typeof (playlist[0]) != "undefined") {
                durationSeconds = playlist[0].duration;
                positionTime = position * durationSeconds;
                this.m_isPlaying = true;
                this.m_flashPlayer.sendEvent("SEEK", positionTime);
            }
            this.m_allowSetPositionSliderPosition = true;
        }
    },

    // indicate buffering a track has started
    onBufferingStarted: function() {
        $("#" + this.m_bufferingIndicatorImageId + "").attr("src", this.m_bufferingImageRunning);
    },

    // indicate buffering a track has completed
    onBufferingComplete: function() {
        $("#" + this.m_bufferingIndicatorImageId + "").attr("src", this.m_bufferingImageStopped);
    },

    // populate info subpanel
    populateInfoSubpanel: function(name, artist, album, time) {
        $("#" + this.m_infoNameElementId + "").html(name);
        $("#" + this.m_infoArtistElementId + "").html(artist);
        $("#" + this.m_infoAlbumElementId + "").html(album);

        if (!time) {
            time = "--:--";
        }
        $("#" + this.m_infoTimeElementId + "").html(time);

        CSBfleXcroll(this.m_infoWrapperElementId);
    },

    // show / configure or hide the 'buy mp3' / more button
    configureReferralButton: function(useraccesslevel, trackid) {
        var referralButtonLinkHref;

        if (trackid === g_default_xPOPropertyId) {
            // no track; reset and hide
            $("#" + this.m_referralButtonLinkElementId + "").attr("href", "");
            $("#" + this.m_referralButtonImageElementId + "").hide();
        }
        else {
            // valid track; set url and show
            if ((useraccesslevel === g_streamingAccessType_sample) || (useraccesslevel === g_streamingAccessType_none)) {
                referralButtonLinkHref = this.m_trackReferralUrl + "?id=0&trackId=" + trackid + "&type=" + g_referralUrlParameterValue_buy;
                $("#" + this.m_referralButtonLinkElementId + "").attr("href", referralButtonLinkHref);
                
                // swap image
                $("#" + this.m_referralButtonImageElementId + "").attr("src", this.m_trackReferralBuyLargeInactiveImageUrl);
                $("#" + this.m_referralButtonImageElementId + "").attr("alt", "buy this mp3");
                $("#" + this.m_referralButtonImageElementId + "").show();
            }
            else {
                referralButtonLinkHref = this.m_trackReferralUrl + "?id=0&trackId=" + trackid + "&type=" + g_referralUrlParameterValue_more;
                $("#" + this.m_referralButtonLinkElementId + "").attr("href", referralButtonLinkHref);

                // swap image
                $("#" + this.m_referralButtonImageElementId + "").attr("src", this.m_trackReferralMoreLargeInactiveImageUrl);
                $("#" + this.m_referralButtonImageElementId + "").attr("alt", "buy more from this artist");
                $("#" + this.m_referralButtonImageElementId + "").show();
            }
        }
    }

    /*
    // fire initiateplay event
    onInitiatePlay: function(name, artist, album, referralurl) {
    this.fireEvent(g_customEvent_player_initiatePlay, name, artist, album, referralurl);
    }
    */
});