/**
 * 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.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.indexOf("viz=");
		if ( pos < 0 ) return;
		
		var query = unescape( billboard.currentUrl.substr( pos + 4 ) );
	
		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 += ",tZs";
			} else if ( data.artists[0].albumId ) {
				url += "Yiid1Z" + data.artists[0].albumId;
				url += "YtZa";
			}
			billboard.log("url = " + url);

			if ( data.artists[1] ) {
				url += ",aid2Z" + 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");
		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 = 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()
	{
		if ( !me.vizOpen ) me.doOpen();
 		else me.doClose();
	};


	/**
	 *
	 */
	me.doOpen = function()
	{
	    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;
	    });
	};
	
	/**
	 *
	 */
	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","215px");
	        $("#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" ) { 
				me.vizData = { artists:[ {id:id} ] };
			}
			else if ( type == "album" ) {
				album = id;
				id = $(".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 = $(".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+")");
		
		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);
