var map;
var datecode = 0;
var mapcontainer;

// zoom levels
var defaultZoomLevel = 3;
var tagCloudZoomLevel = 7;

var defaultCutoffForTweets = 50;

var EVENT_NAME_KEY = 'eventname';

//
// The generated event list will have calls to this function
//
function showEvent(eventID, minDate, maxDate, zoomLevel,tweetThreshold) {
	$("#events_overlay").hide("slow");
	$("#events").hide("slow");
	$("#curEvent").val(eventID);
	$('#date_event').val("event");
    
	//min,max dates are passed to the function from the database
	//see getEventList.php 

	$('#cur_date').datepicker('option', 'minDate', new Date(minDate));
	$('#cur_date').datepicker('option', 'maxDate', new Date(maxDate));
	
	defaultZoomLevel = zoomLevel; //change the global var for zoom
	
	defaultCutoffForTweets = tweetThreshold; //change the global var for tweet cutoff
	
	changeScreen(3);
}

/**
 * 
 * @param enablePoints
 * @return
 */
function initialize_maps(enablePoints) {
	
	if ( enablePoints === undefined ) {
		enablePoints = true;
	}
	
	if (GBrowserIsCompatible()) {
		mapcontainer = $("#map_canvas");
		map = new google.maps.Map2(document.getElementById("map_canvas"));
		map.setCenter(new google.maps.LatLng(39.7736870, -84.0854690),
				defaultZoomLevel); // initial zoom is the number following the
									// lat long
		map.setUIToDefault();
		map.removeMapType(G_HYBRID_MAP);
		map.removeMapType(G_SATELLITE_MAP);
		map.removeMapType(G_PHYSICAL_MAP);
		map.disableScrollWheelZoom();
		
		//Note : enable this to center the tag cloud on move
		//google.maps.Event.addListener(map, "moveend", positionOverlay($('#tags_map')));

		// bindOnClickToDateArrows();
		
		if (enablePoints){
			appendLoader(mapcontainer);
			createPoints();
		}
		
	}
} // end map initialize

// a wrapper method for logging onto firebug console. Checks if console is
// undefined and if not, writes to console. Fixes issues with ff when fb is
// disabled or not present
// works in Webkit, did not check in IE with fb lite.
function log_console(msg) {
	if (typeof console != "undefined") {
		console.log(msg);
	}
}

/*
 * 
 *  Generate the points
 *  Responds to selecting an event
 * 
 */
function createPoints() {
	map.clearOverlays();
	var point;
	var marker;
	var url = "conceptcloud/getLocations.php";
	// alert(console==='undefined');
	log_console(url);
	$
			.getJSON(
					url,
					{'curEvent' : $('#curEvent').val(),
					 'datecode' : $('#cur_date').val(),
					 'date_event' : $('#date_event').val(),
					 'cutoff' : defaultCutoffForTweets
					},
					
					function(data) {
//						
						$("#map_canvas_loader").remove();
						
						$("#cur_date").val(data.date);
						
						//add the event details as the title to the event name
						$("#event_name").attr("title",data.event_description);
						//$("#event_content").html(data.event_description);
						
						$("#event_content").height("180px");
						$("#event_name").text("Twitris Map : " + data.event_name);
						$("#event_name").data(EVENT_NAME_KEY,data.event_name);
						
						//register the highlighting
						$('#event_name').hover(function(){
							$(this).css({'color': 'blue'});
						},function(){
							$(this).css({'color': 'black'});
						})
						
						displayMessage("Pins on the map are displayed only for locations with more than " +  defaultCutoffForTweets + "  tweets on this day");
						
						$('#curEvent').val(data.event_id);
						$
								.each(
										data.location,
										function(i, item) {
											$(document).data(
													item.latitude + ":"
															+ item.longitude,
													item.cluster_label);
											point = new GLatLng(item.latitude,
													item.longitude);
											markeroptions = {
												title : 'Click to see event descriptors from ' + item.cluster_label
											};
											marker = new GMarker(point,
													markeroptions);
											map.addOverlay(marker);
											GEvent.addListener(marker, "click",
													zoomAndSetText);
											// ("<div/>").text(item.latitude).appendTo("#images");
										});
					});
}



// appends an ajax style loader to any div. call before loading with the parent
// jQuery object. positions to the middle of the parent.
function appendLoader(parent) {
	// assigns an id to the element we are adding
	var id = parent.attr('id') + "_loader";
	log_console(' inside append loader');
	// creates the element (ajax loader animation)
	parent.append('<div id="' + id + '" class="loading"></div>');
	// position of the element
	var left = parseInt(parent.css('width')) / 2 - 17;
	var top = parseInt(parent.css('height')) / 2 - 17;
	// assigns the css properties for position
	$("#" + id).css( {
		'display' : 'block',
		'top' : top,
		'left' : left
	});

}

/*
 * 
 * 
 * 
 */
function zoomAndSetText(latlng) {
	//log_console("Inside zoomAndSetText");
	map.setCenter(latlng, tagCloudZoomLevel); // center the map and zoom
	setText(latlng);
}

/*
 * 
 * 
 */
function setText(latlng) {
	//for adding the tag overlay, see the success action for the 
	//addCloudContainer
	var tagsmap = $("#tags_map");
	var cluster_label = $(document).data(latlng.lat() + ":" + latlng.lng());

	addCloudContainer(cluster_label);

}

// adds the closebutton to any div. when the button is clicked the parent is
// closed. The behavior on close is set as a data value to the parent and is
// eval-ed.
function addCloseButton(parent,overlay) {
	
	//log_console(parent.attr('id') + ' is the parent');
	var id = parent.attr('id') + "_close";
	//log_console(id);
	parent.append('<div id= "' + id + '" class="closeButton" style="width: 66px;"></div>');
	//log_console(parent.attr('id') + ' is the parent');
	var closeButtonElement = $('#' + id);
	var currentWidth = parseInt(closeButtonElement.css('width'));
	var padding = parseInt(parent.css("padding"));
    
	if (isNaN(padding)) {
    	padding = 0;
    }
		
	closeButtonElement.css( {
		'left' : parseInt(parent.css("width")) - currentWidth + padding,
		'display' : 'block',
		'cursor' : 'pointer'
		
	});
	
	closeButtonElement.attr("title","Click here to close this dialog");
	
	closeButtonElement.click(function() {
		// remove the close button; is this better or just letting it stay and
		// not adding if one is present better?
		if (overlay != undefined) 	
			closeButtonAction($("#" + $(this).parent().get(0).id), overlay);
		else closeButtonAction($("#" + $(this).parent().get(0).id));
		//	$(this).remove();
		});
}

function closeButtonAction(parent,overlay) {
	parent.hide('slow');
	eval(parent.data('closeaction'));
	
	
	//overlay.hide('slow');
}

// attach a cloud to a parent with a set of actions
function addCloudContainer(cluster_label) {
	

	// see data for parameters
	var tagFetchURL = 'conceptcloud/filterspots.php';

	log_console(tagFetchURL);

	// A
	$.ajax( {
		url : tagFetchURL,
		global : false,
		type : "GET",
		
		data : ({
			 'cc' : cluster_label,
			 'date': $("#cur_date").val(),
			 'curEvent': $('#curEvent').val()
		}),
		
		dataType : "html", // return type is html
		
		beforeSend: function (xhr) {
			  displayMessage("Loading the tag cloud.Please Wait ..");
		},

	    complete: function (xhr, textStatus) {
			displayMessage("");
			//update the display message
			if (textStatus == 'success'){
				//update the geo location
				displayMessage("You are looking at data from " +  cluster_label);
			}
			
			
			
			
		
			 
			 
	    },
        error: function(xhr){
	    	alert("Oops  - Something went wrong!"); // TODO change this
	    },
	    
		success : function(data) {
	    	
	    	// attach tag overlay
	    	parent = attachTagsOverlay();
	    	
	    	
	    	// append the message div
	    	parent.append('<div id="message"></div>');
	    	var messageElt = $("#message");
	    	//set styles for the message
	    	messageElt.css({
	    		'position': 'absolute',
	    		'width': (parent.innerWidth()),
	    		'height': (parent.innerHeight()),
	    		'left' : '20px',
	    		'opacity': '1.0',
	    		'overflow': 'hidden',
	    		'top': '30px'
	    	});
	    	messageElt.data('cc', cluster_label);
	    	
	    	// attach what we got to the message element
	    	messageElt.html(data);
	    	
	    	// NOTE : the element #tags1 is loaded
	    	//from the above insert
			$("#tags1").css( {
				 'position': 'static',
				 'width' : messageElt.innerWidth(),
				 'height': messageElt.innerHeight(),
				 'z-index' : "100",
//				 'margin-top' : '20px',
				 'line-height': '30px'
				 
				

			});
	    	var tags_map_width = messageElt.innerWidth() + 30;
	    	$('#tags_map').css('width', tags_map_width + 'px');
	    	var tags_map_height = messageElt.innerHeight() + 10;
	    	$('#tags_map').css('height', tags_map_height + 'px');
	    	addCloseButton(parent);
	    	// look at jquery event docs for the hover
	    	// event
	    	$("#tags1 a").hover( 
	    	  function(){
	    		  $(this).css({'text-decoration' : 'underline','cursor': 'pointer'});
	    	  },
	    	  function(){
	    		  $(this).css({'text-decoration' : 'none'});	    		
	    	  });
	    	
			
			$("#tags1 a").css( {
				'text-decoration' : 'none',
				//'margin-top' : '10px',
				//'margin-bottom' : '10px',
				'margin-left' : '10px',
				'margin-right' : '10px',
				'font-weight': 'bolder'
			}).click( function(e) {
				$(this).data("X", e.pageX);
				$(this).data("Y", e.pageY);

					// this is the text of the clicked tag
					var text = $(this).text();
					
					// fetch news
					fetchTwitsixNews(text,
							       $("#cur_date").val(),
							       $("#event_name").data(EVENT_NAME_KEY));
					// fetch dbpedia
					fetchDBPedia(text,$("#event_name").data(EVENT_NAME_KEY));
					
					// fetch relevant tweets
					fetchTweets(text, $("#cur_date").val(), cluster_label,$("#event_name").data(EVENT_NAME_KEY));
		});
			
			$("#tags1 a").tagcloud( {
				size: {start: 18, end: 40, unit: "px"},
			    color: {start: '#603311', end: '#8B0000'}  //color change from red to dark green
			});
			
		    
	}});
	
}

/* ************************************************************** */
/* Helper functions */

/*
 *  Tags overlay
 * 
 */
function attachTagsOverlay(){
	// remove and add the element
	$("#tags_map").remove();
	$("#container")
			.append(
					'<div id="tags_map"></div>');

	var tagsmap = $("#tags_map");
	tagsmap.appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));
	tagsmap.show().css( {
		//'background-color': '#557788',// !important - the twitter color
		'background-color': '#FFFFFF',
		'opacity': '0.8',
		'position': 'relative',
		'max-height': '400px', 
		'min-height': '350px',
		'max-width': '800px', //top and  left set by the positionOverlay call
		'min-width': '600px',
		//'top' : '15px',
		//'left' : '20px',
		'padding': '10px', //used in code to position the close button
		'text-align' : 'center',
		'border' : 'solid 4px #000000'
		
		
	});

	positionOverlay(tagsmap);
	
	// the close button is very generic and can be attached to any element. The
	// action of the close button should be stored as a data property of the
	// parent
	tagsmap.data('closeaction',
					'map.setCenter(new GLatLng(39.7736870,-84.0854690),' + defaultZoomLevel + ');' + 
					"$(\"#message\").remove();" +
					"displayMessage('Pins on the map are displayed only for locations with more than " + defaultCutoffForTweets + " tweets on this day');");
		
	//make it have rounded corners
	tagsmap.corner();
	
	return tagsmap;
}

/*
 * Fetch the nes items
 * @param keywordText
 * @param date
 * @param eventid
 * @return
 */
function fetchTwitsixNews(keywordText, date, eventid) {
	var newsURL = "twitnews/get6news.php";

	$.ajax( {
		url : newsURL,
		global : false,
		type : "GET",
		data : ({
			keyword : keywordText, //TODO pass the display name for this event ?
			date : date,
			event : eventid
		}),
		dataType : "html", // return type is html
		
		beforeSend: function (xhr) {
			 //update the header
//	    	  displayHTMLMessage("<h3>Related news for " + keywordText + " [" + eventid  + "]</h3>" ,$('#news_widget_head'));
	    
			  displayMessage("Loading related news items. Please Wait ..",$('#googlenews_content'));
		},

	    complete: function (xhr, textStatus) {
			//displayMessage("");
	    },

		success : function(data) {
		    var contentDisplay = $('#googlenews_content');
		    contentDisplay.html(data);
		    contentDisplay.show("slow");
		    contentDisplay.height('180px');
		    
		    
		},
	    
	    error : function (XMLHttpRequest, textStatus, errorThrown) {
			displayMessage("Oops! There was an error in fetching the content!",$('#googlenews_content'));
		}

	});
}

/*
 * 
 * Fetch data from DBPedia
 * 
 */
function fetchTweets(keywordText, date, clusterLabel,eventId){
	
	var URL = "conceptcloud/getTweetForCloud.php";
	
	$.ajax( {
		url : URL,
		global : false,
		type : "GET",
		data : ({
			'term' : keywordText, 
			'date' : date,
			'cluster_label' : clusterLabel,
			'eventid' : $('#curEvent').val() //this is the actual event id
		}),
		dataType : "json", // return type is json
		
		beforeSend: function (xhr) {
			 //update the header
//  	  		 displayHTMLMessage("<h3></h3>" ,$('#tweet_widget_head'));
             displayMessage("Loading the relevant tweets ..",$('#event_content'));
		},

	    complete: function (xhr, textStatus) {
			//displayMessage("");
	    },

		success : function(data) {
	    	var contentDisplay = $('#event_content');
	    	contentDisplay.empty();
	    	var str = "<p class='title'>Distinct tweets for \"" + keywordText + "\" on "+date+" from "+clusterLabel+"</p>";
		    if (data.length!=0){
		    	str += "<ul>";
		    	for(i=0;i<data.length;i++){
		    		str += "<li>" + data[i]+"</li>";
		    	}
			    str+="</ul>";
		    }else{
		    	str += "There are no tweets to be shown!";
		    }
	    	
		    
	    	//this is a json array
	    	contentDisplay.append(str);
		    contentDisplay.show("slow");
		    contentDisplay.height('180px');
		    
		    //TODO update the div with the right heading ?
		},
		error : function (XMLHttpRequest, textStatus, errorThrown) {
			displayMessage("Oops! There was an error in fetching the content!",$('#event_content'));
		}
	});
}

/*
 * 
 * Fetch data from DBPedia
 * 
 */
function fetchDBPedia(keywordText,  eventName){
	
	var dbpediaURL = "dbpedia/getDBPediaInfo.php";
	
	$.ajax( {
		url : dbpediaURL,
		global : false,
		type : "GET",
		data : ({
			keyword : keywordText, 
			event : eventName
		}),
		dataType : "html", // return type is html
		
		beforeSend: function (xhr) {
//			  displayHTMLMessage("<h3>Articles about " + keywordText + " [" + eventName  + "]</h3>" ,$('#dbpedia_widget_head'));
			  displayMessage("Loading relevant articles from Wikipedia ..",$('#db_content'));
		},

	    complete: function (xhr, textStatus) {
			//displayMessage("");
	    },

		success : function(data) {
		    var contentDisplay = $('#db_content');
		    contentDisplay.html(data);
		    contentDisplay.show("slow");
		    contentDisplay.height('180px');
		    
		    //TODO update the div with the right heading ?
		},
	    
	    error : function (XMLHttpRequest, textStatus, errorThrown) {
			displayMessage("Oops! There was an error in fetching the content!",$('#db_content'));
		}
	});
}

/**
 * Display messages
 * @return
 */
function displayMessage(message,messageDiv){
	
	if ( messageDiv === undefined ) {
		messageDiv = $('#loading_messages');
	}

	messageDiv.text(message);
}

/**
 * Display messages but with HTML
 * @return
 */
function displayHTMLMessage(message,messageDiv){
	
	if ( messageDiv === undefined ) {
		messageDiv = $('#loading_messages');
	}

	messageDiv.html(message);
}


/*
 * to center the overlay wrt to the current map center. when the map is zoomed
 * or moved, the overlay is adjusted
 */
function positionOverlay(overlayDiv) {
	var markerOffset = map.fromLatLngToDivPixel(map.getCenter());
	var currentWidth = overlayDiv.width();
	var currentHeight = overlayDiv.height();
	
	//alert(markerOffset + ":" + currentWidth + " : " + currentHeight);
	
	overlayDiv.css( {
		'left' : markerOffset.x - currentWidth/2,
		'top' : markerOffset.y - currentHeight/2
	});
	
}