lala = {
    _loaded: false,
    onload: function() {
        // Prevent double loads
        // This can happen if onload called manually
        // which sites may need to fix wierd IE6 timing/onload event issues
        if (lala._loaded) return;
        lala._loaded = true;
        // We have this indirection in order to setup the "this" context
        lala.PlaylistWidget.onLoad();

        // Load the lala media library in case both are included
        if (lala.MediaPlayer) {
            lala.MediaPlayer.onLoad();
        }
    },

    PlaylistWidget: {
        idGenerator: 1,
        
        onLoad: function() {
            // First look for the embed targets
            var idsToFind = ['embedLalaPlaylistWidget',
                             'embedLalaForecastWidget',
                             'embedLalaSongWidget'];
            var idDivs = [];

            for (var j = 0; j < idsToFind.length; j++) {
                if (document.getElementById(idsToFind[j])) {
                    idDivs.push(document.getElementById(idsToFind[j]));
                }
            }

            if (idDivs.length > 0) {
                // Website is embedding the widget.  We find the instance
                // by looking for the div with our custom ID.
                for (var k = 0; k < idDivs.length; k++) {
                    var div = idDivs[k];
                    this._renderEmbeddedWidget(div, div.id);
                }
            } else {
                // Website is embedding multiple instances.  We find the instances
                // by looking for divs with our custom classname (used internally)
                var divs = document.getElementsByTagName("DIV");
                for (var i = 0; i < divs.length; i++) {
                    div = divs[i];
                    if (div.className.match(/embedLalaPlaylistWidget|embedLalaForecastWidget|embedLalaSongWidget/)) {
                        this._renderEmbeddedWidget(div, div.className);
                    }
                }
            }

            // Now look for an link targets
            var self = lala.PlaylistWidget;
            var anchors = document.getElementsByTagName("A");
            for (var i = 0; i < anchors.length; i++) {
                var a = anchors[i];
                if (a.className.match(/linkLalaPlaylistWidget|linkLalaForecastWidget|linkLalaSongWidget/)) {
                    a.href = 'javascript:void 0';
                    a.onclick = self._makeTriggerClosure(a);
                }
            }
        },

        _makeTriggerClosure: function(a) {
            var self = this;
            return function() {
                var flashVars = self._getFlashVars(a); // anchor
                flashVars.autoPlayIndex = 0;
                self._openPlayerInWindow(flashVars, a.className);
                return false;
            }
        },

        _renderEmbeddedWidget: function(div, idOrClass) {
            if (!div) return; // no-op if div isn't in the DOM

            // The Flashembed library replaces the div id with the object tag.
            // Lets create our own div with a random id and hand it to embed code
            var embedDiv = document.createElement('DIV');
            embedDiv.id = 'lalaWidgetFlashDiv_' + this.idGenerator++;
            div.appendChild(embedDiv);

            var flashVars = this._getFlashVars(div);
            var swf = this._getSwf(idOrClass);
            var size = this._getSize(flashVars, swf, div);
            this._loadViaFlashEmbed(embedDiv.id, flashVars, swf,
                                    size.width, size.height);
        },

        _getSwf: function(idOrClass) {
            var swf;
            if (!idOrClass) {
                swf = 'PlaylistWidget';
            } else if (idOrClass.match(/PlaylistWidget/))  {
                swf = 'PlaylistWidget';
            } else if (idOrClass.match(/ForecastWidget/))  {
                swf = 'LalaForecastWidget';
            } else if (idOrClass.match(/SongWidget/))  {
                swf = 'SingleSongWidget';
            } else {
                throw 'unspported widget type: ' + idOrClass;
            }

            return swf;
        },

        _getSize: function(flashVars, swf, div, isTearout) {
            var size = {
                width: flashVars.widgetWidth,
                height: flashVars.widgetHeight
            };

            // Tearouts have hard coded sizes for all widgets
            if (!size.width || !size.height || isTearout) {
                if (swf == 'PlaylistWidget') {
                    var isNarrow =
                            div &&
                              div.getAttribute('widgetNarrowLayout') == 'true';
                    size.width  = isNarrow ? '170px' : '300px';
                    size.height = isNarrow ? '320px' : '254px';
                    if (isTearout) {
                        size.width  = '300px';
                        size.height = '350px';
                        size.windowWidth  = 320;
                        size.windowHeight = 370;
                    }
                } else if (swf == 'LalaForecastWidget') {
                    size.width  = '150px';
                    size.height = '345px';
                    if (isTearout) {
                        size.windowWidth  = 170;
                        size.windowHeight = 355;
                    }
                } else if (swf == 'SingleSongWidget') {
                    size.width  = '220px';
                    size.height = '70px';
                    if (isTearout) {
                        size.width  = '220px';
                        size.height = '70px';
                        size.windowWidth  = 240;
                        size.windowHeight = 85;
                    }
                }
            }

            // Kill them now that we pulled them out since we embed code doesnt
            // use them as flash vars -- to do: clean this up
            delete flashVars.widgetWidth;
            delete flashVars.widgetHeight;

            return size;
        },

        _getFlashVars: function(elem) {
            var host = elem.getAttribute('widgetHost');

            var showAlbumNames  = elem.getAttribute('widgetShowAlbumNames') == 'true';
            var autoPlay = elem.getAttribute('widgetAutoPlay') == 'true';
            var partnerId = elem.getAttribute('widgetPartnerId');
            if (!partnerId) {
                throw "widgetPartnerId is a required config attribute";
            }

            var playlistId      = elem.getAttribute('widgetPlaylistId');
            var xspfUrl         = elem.getAttribute('widgetXspfUrl');
            var feedUrl         = elem.getAttribute('widgetFeedUrl');
            var albumId         = elem.getAttribute('widgetAlbumId');
            var labelName       = elem.getAttribute('widgetLabelName');
            var artistId        = elem.getAttribute('widgetArtistId');
            var artistName      = elem.getAttribute('widgetArtistName');
            var albumName       = elem.getAttribute('widgetAlbumName');
            var songName        = elem.getAttribute('widgetSongName');
            var userId          = elem.getAttribute('widgetUserId');
            var songId          = elem.getAttribute('widgetSongId');
            var mp3Url          = elem.getAttribute('widgetMp3Url');
            var streamUrl       = elem.getAttribute('widgetStreamUrl');
            var mp3Duration     = elem.getAttribute('widgetDuration');
            var useSignupDialog = elem.getAttribute('widgetUseSignupDialog');
            var width           = elem.getAttribute('widgetWidth');
            var height          = elem.getAttribute('widgetHeight');
            var songsPerArtist  = elem.getAttribute('widgetSongsPerArtist');

            var useCustomColors = elem.getAttribute('widgetUseCustomColors');
            var noBorder        = elem.getAttribute('widgetNoBorder');
            var bgColor         = elem.getAttribute('widgetBackgroundColor');
            var fgColor         = elem.getAttribute('widgetFontColor');
            var fgSecondColor   = elem.getAttribute('widgetFontSecondaryColor');
            var trackColor      = elem.getAttribute('widgetProgressTrackColor');
            var loadColor       = elem.getAttribute('widgetProgressLoadColor');
            var barColor        = elem.getAttribute('widgetProgressBarColor');

            var userImageUrlFs  = elem.getAttribute('widgetUserImageUrlFs');
            var userImageUrlDb  = elem.getAttribute('widgetUserImageUrlDb');

            var flashVars = {
                host: host,
                partnerId: partnerId,
                useSignupDialog: useSignupDialog,
                songsPerArtist: songsPerArtist,
                showAlbumNames: showAlbumNames,
                jsEnabled: true // always enable JS when embedding from this page
            };

            if (autoPlay) {
                flashVars.autoPlayIndex = 0;
            }

            if (useCustomColors) {
                flashVars.useCustomColors = useCustomColors;
                flashVars.noBorder = noBorder;
                flashVars.backgroundColor = bgColor;
                flashVars.fontColor = fgColor;
                flashVars.fontSecondaryColor = fgSecondColor;
                flashVars.progressTrackColor = trackColor;
                flashVars.progressLoadColor = loadColor;
                flashVars.progressBarColor = barColor;
            }

            if (playlistId) {
                // Playlist widget
                flashVars.playlistId = playlistId;
            } else if (xspfUrl) {
                // CMJ Rss Feed
                flashVars.xspfUrl = xspfUrl;
            } else if (feedUrl) {
                // CMJ Rss Feed
                flashVars.feedUrl = feedUrl;
            } else if (albumId) {
                // Album widget
                flashVars.albumId = albumId;
            } else if (labelName) {
                // Album widget
                flashVars.labelName = labelName;
            } else if (artistId && artistName) {
                flashVars.artistId = artistId;
                flashVars.artistName = artistName;
            } else if (artistId) {
                flashVars.artistId = artistId;
            } else if (artistName && albumName) {
                // Album widget by doing a search
                flashVars.albumName  = albumName;
                flashVars.artistName = artistName;
            } else if (artistName && songName) {
                // Song widget by doing a search
                flashVars.artistName = artistName;
                flashVars.songName   = songName;
                if (mp3Url) {
                    flashVars.mp3Url = mp3Url;
                    flashVars.duration = mp3Duration;
                } else if (streamUrl) {
                    flashVars.streamUrl = streamUrl;
                }
            } else if (artistName) { // Artist top songs widget
                flashVars.artistName = artistName;
            } else if (userId) { // Forecast widget
                flashVars.userToken = userId;
            } else if (songId) { // Song widget
                flashVars.songLalaId = songId;
            } else {
                throw "Lala playlist widget mis-configured, view documentation";
            }

            if (width)  flashVars.widgetWidth   = width;
            if (height) flashVars.widgetHeight  = height;

            if (userImageUrlFs) flashVars.userImageUrlFs = userImageUrlFs;
            if (userImageUrlDb) flashVars.userImageUrlDb = userImageUrlDb;

            return flashVars;
        },

        _loadViaFlashEmbed: function(divId, flashVars, swf, width, height) {
            var host = flashVars.host || 'www.lala.com';
            var versionPath =
                    host.indexOf('dhcp') != -1 || host.indexOf('localhost') != -1
                            ? 'static' : 'external';
            var swfUrl = 'http://' + host + '/' + versionPath + '/flash/' + swf + '.swf';

            var params = {
                wmode: 'transparent',
                allowScriptAccess: 'always',
                allowNetworking: 'all'
            };
            var attributes = {};

            flashVars.containerId = divId;

            this._embedSWF(
                    divId, // replaces this elem
                    swfUrl,
                    width, height,
                    flashVars,
                    params);
        },

        _embedSWF: function(divId, swfUrl, width, height, flashVars, params) {
            var container = document.getElementById(divId);
            if (container) {
                var swfId = divId + "_swf";
                var swfTemplate = '<object type="application/x-shockwave-flash" data="@swfUrl@" id="@swfId@" width="@width@" height="@height@"><param name="movie" value="@swfUrl@"/><param name="wmode" value="transparent"/><param name="allowNetworking" value="all"/><param name="allowScriptAccess" value="always"/><param name="flashvars" value="@flashvars@"/><embed id="@swfId@" name="@swfId@" src="@swfUrl@" width="@width@" height="@height@" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" wmode="transparent" allowNetworking="all" allowScriptAccess="always" flashvars="@flashvars@"></embed></object>';

                var flashVarsStr = lala.buildQueryString(flashVars);
                var swfCode = swfTemplate.replace(/@swfUrl@/g, swfUrl)
                                         .replace(/@swfId@/g, swfId)
                                         .replace(/@width@/g, width)
                                         .replace(/@height@/g, height)
                                         .replace(/@flashvars@/g, flashVarsStr);
                container.innerHTML = swfCode;
            }
        },

        onTearOut: function(flashVars) {
            this._openPlayerInWindow(flashVars);
        },

        onErrorNotify: function(divId) {
            var container = document.getElementById(divId);
            // get lala parent container
            var parent;
            while (parent = container.parentNode) {
                if (parent == null) break;

                if ((parent.className && parent.className.match('embedLala'))
                        || (parent.id && parent.id.match('embedLala'))) {
                    parent.style.display = 'none';
                    break;
                } else {
                    container = parent;
                }
            }
        },

        _openPlayerInWindow: function(flashVars, idOrClass) {
            flashVars.hideNewWindow = true; // dont show tear out link

            var swf = this._getSwf(idOrClass);
            var size = this._getSize(flashVars, swf, null, true);
            var win = window.open(
                    "",
                    "lalaTearOutWindow",
                    "resizable=0,toolbar=0,status=0,menubar=0,fullscreen=0,width="
                    + size.windowWidth + ",height=" + size.windowHeight);
            win.document.open("text/html", "replace");

            var html = this._getPlayerInWindowEmbed(flashVars, swf, size);
            win.document.write(html);
            win.document.close();
            win.focus();
        },

        _getPlayerInWindowEmbed: function(flashVars, swf, size) {
            var host = flashVars.host || 'www.lala.com';
            var versionPath =
                    host.indexOf('dhcp') != -1 || host.indexOf('localhost') != -1
                            ? 'static' : 'external';
            var swfUrl = 'http://' + host + '/' + versionPath + '/flash/' + swf + '.swf';

            var flashVarsStr = lala.buildQueryString(flashVars);
            return '<object width="' + size.width + '" height="' + size.height + '" \
                         align="middle" \
                         data="' + swfUrl + '" \
                         type="application/x-shockwave-flash">\
                     <param name="movie"             value="' + swfUrl + '"/>\
                     <param name="flashVars"         value="' + flashVarsStr + '"/>\
                     <param name="bgcolor"           value="ffffff"/>\
                     <param name="play"              value="true"/>\
                     <param name="loop"              value="false"/>\
                     <param name="quality"           value="high"/>\
                     <param name="scale"             value="noscale"/>\
                     <param name="salign"            value="TL"/>\
                     <param name="wmode"             value="transparent"/>\
                     <param name="allowScriptAccess" value="always"/>\
                     <param name="allowNetworking"   value="all"/>\
                 </object>';
        }
    },

    SignupDialog: {
        DIALOG_WIDTH: 680,
        DIALOG_HEIGHT: 490,
        
        init: function(params) {
            params = params || {};
            this._callbackUrl = params.callbackUrl;
            this._partnerId = params.partnerId || "unknown";
            this._sslBaseUrl = params.sslBaseUrl || "https://www.lala.com";
            this._logoUrl = params.logoUrl;
            this._partnerName = params.partnerName;
            this._partnerSite = params.partnerSite;

            var userAgent = navigator.userAgent.toLowerCase();
            this.IE6 = userAgent.indexOf('msie 6.') != -1;
            
            this._shield = document.createElement('div');
            this._shield.id = "lalaSignupDialogShield";

            this._shield.style.backgroundColor = "#000000";
            this._shield.style.opacity = .5;
            this._shield.style.filter = 'alpha(opacity=50)';
            this._shield.style.zIndex = 999;
            this._shield.style.display = "none";

            document.body.appendChild(this._shield);

            this._dialog = document.createElement('iframe');
            this._dialog.frameBorder = 0;
            this._dialog.allowTransparency = true;
            this._dialog.style.width = this.DIALOG_WIDTH + "px";
            this._dialog.style.height = this.DIALOG_HEIGHT + "px";
            this._dialog.style.position = "absolute";
            this._dialog.style.zIndex = 1000;
            this._dialog.style.display = "none";

            document.body.appendChild(this._dialog);

            if (this.IE6) {
                this._shield.style.position = "absolute";
                this._dialog.style.position = "absolute";
            } else {
                this._shield.style.position = "fixed";
                this._dialog.style.position = "fixed";
            }
        },

        show: function(mode, freeWebSong) {
            this.showModalShield();

            if (!mode) {
                mode = "signup";
            }

            var width, height;
            if (window.innerWidth) {
                width = window.innerWidth;
                height = window.innerHeight;
            } else if (document.documentElement.clientWidth &&
                    document.documentElement.clientWidth > 0) {
                width = document.documentElement.clientWidth;
                height = document.documentElement.clientHeight;
            } else {
                width = document.body.clientWidth;
                height = document.body.clientHeight;
            }

            this._dialog.style.left = (width - this.DIALOG_WIDTH) / 2 + "px";
            this._dialog.style.top = (this.IE6 ? document.documentElement.scrollTop : 0) +
                                     ((height - this.DIALOG_HEIGHT) / 2) + "px";

            var srcUrl = this._sslBaseUrl +
                         "/partnersignup?partnerId=" +
                         this._partnerId + "&callbackUrl=" +
                         this._callbackUrl + "&iframe=true&logoUrl=" +
                         this._logoUrl + "&partnerName=" +
                         this._partnerName + "&partnerSite=" + 
                         this._partnerSite;
            if (freeWebSong) {
                srcUrl += "&freeWebSong=" + freeWebSong;
            }            

            // IMPORTANT: mode must be the final url param
            srcUrl += "&mode=" + mode;
            this._dialog.src = srcUrl;
            
            this._dialog.style.display = "block";
        },

        onSignupComplete: function(signupCanceled) {
            this.hide();

            if (!signupCanceled && lala.Player) {
                lala.Player.reloadPlayer();
            }
        },

        hide: function() {
            this.hideModalShield();
            
            this._dialog.style.display = "none";
        },

        showModalShield: function() {
            if (this.IE6) {
                this._shield.style.width = parseInt(document.body.scrollWidth);
                this._shield.style.height = parseInt(document.body.scrollHeight);
            } else {
                this._shield.style.width = "100%";
                this._shield.style.height = "100%";
            }

            this._shield.style.top = 0;
            this._shield.style.left = 0;
            this._shield.style.display = "block";
        },

        hideModalShield: function() {
            this._shield.style.display = "none";
        }
    },

    Player: {
        DEFAULT_WIDTH: 220,
        DEFAULT_HEIGHT: 70,

        EVENT_PLAYER_LOADED: "loaded",
        EVENT_PLAYER_STATUS_CHANGE: "statusChange",
        EVENT_PLAYBACK_ERROR: "error",
        EVENT_PLAYBACK_FATAL_ERROR: "fatalError",
        EVENT_PLAYBACK_COMPLETE: "complete",
        EVENT_PLAYING_SAMPLE: "playingSample",

        NUM_PLAYS_BEFORE_AD_CHANGE: 3,

        AD_EXCLUDE_KEY: 'exclude',

        _listeners: {},
        _swfId: '',
        _playerSwf: null,
        
        // if size.width, size.height not specified,
        // swf will be rendered with default dimensions
        // init params may include host, songLalaId, songName, artistName
        init: function(divId, size, params) {            
            params = params || {};
            this._adDivId = params.adDivId;
            size = size || {};

            var playerDiv = document.getElementById(divId);
            if (playerDiv) {
                this._swfId = divId + "_swf";

                var host = params.host || 'www.lala.com';
                this._userImageHost = params.userImageHost || 'http://user-images.lala.com/servlet/UserImageServlet';
                var versionPath =
                        host.indexOf('dhcp') != -1 || host.indexOf('localhost') != -1
                                ? 'static' : 'external';
                var swfUrl = 'http://' + host + '/' + versionPath + '/flash/SingleSongWidget.swf';
                var swfTemplate = '<object type="application/x-shockwave-flash" data="@swfUrl@" id="@swfId@" width="@width@" height="@height@"><param name="movie" value="@swfUrl@"><param name="wmode" value="transparent"/><param name="allowNetworking" value="all"/><param name="allowScriptAccess" value="always"/><param name="flashvars" value="@flashvars@"/><embed id="@swfId@" name="@swfId@" src="@swfUrl@" width="@width@" height="@height@" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" wmode="transparent" allowNetworking="all" allowScriptAccess="always" flashvars="@flashvars@"></embed></object>';

                params.playerMode = true;
                var flashVars = lala.buildQueryString(params);
                var swfCode = swfTemplate.replace(/@swfUrl@/g, swfUrl)
                        .replace(/@swfId@/g, this._swfId)
                        .replace(/@width@/g, size.width || lala.Player.DEFAULT_WIDTH)
                        .replace(/@height@/g, size.height || lala.Player.DEFAULT_HEIGHT)
                        .replace(/@flashvars@/g, flashVars);
                playerDiv.innerHTML = swfCode; 
            }
        },

        playSongById: function(songId, bAutoPlay) {
            if (this._playerSwf) {
                this._playerSwf.playSongById(songId, bAutoPlay);
            }
        },

        playSong: function(songName, artistName, bAutoPlay) {
            if (this._playerSwf) {
                this._playerSwf.playSong(songName, artistName, bAutoPlay);
            }            
        },

        playMP3: function(songUrl, songName, artistName, duration, bAutoPlay) {
            if (this._playerSwf) {
                this._playerSwf.playMP3(songUrl, songName, artistName, duration, bAutoPlay);
            }
        },

        playStream: function(streamUrl, songName, artistName, bAutoPlay) {
            if (this._playerSwf) {
                this._playerSwf.playStream(streamUrl, songName, artistName, bAutoPlay);
            }
        },

        playAlbumById: function(albumId, bAutoPlay, linkIndex, bLoadBag, nodeIndex) {
            if (this._playerSwf) {
                this._playerSwf.playAlbumById(albumId, bAutoPlay, linkIndex, bLoadBag, nodeIndex);
            }
        },

        playArtist: function(artist, bAutoPlay, linkIndex, bLoadBag, nodeIndex) {
            if (this._playerSwf) {
                this._playerSwf.playArtist(artist, bAutoPlay, linkIndex, bLoadBag, nodeIndex);
            }
        },

        playPlaylist: function(playlistToken, bAutoPlay, linkIndex, bLoadBag, nodeIndex) {
            if (this._playerSwf) {
                this._playerSwf.playPlaylist(playlistToken, bAutoPlay, linkIndex, bLoadBag, nodeIndex);
            }
        },

        togglePlayback: function() {
            if (this._playerSwf) {
                this._playerSwf.togglePlayback();
            }
        },

        stopPlayback: function() {
            if (this._playerSwf) {
                this._playerSwf.stopPlayback();
            }                        
        },

        addSong: function() {
            if (this._playerSwf) {
                this._playerSwf.addSong();
            }
        },

        addEventListener: function(type, handlerFn) {
            if (!this._listeners[type]) {
                this._listeners[type] = [];
            }

            this._listeners[type].push(handlerFn);
        },

        removeEventListener: function(type, handlerFn) {
            if (this._listeners[type]) {
                for (var i=0; i<this._listeners[type].length; i++) {
                    var fn = this._listeners[type][i];
                    if (fn === handlerFn) {
                        this._listeners[type].splice(i, 1);
                    }
                }
            }
        },

        fireEvent: function(type, data) {
            if (this._listeners[type]) {
                for (var i=0; i<this._listeners[type].length; i++) {
                    this._listeners[type][i](data);
                }
            }
        },

        onWebsiteImagesLoaded: function(imageObjs) {
            var self = this;            
            if (this._adDivId && !this._adInit) {
                // randomly start at index
                this._adObjs = imageObjs;
                this._adCount
                        = Math.floor(Math.random()*this._adObjs.length);
                this._playCountForAdChange = 0;                

                this.doAutoUpdateAd();
                this.addEventListener(lala.Player.EVENT_PLAYER_STATUS_CHANGE,
                    function(data) {                        
                        var status = data.status;
                        if (status == "playing") {
                            // check if we have an ad with genre/songId in path
                            if (!self.checkSpecificAdAndUpdate(data.song)) {
                                var index = (self._playCountForAdChange
                                        % lala.Player.NUM_PLAYS_BEFORE_AD_CHANGE) + 1;
                                if (self.showingExcludedAd || index == lala.Player.NUM_PLAYS_BEFORE_AD_CHANGE) {
                                    self.doAutoUpdateAd();
                                    self.showingExcludedAd = false; 
				}
                                self._playCountForAdChange++;
                            }
                        }
                    });
                this._adInit = true;
            }
        },

        doAutoUpdateAd: function() {
            var index = (this._adCount % this._adObjs.length);
            var ad = this._adObjs[index];
            this._adCount++;
            if (ad.path.indexOf(lala.Player.AD_EXCLUDE_KEY) != -1) {
                this.doAutoUpdateAd();
            } else {
                this.updateAd(ad);
            }                                    
        },

        updateAd: function(obj) {
            document.getElementById(this._adDivId).innerHTML
                    = "<a target='_blank' href='" + obj.href + "'><img src='"
                    + this._userImageHost
                    + "?path=" + encodeURIComponent(obj.path)
                    + "'/></a>";
            if (this._playerSwf) {
                var matches = obj.href.match(/fc=(.*)[&$]?/);
                if (matches) {
                    var fc = matches[0];
                    var adName = fc.replace(/^.*widgetad\./, '');
                    this._playerSwf.trackAdImpression(adName);
                }
            }
        },

        checkSpecificAdAndUpdate: function(song) {
            var keys = [];            
            if (song.genre) keys.push(encodeURIComponent(song.genre));
            if (song.linkSongLalaId) keys.push(song.linkSongLalaId);
            if (song.linkDiscLalaId) keys.push(song.linkDiscLalaId);            
            if (song.artist) keys.push(encodeURIComponent(song.artist));
            if (keys.length <= 0) return false;

            var ad = null;
            for (var i = 0; i < this._adObjs.length; i++) {
                var currVal = this._adObjs[i]['path'];
                // cycle through the different keys
                var val;
                for (var j = 0; j < keys.length; j++) {
                    val = keys[j];
                    if (currVal.indexOf(val) != -1) {
                        ad = this._adObjs[i];
                        break;
                    }
                }
                if (ad) break;

            }
            if (ad) {
                this.updateAd(ad);
                if (ad.path.indexOf(lala.Player.AD_EXCLUDE_KEY) != -1) {
	            this.showingExcludedAd = true;			
		} 
		return true;
            } else {
                return false;
            }
        },

        // fired once the swf has completed loading.
        onPlayerLoaded: function() {            
            this._playerSwf = document.getElementById(this._swfId);
            this.fireEvent(lala.Player.EVENT_PLAYER_LOADED);
        },

        // currently triggered when playback becomes disabled. signin
        // is required for subsequent playback.
        onPlaybackFatalError: function() {
            this.fireEvent(lala.Player.EVENT_PLAYBACK_FATAL_ERROR);
        },

        // triggered as the result of an IO error, playback can proceed
        // after this error.
        onPlaybackError: function() {
            this.fireEvent(lala.Player.EVENT_PLAYBACK_ERROR);
        },

        // triggered when playback of a song is complete.
        onPlaybackComplete: function() {
            this.fireEvent(lala.Player.EVENT_PLAYBACK_COMPLETE);
        },

        onPlayerStatusChange: function(status, songData) {
            this.fireEvent(lala.Player.EVENT_PLAYER_STATUS_CHANGE,
                           {status: status, song: songData});
        },

        onPlayingSample: function() {
            this.fireEvent(lala.Player.EVENT_PLAYING_SAMPLE);
        },

        reloadPlayer: function() {
            if (this._playerSwf) {
                this._playerSwf.reloadPlayer();
            }
        }
    },

    buildQueryString: function(params) {
        var str = '';

        for (var key in params) {
            var val = params[key];
            // typeof is needed because 0 == '', sadly
            if (val == null || (typeof(val) == 'string' && val == '')) continue;
            str += '&' + key + '=' + encodeURIComponent(val);
        }
        if (str != '') str = str.replace(/^&/, ''); // remove the leading amp

        return str;
    },

    assert: function(cond, msg) {
        if (cond) return;
        throw 'Lala Playlist widget: ' + msg;
    }
};

if (window.addEventListener) {
    window.addEventListener('load', lala.onload, false);
} else {
    window.attachEvent('onload', lala.onload);
}
