/**
 * Visualizer communication interface
 *
 * visualizer will never interact with web services directly, but rather
 * pull all necessary state data from JS and call proxy methods in JS that
 * will gather information from necessary sources and marshal it back to 
 * the flash application
 *
 * billboard.visualizer.setData( [ {id:50294,albumId:5112,track:null}, 
 *                                  {id:50294,albumId:5112,track:null}, 
 *                                  {id:50294,albumId:5112,track:null}
 *                               ] );
 *
 */
if ( typeof(window.billboard)=="undefined"){ billboard={}; }
billboard.visualizer = new ( function($) 
{
    var me = this;
    var type = ""; // default|artist|compare|compare-h2h
    var artists = [];
    var formatId = null;
    var head2Head = false;

    me.blockedIds = ["684701","684702","684703","684704","684705","684721","736074","771713","964160","978804"];

    me.swfId = "visualizer_swf";
    me.vizOpen = false;
    me.vizInited = false;
    me.fromFlashVizData;
    
    /**
     *
     */
    me.getFeaturedArtists = function() 
    {
        var data = {};
        data.formatId = null;
        data.head2head = false;
        data.artists = [
            {
                "id":"5451",
                "songId":null,
                "albumId":null
            },
            {
                "id":"4057",
                "songId":null,
                "albumId":null
            },
            {
                "id":"5738",
                "songId":null,
                "albumId":null
            },
            {
                "id":"48340",
                "songId":null,
                "albumId":null
            }
        ]
        
        return data;
    };
    
    me.vizData = me.getFeaturedArtists();
    
    me.onPageLoadedHasRun = false;
    me.swfNeedsArtists = false;
    
    me.formatsWS     = "/artist/formats.ws?artistId=";
    me.performanceWS = "/artist/performance.ws?artistId="; // &chartFormatId=
    me.weeksAlbumWS  = "/album/weeks.ws?albumId=";  // &chartFormatId=
    me.weeksTrackWS  = "/track/weeks.ws?trackId=";  // &chartFormatId=
    
    me.cache = [];
    me.requestQueue = [];
    me.response = {};
    
    me.firstTime = true;
    me.isFlashReady = false;
    me.isDataReady = false; 
    
    // listen for page loaded changes
    billboard.broadcaster.addListener( "pageLoaded", function() { me.onPageLoaded(); } );

    /**
     * called *ONE* time per web site visit - 
     * doesnt do much more than register for page loaded events
     */
    me.init = function()
    {       
        billboard.info("Visualizer.init()");

        /**
         * determine base type
         *  a) if url contains information for visualizer, its either
         *    i) one artist type is 'artist'
         *    ii) two artist type is 'compare'
         *    iii) two artist with h2h flag set 'compare-h2h'
         *  b) if, artist/album/song page type is 'artist'
         *  c) none of the above, 'default'
         */
        type = "default";       

        // if IE6 (since it doesnt support the position:fixed css), update 
        // everything, and start listening for scroll/resize to reposition visualizer
        if ( $.browser.msie && parseInt($.browser.version) == 6 ) {
            billboard.info("IE6 - activating scroll/resize listeners to position visualizer");
            var moveViz = function() { 
                var pos = $(window).height() + $(window).scrollTop() - (288);
                $("#visualizer-container").css({top:pos});
            }
            $("#visualizer-container").css("position","absolute");
            $(window).scroll( moveViz );
            $(window).resize( moveViz );

            var pos = $(window).height() + $(window).scrollTop() - (288);
            $("#visualizer-container").css({top:pos});
        }

        // slide out the visuzalizer button, indicating readiness
        setTimeout( '$("#visualizer-container").animate({"left":"0px"});', 2000);       
    };

    /**
     * @param data, String - viz data deep link, must be formatted as comma 
     * delimited, pipe separated name values pairs, 
     *
     * examples:
     *
     * single artist
     *   aid1|5738
     *
     * single artist with an album expanded for a specific chart format
     *   h2h|0,cfid|305,t|a,aid1|5738,iid1|541077
     *
     * two artists with albums compared for a given chart format
     *   h2h|0,cfid|305,t|a,aid1|5738,iid1|541077,aid2|1246296,iid2|1636139
     *
     * two artists with albums compared for a given chart format, head to head
     *   h2h|1,cfid|305,t|a,aid1|5738,iid1|541077,aid2|1246296,iid2|1636139
     */
    me.parseVizData = function()
    {
        var pos = billboard.currentUrl.search(/viz=\w+$/);
        if ( pos < 0 ) return;

        var endpos = billboard.currentUrl.indexOf("&sms");
        
        if( endpos < 0 ){
            var query = unescape( billboard.currentUrl.substr( pos + 4 ) );
        }else{
            var query = unescape( billboard.currentUrl.substring( pos + 4, endpos) );
        
        }
        
            
        var parts = query.split("Y");
        var pairs = new Array();
        for ( var i=0;i<parts.length;i++ ) {
            pairs[parts[i].split("Z")[0]] = parts[i].split("Z")[1];
        }
        
        data = {};

        if (pairs['featured'] == '1') {
            billboard.log("deep link to Featured Artists");
            data = me.getFeaturedArtists();
        } else {
            billboard.log("deep link to artist(s)");
            var artist;
            var type = (pairs['t']=='a')?('album'):(pairs['t']=='s'?'song':null);

            data.head2head = (pairs['h2h']=='1')?true:false;
            data.formatId =  (pairs['cfid'])?pairs['cfid']:null;
            data.artists = new Array();

            artist = { id:pairs['aid1'] };
            if ( pairs['iid1'] ) { 
                artist[type+"Id"] = pairs['iid1'];
            }               
            data.artists.push( artist );

            if ( pairs['aid2'] ) { 
                artist = { id:pairs['aid2'] };
                if ( pairs['iid2'] ) { 
                    artist[type+"Id"] = pairs['iid2'];
                }               
                data.artists.push( artist );
            }
        }

        billboard.log("Visualizer.parseVizData("+query+")");
        billboard.log( data );
        return data;
    };
    
    me.getDeepLink = function()
    {
        billboard.log("Visualizer.getDeepLink");
        var base = billboard.currentUrl;
        if ( window.location.pathname.indexOf("bbcom") == -1 ) {
            base = base.replace("bbcom","");
        }
        billboard.log("base = " + base);

        var data = me.fromFlashVizData?me.fromFlashVizData:me.vizData;

        var url = "";
        if (data.artists.length == 4) {
            url = "featuredZ1";
            url = updateQueryParams( base, {viz:url} );
        } else if (data.artists.length == 1 || data.artists.length == 2) {
            billboard.log("url = " + url);
            url = "h2hZ";
            billboard.log("url = " + url);
            url += (data.head2head) ? "1" :"0";
            billboard.log("url = " + url);
            if ( data.formatId ) { 
                url += "YcfidZ" + data.formatId;
            }
            billboard.log("url = " + url);
            url += "Yaid1Z" + data.artists[0].id;
            billboard.log("url = " + url);
            if ( data.artists[0].songId ) {
                url += "Yiid1Z" + data.artists[0].songId;
                url += "YtZs";
            } else if ( data.artists[0].albumId ) {
                url += "Yiid1Z" + data.artists[0].albumId;
                url += "YtZa";
            }
            billboard.log("url = " + url);

            if ( data.artists[1] ) {
                url += "Yaid2Z" + data.artists[1].id;
                if ( data.artists[1].songId ) {
                    url += "Yiid2Z" + data.artists[1].songId;
                } else if ( data.artists[1].albumId ) {
                    url += "Yiid2Z" + data.artists[1].albumId;
                }
            }
            billboard.log("url = " + url);
            url = updateQueryParams( base, {viz:url} );
            billboard.log("url = " + url);
        } else url = base;
        
        billboard.log("... finally, url = " + url);
        
        return url;
    };

    
    /**
     * getter & setter for 'type'
     */
    me.type = function(t){
        if (t) type = t;
        return type;
    };

    /**
     * getter & setter for 'formatId'var data = {};
     */
    me.formatId = function(t){
        if (t) formatId = t;
        return formatId;
    };

    /**
     * getter & setter for 'head2Head'
     */
    me.head2Head = function(t){
        if (t) head2Head = t;
        return head2Head;
    };

    /**
     * triggered by flash when its loaded and ready for data
     */
    me.visualizerReady = function()
    {
        billboard.log("visualizerReady");
        me.isFlashReady = true;
        if ( me.isDataReady ) {
            billboard.log("artists.length = " + artists.length);
            var visualizer = me.getVisualizer();
            visualizer.vizBaseDataResults(me.vizData);
            me.firstTime = false;
        }
    };


    /**
     * called by the flash application when changes happen inside of it - specifically
     * changes that the javascript cannot imply from current page or JS app state, i.e. head-to-head
     */
    me.setVizData = function( data ) 
    {
        billboard.log("visualizer.setVizData");

        for (var i = 0; i < data.artists.length; i++) {
            for (var propp in data.artists[i]) {
              if(propp == 'id' && $.inArray(data.artists[i][propp], me.blockedIds) > -1)
                data.artists[i][propp] = -1;
            }
        }

        me.vizData = data;
        me.fromFlashVizData = data;
        for (var prop in data) {
            billboard.log("data." + prop + " = " + data[prop]);
        }
        for (var i = 0; i < data.artists.length; i++) {
            for (var propp in data.artists[i]) {
                billboard.log("data.artists[" + i + "]." + propp + " = " + data.artists[i][propp]);
            }
        }
    };

    /**
     *
     */
    me.setData = function( artistId, chartFormatId, itemId, type )
    {
        billboard.log("visualizer.setData");
        if ( typeof(artistId)=="undefined" ) {
            return;
        }
        type = (type && type.length > 0 && type=="album")?("album"):("song");
        var artist = {};
        artist.id = ($.inArray(artistId, me.blockedIds) > -1) ? -1 : artistId;
        artist.songId = (type=="song" && itemId.length > 0) ? itemId : null;
        artist.albumId = (type=="album") ? itemId : null;
        artists = [ artist ];
        formatId = (chartFormatId) ? chartFormatId : null;
        head2Head = false;
        
        billboard.log("artist.id = " + artist.id);
        billboard.log("artist.songId = " + artist.songId);
        billboard.log("artist.albumId = " + artist.albumId);
        billboard.log("formatId = " + formatId);
        
        me.vizData = {};
        me.vizData.formatId = formatId;
        me.vizData.head2Head = head2Head;
        me.vizData.fromPage = true;
        me.vizData.artists = artists;
        
        var visualizer = me.getVisualizer();
        billboard.log( "visData:" );
        billboard.log( me.vizData );
        
        if (!me.vizOpen) me.doOpen();
        if (me.vizInited) visualizer.vizBaseDataResults( me.vizData );
    };
    
    
    /**
     * toggles open/closed state
     */
    me.toggle = function(main)
    {
        if ( !me.vizOpen ) me.doOpen(main);
        else me.doClose();
    };


    /**
     *
     */
    me.doOpen = function(main)
    {
        var vId="";
        var midX = (me.vizInited) ? "-790px" : "-63px";
        $("#visualizer-container").animate({"left":midX}, 300, "easeinout", function() {
            if (!me.vizInited) {
                $("#visualizer-bkg").css("display","block");
                $("#visualizer").css("display","block");
                $("#float-container").css("top","0px");
                $("#float-container").css("position","absolute");
                $("#visualizer-container").css("width","808px");
            }           
            $("#float-container").css("height","284px");
            $("#visualizer-bkg").css("height","284px");
            $("#visualizer-container").css("height","284px");
            $("#visualizer-container").css("bottom","0");
            $("#visualizer-container").css("left","-727px");
            $("#visualizer-buttons").css("width","12px");
            $("#visualizer-icon").css("display","none");
            $("#visualizer-share").css("display","block");
            $("#visualizer-container").animate({"left":"0px"},1000,"easeinout");
            me.vizOpen = true;
            me.vizInited = true;
            
            if(me.vizData.artists){
                if(me.vizData.artists[0].albumId) vId = "Album ID: " + me.vizData.artists[0].albumId;
                else if(me.vizData.artists[0].songId) vId = "Song ID: " + me.vizData.artists[0].songId;
            }
             
            if(main) googleA.trackEvent(3, "MainOpen", (me.vizData.artists) ? "Artist ID: " + me.vizData.artists[0].id : "", vId);
            else googleA.trackEvent(3, "Open", (me.vizData.artists) ? "Artist ID: " + me.vizData.artists[0].id : "", vId);
        });
    };
    
    /**
     *
     */
    me.doClose = function()
    {
        $("#visualizer-container").animate({"left":"-727px"},1000,"easeinout",function() {
            $("#float-container").css("height","69px");
            $("#visualizer-bkg").css("height","69px");
            $("#visualizer-container").css("left","-790px");
            $("#visualizer-container").css("height","69px");
            $("#visualizer-container").css("bottom","27%");
            $("#visualizer-share").css("display","none");
            $("#visualizer-buttons").css("width","81px");
            $("#visualizer-icon").css("display","block");
            $("#visualizer-container").animate({"left":"-727px"},300,"easeinout");
        });
        
        me.vizOpen = false;
    };
        
    /**
     * getter & setter for 'artists'
     */
    me.artists = function(a){
        billboard.log("visualizer.artists()");
        if (a) artists = a;
        if (artists.length > 0) me.sendArtists();
        else me.swfNeedsArtists = true;
    };
    
    me.sendArtists = function() {
        billboard.log("me.sendArtists");
        var visualizer = me.getVisualizer();
        visualizer.artistRecsReceived(artists);
    }
    
    ;/**
     * pull the flash object to send externalInterface calls to 
     */
    me.getVisualizer = function()
    {
        if ( $.browser["msie"] ) { 
            return window[me.swfId];
        } else {
            return document[me.swfId];
        }
    };
    
    /**
     *
     */
    me.onPageLoaded = function()
    {
        billboard.log("Visualizer.onPageLoaded");

        /** 
         * get/create the artist list, and get and populate artist array by 
         *  a) if the url has information about visualizer, parse it out 
         *  b) does this page have artist as part of its context
         *    i) if this is an album page, get the album id
         *    ii) if song page, get song id
         *  c) return the default editorial artists
         *
         */
        me.vizData = me.parseVizData();
        if ( me.vizData ) { 
            if ( !me.vizOpen ) { 
                me.doOpen();
            }
        }
        else if ( billboard.section == "artists" ) {

            var id,type,song,album;

            type = $("#entity-id").text().split("-")[0];
            id = $("#entity-id").text().split("-")[1];
            if ( type == "artist" ) { 
                if($.inArray(id, me.blockedIds)>-1)
                    me.vizData = { artists:[ {id:-1} ] };
                else 
                    me.vizData = { artists:[ {id:id} ] };
            }
            else if ( type == "album" ) {
                album = id;
                id = ($.inArray($(".artist-id").text(), me.blockedIds)>-1) ? -1 : $(".artist-id").text();
                chartFormatId = $(".chart-format-id").text();
                me.vizData = { formatId:chartFormatId, artists:[ {id:id,albumId:album} ] };
                billboard.log( me.vizData );
            }
            else if ( type == "song" ) {
                song = id;
                id = ($.inArray($(".artist-id").text(), me.blockedIds)>-1) ? -1 : $(".artist-id").text();
                chartFormatId = $(".chart-format-id").text();
                me.vizData = { formatId:chartFormatId, artists:[ {id:id,songId:song} ] };
                billboard.log( me.vizData );
            }
        }
        else {
            me.vizData = me.getFeaturedArtists();       
        }

        // wait for the flash to be ready, and send then
        me.isDataReady = true;
        if ( me.isFlashReady && me.firstTime ) {            
            var visualizer = me.getVisualizer();
            visualizer.vizBaseDataResults(me.vizData);
            me.firstTime = false;
        }
    };

    /**
     *
     */
    me.onError = function( p1, p2, p3 ) 
    {
        billboard.log("Visualizer.onError(" + p1 + "," + p2 + "," + p3 + ")");
        var visualizer = me.getVisualizer();
        if ( visualizer ) visualizer.dataError();
    };

    

    /**
     * getFormatByArtist
     *
     * creates a queue of chart format data requests, and sends them along to the true 
     * getFormatByArtist implementation
     * 
     * @param artistId - id of an artist
     * @param chartFormats - an array of chart format IDs
     */
    me.getFormatByArtist = function( artistId, chartFormats )
    {
        me.requestQueue = [];
        var request = {};
        var len = chartFormats.length-1;
        for ( var i=len;i>=0;i-- ) {
            request = { method:"getFormatByArtist", artistId:artistId, chartFormatId:chartFormats[i] }
            me.requestQueue.push( request );
        }

        me.response = { formats:[] };
        request = me.requestQueue.pop();
        me.getFormatByArtistImpl( request.artistId, request.chartFormatId );
    };

    /**
     * Gets all the information under a specific chart format for a specific artist
     * if the chart format is type 'album', then the WebService returns  array of albums 
     * and if its singles, tracks are returned, in both cases they are translated into 
     * 'items' prior to delivery to the flash
     *
     * @param artistId - id of an artist
     * @param chartFormatId - a chart format ID
     */
    me.getFormatByArtistImpl = function( artistId, chartFormatId )
    {       
        billboard.log( "Visualizer.getFormatByArtistImpl("+artistId+","+chartFormatId+")");

        artistId = ($.inArray(artistId, me.blockedIds) > -1) ? -1 : artistId;
        
        var artist = me.cache[artistId];
        if ( !artist || typeof(artist.id) == "undefined" ) {
        }               
                    
        $.ajax( {
                type: "GET",
                url: me.performanceWS + artistId + "&chartFormatId=" + chartFormatId,
                dataType: "xml",
                error:me.onError,
                success:function(response) {
                    response = $.xmlToJSON( response );
                    if ( !me.cache[artistId] ) {
                        me.cache[artistId] = {};
                    }
                    var artist = me.cache[artistId];
                    if (!artist.formats ) {
                        artist.formats = [];
                    }
                    
                    if ( typeof(artists.id) == "undefined" ) {
                        artist.id = response.artist[0].id;
                        artist.image = response.artist[0].image;
                        artist.link = response.artist[0].link;
                        artist.name = response.artist[0].name;
                    }
                    
                    var format = {};
                    format.id = response.format[0].id;
                    format.group = response.format[0].group;
                    format.length = response.format[0].length;
                    format.name = response.format[0].name;
                    
                    
                    var index = -1;
                    for ( var i=0;i<artist.formats.length;i++ ) {
                        if ( parseInt(artist.formats[i].id) == parseInt(chartFormatId) ) {
                            format = artist.formats[i];
                            index = i;
                            break;
                        }
                    }
                    format.artistName = response.artist[0].name;
                    format.items = [];
                    if (format.group == "Singles") {
                        format.items = response.tracks[0].track;
                    }
                    else if (format.group == "Albums") {
                        format.items = response.albums[0].album;
                    }
                    
                    format.peers = [];
                    
                    billboard.log("checking for related artists");
                    if ( response.related_artists[0].artist != undefined ) {
                        billboard.log("artist.length = " + response.related_artists[0].artist.length);
                        if ( response.related_artists[0].artist.length > 0 ) {
                            billboard.log("adding related artists");
                            format.peers = response.related_artists[0].artist;
                        }
                    }
                    
                    if ( index == -1 ) {
                        artist.formats.push( format );
                    }
                    artist.peers = response.related_artists[0].artist; // this should come back in the first, but still isnt
                    //artist.url = response.artist[0].link; // these should come back in the first getArtist call
                    //artist.image = response.artist[0].image; // these should come back in the first getArtist call

                    if ( !me.response.formats ) {
                        me.response.formats = [];
                    }
                    me.response.formats.push( format );
                    
                    for (i = 0; i < me.response.formats.length; i++) {
                        me.response.formats[i].image = response.artist[0].image;
                    }
                    
                    if ( me.requestQueue.length > 0 ) {
                        var request = me.requestQueue.pop();
                        me.getFormatByArtistImpl( request.artistId, request.chartFormatId );
                    }
                    else {
                        // send back to visualizer
                        billboard.log( me.response );
                        var visualizer = me.getVisualizer();
                        if ( visualizer && visualizer.formatByArtistResults ) visualizer.formatByArtistResults( me.response );
                    }
                }
        });     
    };
    
    me.getArtist = function( artistId )
    {
        $.ajax( {
                type: "GET",
                url: me.formatsWS + artistId,
                dataType: "xml",
                error:me.onError,
                success:function(response) {
                
                    response = $.xmlToJSON( response );
                    var artist = response.artist[0];
                    artist.formats = response.formats[0].format;
                    artist.url = response.artist[0].link;
                    me.cache[artistId] = artist;
                    
                    billboard.log("response.artist[0].name = " + response.artist[0].name);
                    billboard.log(artist);
                    var visualizer = me.getVisualizer();
                    if ( visualizer ) visualizer.artistResults( artist );
                }
        });
    };


    /**
     * request the weekly data for an album, and related albums
     */
    me.getWeeks = function( chartId, itemId, type )
    {
        billboard.log("visualizer.getWeeks");
        billboard.log(" chartId = " + chartId);
        billboard.log(" itemId = " + itemId);
        billboard.log(" type = " + type);

        var url;
        if ( type == "album" ) {
            url = me.weeksAlbumWS + itemId+"&chartFormatId="+chartId;
        }
        else {
            url = me.weeksTrackWS + itemId+"&chartFormatId="+chartId;
        }

        $.ajax( {
            type:"GET",
                     url:url,
                     dataType:"xml",
                     error:me.onError,
                     success:function(response) {
                response = $.xmlToJSON( response );

                // create the response object from the deserialized xml
                var data = {};
                data.format = response.format[0];
                data.artist = response.artist;
                data.weeks = response.weeks[0].week;

                if ( type == "album" ) { 
                    data.album = response.album;
                    //data.album[0].url = "/album/press-play/life-is-beautiful/1262026";
                    data.related = response.related_albums[0].album;
                }
                else if ( type == "track" ) {
                    data.track = response.track;
                    //data.track[0].url = "/song/jason-mraz/i-m-yours/11149259";
                    data.related = response.related_tracks[0].track;
                }

                // send to visualizer
                billboard.log( data );
                var visualizer = me.getVisualizer();
                if ( visualizer && visualizer.weeksResults ) visualizer.weeksResults( data );
            }});                     
    }

    me.doSearch = function( searchString, id )
    {
        billboard.log("searchString = " + searchString);
        var url = "/search-suggest.json";
        url = url + "?q="+searchString;
        var i = id;
        if ( searchString.length > 2 ) {
            $.getJSON( url, function(data) {
                billboard.log( data );
                var list = data.response.body.list;
                var response = {};
                response.items = list;
                response.id = i;
                var visualizer = me.getVisualizer();
                billboard.log("visualizer = " + visualizer);
                visualizer.searchResults(response);
            });
        }
    }
    
    me.updateURL = function( newUrl )
    {
        billboard.log("visualizer.updateURL");
        billboard.log("newUrl = " + newUrl);
        billboard.navigateToUrl( newUrl )
    }

})(jQuery);

