/**
 * @author sorayad
 */
//<![CDATA[
var c;
var map;
var geocoder;
var markers;
var points;
var allPoints;
var details;
var tz;
/**
* configuration
*/
// this variable will collect the html which will eventually be placed in the side_bar
var live_html    = "";
var public_html  = "";
var private_html = "";
// arrays to hold copies of the markers and html used by the side_bar
var gmarkers    = [];
var windowHtmls = [];
var gicons      = [];
var giconslabel = [];
var gclusters   = [];
var gtitle		= [];


// === Create an associative array of GIcons() ===
var iconLive = new GIcon();
iconLive.image = 'screenings/images/marker_yellow_large.png';
iconLive.iconSize = new GSize(25, 37);
iconLive.iconAnchor = new GPoint(13, 37);
iconLive.infoWindowAnchor = new GPoint(10, 37);
iconLive.transparent = "screenings/images/marker_trans_large.gif";
iconLive.imageMap=[0,0,25,0,25,37,0,37];
//first pair is the top/left corner, the second pair is top/right, the third is bottom/right, and the fourth is bottom/left.

var iconPublic = new GIcon();
iconPublic.image = 'screenings/images/marker_red_medium.png';
iconPublic.iconSize = new GSize(21, 31);
iconPublic.iconAnchor = new GPoint(10, 31);
iconPublic.infoWindowAnchor = new GPoint(10, 31);
iconPublic.transparent = "screenings/images/marker_trans_medium.gif";
iconPublic.imageMap=[0,0,21,0,21,31,0,31];

var iconPrivate = new GIcon();
iconPrivate.image = 'screenings/images/marker_orange_small.png';
iconPrivate.iconSize = new GSize(17, 27);
iconPrivate.iconAnchor = new GPoint(9, 27);
iconPrivate.infoWindowAnchor = new GPoint(9, 27);
iconPrivate.transparent = "screenings/images/marker_trans_small.gif";
iconPrivate.imageMap=[0,0,17,0,17,27,0,27];

iconLiveLabel = {
	"url":"screenings/images/dot.png",
	"anchor":new GPoint(10,10),
	"size":new GSize(6,6)
};
iconPublicLabel = {
	"url":"screenings/images/dot.png",
	"anchor":new GPoint(8,8),
	"size":new GSize(6,6)
};
iconPrivateLabel = {
	"url":"screenings/images/dot.png",
	"anchor":new GPoint(6,7),
	"size":new GSize(5,5)
};

gicons[1] = iconLive;
gicons[2] = iconPublic;
gicons[3] = iconPrivate;

giconslabel[1] = iconLiveLabel;
giconslabel[2] = iconPublicLabel;
giconslabel[3] = iconPrivateLabel;

gtitle[1] = "Live Broadcast Location";
gtitle[2] = "Large Public Venue";
gtitle[3] = "Small Private Venue";


//Create an icon for the clusters
var iconClusterLarge = new GIcon();
iconClusterLarge.image = 'screenings/images/marker_cluster_large.png';
iconClusterLarge.iconSize = new GSize(50, 50);
iconClusterLarge.iconAnchor = new GPoint(24, 20);
iconClusterLarge.infoWindowAnchor = new GPoint(24, 20);

var iconClusterSmall = new GIcon();
iconClusterSmall.image = 'screenings/images/marker_cluster_small.png';
iconClusterSmall.iconSize = new GSize(46, 38);
iconClusterSmall.iconAnchor = new GPoint(23, 19);
iconClusterSmall.infoWindowAnchor = new GPoint(23, 19);

gclusters[2] = iconClusterLarge;
gclusters[3] = iconClusterSmall;


function myclick(sid){
	var request = GXmlHttp.create();
	request.open('GET', 'screenings/event_loc.php?sid='+sid, true);
	request.onreadystatechange = function(){
	    if (request.readyState == 4) {
			if (request.status == 200){
		        var infoText = request.responseText;
				map.openInfoWindowHtml(gmarkers[sid].getLatLng(),infoText);
				document.getElementsByClassName('modal').each(function(link){
					new Control.Modal(link);
				});
			}
	    }
	}
	request.send(null);
}

function sendBack(marker, b){
    return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance * 1000000;
}

function createCluster(type, point, eventType, sid){
    var marker = new GMarker(point, {icon: gclusters[eventType], title:"Multiple events found. Click to zoom in."});
	GEvent.addListener(marker, "click", function() {
		var currZoom = map.getZoom();
		if(currZoom<17){map.setCenter(point, currZoom+1);}
	});
    return marker;
}

function createMarker(type, point, sid, eventType, importance, contact){
	gicons[eventType].label = (contact == 'y') ? giconslabel[eventType] : '';
    var marker = new GMarker(point, {zIndexProcess: sendBack, icon: gicons[eventType], title:gtitle[eventType]+" found. Click to view details."});
    marker.importance = importance;
	GEvent.addListener(marker, "click", function() {
	    var request = GXmlHttp.create();
	    request.open('GET', 'screenings/event_loc.php?sid='+sid, true);
	    request.onreadystatechange = function(){
	        if (request.readyState == 4) {
				if (request.status == 200) {
		            var infoText = request.responseText;
					map.openInfoWindowHtml(point,infoText);
					document.getElementsByClassName('modal').each(function(link){
						new Control.Modal(link);
					});
				}
	        }
	    }
	    request.send(null);
	});
    return marker;
}

function getMarkers(w){
    var request = GXmlHttp.create();
    request.open('GET', 'screenings/event_loc.php?r='+w, true);
    request.onreadystatechange = function(){
        if (request.readyState == 4) {
			if (request.status == 200) {
				var jScript = request.responseText;
				eval(jScript);
				allPoints = points;
				drawMarkers();
			}
        }
    }
    request.send(null);
}

function updateMarkers(c){
	points = allPoints;
    map.clearOverlays();
	drawMarkers(c);	
	if(gmarkers['myPos']){
		map.addOverlay(gmarkers['myPos']);
	}
}

//////////////////////////////
function drawMarkers(c){
	var currZoom = map.getZoom();
    //get the bounds of the viewable area
    var mapBounds = map.getBounds();
    var sw = mapBounds.getSouthWest();
    var ne = mapBounds.getNorthEast();
    var size = mapBounds.toSpan(); //returns GLatLng
    // make a grid that's gridSize^2 in the viewable area
    var gridSize = 50;
    var gridCellSizeLat = size.lat() / gridSize;
    var gridCellSizeLng = size.lng() / gridSize;
    var gridCells = [];
    //loop through the points and assign each one to a grid cell
    for (k in points) {
        var latlng = new GLatLng(points[k].lat, points[k].lng);
        var sid = points[k].sid;
        var eventType = points[k].type;
        var contact = points[k].contact;
        var importance;
        switch (points[k].type) {
            case 1:
                importance = "2";
                break;
            case 2:
            case 3:
                importance = "0";
                break;
        }
		//if((points[k].type != 1)&&(c!='search')&&(currZoom<14)){
		if(points[k].type != 1){
	        //check if it is in the viewable area,
	        //it may not be when zoomed in close
	        if (!mapBounds.contains(latlng)) 
	            continue;
	        
	        //find grid cell it is in:
	        var testBounds = new GLatLngBounds(sw, latlng);
	        var testSize = testBounds.toSpan();
	        var i = Math.ceil(testSize.lat() / gridCellSizeLat);
	        var j = Math.ceil(testSize.lng() / gridCellSizeLng);
	        var cell = i + j;
	        
	        if (typeof gridCells[cell] == 'undefined') {
	            //add it to the grid cell array
	            var cellSW = new GLatLng(sw.lat() + ((i - 1) * gridCellSizeLat), sw.lng() + ((j - 1) * gridCellSizeLng));
	            var cellNE = new GLatLng(cellSW.lat() + gridCellSizeLat, cellSW.lng() + gridCellSizeLng);
	            gridCells[cell] = {
	                GLatLngBounds: new GLatLngBounds(cellSW, cellNE),
	                cluster: false,
	                markers: [],
	                length: 0
	            };
	            
	        }
	        gridCells[cell].length++;
	        
	        //already in cluster mode
	        if (gridCells[cell].cluster) 
	            continue;
	        
	        //only cluster if it has more than 2 points
	        if ((gridCells[cell].markers.length == 4)&&(currZoom<14)) {
	            gridCells[cell].markers = null;
	            gridCells[cell].cluster = true;
	            gridCells[cell].eventType = eventType;
	            gridCells[cell].sid = sid;
	            gridCells[cell].contact = contact;
	        } else {
	            var single = new Array();
	            single['latlng'] = latlng;
	            single['sid'] = sid;
	            single['eventType'] = eventType;
	            single['importance'] = importance;
	            single['contact'] = contact;
	            gridCells[cell].markers.push(single);
	        }
		} else {
			//for events that we don't want clustered
            var marker = createMarker('p', latlng, sid, eventType, importance, contact);
			gmarkers[sid] = marker;
            map.addOverlay(marker);
		}
    }
	
    for (k in gridCells) {
        if (gridCells[k].cluster == true) {
            //create a cluster marker in the center of the grid cell
            var span = gridCells[k].GLatLngBounds.toSpan();
            var sw = gridCells[k].GLatLngBounds.getSouthWest();
			var eventType = gridCells[k].eventType;
			var sid = gridCells[k].sid;
            var marker = createCluster('c', new GLatLng(sw.lat() + (span.lat() / 2), sw.lng() + (span.lng() / 2)),eventType,sid);
            map.addOverlay(marker);
        } else {
            //create the single markers
            if (gridCells[k].markers) {
                for (var i = 0; i < gridCells[k].markers.length; i++) {
                    var marker = createMarker('p', gridCells[k].markers[i]['latlng'], gridCells[k].markers[i]['sid'], gridCells[k].markers[i]['eventType'], gridCells[k].markers[i]['importance'], gridCells[k].markers[i]['contact']);
					gmarkers[gridCells[k].markers[i]['sid']] = marker;
                    map.addOverlay(marker);
                }
            }
        }
    }//k in gridCells
	$('mapLoading').hide();
}


/*
 * Create map overlay to display time zones for official events
 */
function tzOverlay(bounds){
	this.bounds_ = bounds;
}
tzOverlay.prototype = new GOverlay();
tzOverlay.prototype.initialize = function (map){
	var img = document.createElement("img");
	img.src = "screenings/images/map_time_overlay.gif";
	var div = document.createElement("div");
	div.appendChild(img);
	div.style.position = "absolute";
	map.getPane(G_MAP_MAP_PANE).appendChild(div);
	this.map_ = map;
	this.div_ = div;
};
tzOverlay.prototype.remove = function(){
	this.div_.parentNode.removeChild(this.div_);
};
tzOverlay.prototype.copy = function(){
	return new tzOverlay(this.bounds_);
};
tzOverlay.prototype.redraw = function(){
  // Calculate the DIV coordinates of two opposite corners of our bounds to get the size and position of our rectangle
  var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // Now position our DIV based on the DIV coordinates of our bounds
  this.div_.style.width = "461px";
  this.div_.style.height = "347px";
  this.div_.style.left = Math.min(c2.x, c1.x) + "px";
  this.div_.style.top  = Math.min(c2.y, c1.y) + "px";
};

/*
 * onload initialization function
 */
function init(){
	document.getElementsByClassName('moreInfo').each(function(link){
		new Control.Modal(link,{
			opacity: 1, position: 'mouse', width:200, offsetLeft: 20, containerClassName: 'tooltip'
		});
	});
    if (GBrowserIsCompatible()) {
      var i = 0;
		// create the map
		map = new GMap2(document.getElementById("pangeaMap"));
		var mapID = document.getElementById("pangeaMap");
		mapID.style.background = '#99B3CC';
		var mapTypeControl = new GMapTypeControl();
		var mapZoomControl = new GLargeMapControl();
		var topRight = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(5,5));
		var topLeft = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(5,5));
		var botRight = new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(0,0));
		map.addControl(mapTypeControl, topRight);
		map.addControl(mapZoomControl, topLeft);
		map.setCenter(new GLatLng(20,-10), 1);
		map.setMapType(G_NORMAL_MAP);
		geocoder = new GClientGeocoder();
		// event listeners
		GEvent.addListener(map, "maptypechanged", function() {
			var myMapType = map.getCurrentMapType();
			if ((myMapType == G_SATELLITE_TYPE) || (myMapType == G_HYBRID_TYPE)) {
				 mtype = "Satellite";
			  mapID.style.background = '#1e1d57';
			} else if (myMapType == G_MAP_TYPE) {
			  mtype = "Map";
			  mapID.style.background = '#99b3cc';
			}
		});

		GEvent.addListener(map, "zoomend", function(x,y) {
			if(y==1){
				map.clearOverlays();
				drawMarkers();
				map.addOverlay(tz);
			} else {
				updateMarkers();
			}
		});
		// end listeners

	// Create timezone overlay
		var bounds = new GLatLngBounds(new GLatLng(-81, -179),new GLatLng(81, 179));
		tz = new tzOverlay(bounds);
		getMarkers('all');
		map.addOverlay(tz);
	} // end if(GBrowserIsCompatible)	
}// end init()

/**
* search-related functions
*/
function resetSearch(){
	$('mapLoading').show();
	if(gmarkers['myPos']){map.removeOverlay(gmarkers['myPos']); delete gmarkers['myPos']}
	$('results').setStyle({'display': 'none'});
	$('introCopy').setStyle({'display': 'block'});
	map.closeInfoWindow();
	map.setCenter(new GLatLng(20,-10), 1);
	points = gmarkers;
	updateMarkers();
	map.addOverlay(tz);
	return false;
}

function addAddressToMap(response) {
	if (!response || response.Status.code != 200) {
		alert("Your search did not match any locations.");
		$('address').focus();
	} else {
		points = null;
		$('introCopy').setStyle({'display': 'none'});
		$('results').setStyle({'display': 'block'});
		$('results_events').innerHTML = '';
		$('results_search').innerHTML = '<a href="events.php" onclick="resetSearch(); return false"><img src="screenings/images/btn_close_results.gif" alt="Reset" /></a>';
		places = response.Placemark;
		point = new GLatLng(places[0].Point.coordinates[1], places[0].Point.coordinates[0]);
		var bounds = map.getBounds();
		var getVars = 'known='+point.toUrlValue();
		document.getElementById("results_search").innerHTML += '<h3>Results for:</h3>';
		document.getElementById("results_search").innerHTML += '<p>'+places[0].address+'</p>';
		document.getElementById("results_events").innerHTML = 'searching...';
		var request = GXmlHttp.create();
		request.open('GET', 'screenings/event_loc.php?r=search&'+getVars, true);
		request.onreadystatechange = function(){
			if (request.readyState==4){
				if(gmarkers['myPos']){map.removeOverlay(gmarkers['myPos'])}
				map.closeInfoWindow();
				var jScript = request.responseText;
				var bounds = new GLatLngBounds;
				eval(jScript);
				for (i in points){
					var bPoint = new GLatLng(points[i].lat,points[i].lng);
					bounds.extend(bPoint);
				}
				$('results_events').innerHTML = '';
				for (i in details){
					var event_type;
					var filtered_result;
					switch (details[i].event_type_id){
						case 1: event_type = "official"; break;
						case 2: event_type = "public"; break;
						case 3: event_type = "private"; break;
					}
					var contact = (details[i].contact == 'y') ? '_open':'';
					filtered_result = '<div class="'+event_type+contact+'">';
					filtered_result += '<a href="javascript:myclick('+details[i].screenings_id+')">'+ details[i].location_name+'</a>';
					var details_address = (details[i].address) ? details[i].address : '&nbsp;' ;
					filtered_result += '<br /><span>'+details_address+'</span></div>';
					document.getElementById("results_events").innerHTML += filtered_result;
				}
				var zLvl = map.getBoundsZoomLevel(bounds);
				map.setZoom(Math.min(zLvl, 12));
				map.setCenter(bounds.getCenter());
				var resultIcon = new GIcon();
				resultIcon.image = 'http://maps.google.com/intl/en_us/mapfiles/arrow.png';
				resultIcon.iconSize = new GSize(39, 34);
				resultIcon.iconAnchor = new GPoint(6, 20);
				resultIcon.infoWindowAnchor = new GPoint(12, 5);
				updateMarkers('search');
	            gmarkers['myPos'] = new GMarker(point,resultIcon);
				map.addOverlay(gmarkers['myPos']);
			}
		}
		request.send(null);
	}
}
// showLocation() is called when you click on the Search button in the form.
function showLocation(address) {
	$('mapLoading').show();
	geocoder.getLocations(address, addAddressToMap);
}

window.onload = init;
window.onunload = GUnload;
//]]>
