// Set up namespace
var $A = YAHOO.util.Anim;
var $D = YAHOO.util.Dom;
var $E = YAHOO.util.Event;
var $M = YAHOO.util.Motion
var $TT = YAHOO.widget.Tooltip;
var $ = $D.get;

_log = function(type,args) {
  var arg, self = arguments.callee;
  for (var i = 1; i < args.length; i++) {
    arg = arguments[i];
    if (window.console)
      (window.console[type] || window.console.log)(arg);
    else if (window.opera) { window.opera.postError(arg); }
    else if (window.Log) {
       self._logger = self._logger || new Log(Log.INFO, Log.popupLogger);
       self._logger[type](arg);
    }
  }
}

function _error(arguments) { _log("error", arguments); }
function _warn(arguments)  { _log("warn",  arguments); }
function _info(arguments)  { _log("info",  arguments); }
function _debug(arguments) { _log("debug", arguments); }

function purge(d) { var a = d.attributes, i, l, n; if (a) { l = a.length; for (i = 0; i < l; i += 1) { n = a[i].name; if (typeof d[n] === 'function') { d[n] = null; } } } a = d.childNodes; if (a) { l = a.length; for (i = 0; i < l; i += 1) { purge(d.childNodes[i]); } } }

$E.addListener(window, "load", function() {
	
	$E.addListener("geoSyncOrange", "click", function() { geoSync('Orange, CA');});
	$E.addListener("geoSyncLA", "click", function() { geoSync('Los Angeles, CA');});
	$E.addListener("geoSyncIrvine", "click", function() { geoSync('Irvine, CA');});
    
    $E.addListener("geoquery", "blur", function() { if(this.value==''){this.value='Elsewhere...';} });
    $E.addListener("geoquery", "focus", function() { if(this.value=='Elsewhere...'){this.value='';} });
    $E.addListener("geoquery", "change", function() { addGeocode(); });
    
    $E.addListener("localquery", "blur", function() { if(this.value==''){this.value='Search local...';} });
    $E.addListener("localquery", "focus", function() { if(this.value=='Search local...'){this.value='';} });
    $E.addListener("localquery", "change", function() { addLocal(); });
        
    var tooltTipIds = ["plotTraffic","addTraffic","clearMap","geoSyncIrvine","geoSyncOrange","geoSyncLA","geoquery","localquery"];
	var myTooltip = new $TT("MyTooltips", { 
		effect:{effect:YAHOO.widget.ContainerEffect.FADE,duration:0.20}, context:tooltTipIds, showDelay:150, hidedelay:100 } );
	purge(myTooltip);
		
    // Globals
    var xmlhttp = false;
    var gmap; // google map
    var ymap; // yahoo map
    var appid = "phuson999"; // yahoo API id
    var gmarkers = []; // array of markers in order to list it out on the sidebar
    var ymarkers = [];
    var iconType = "blue"; // default iconType if none has been stated
    /* Set the icon properties that will be marked on Google map */
    var smIcon = new GIcon();
    	smIcon.shadow = "http://www.phuson.com/projects/ajax/icons/shadow.png";
    	smIcon.iconSize = new GSize(12, 20);
    	smIcon.shadowSize = new GSize(22, 20);
    	smIcon.iconAnchor = new GPoint(6, 20);
    	smIcon.infoWindowAnchor = new GPoint(5, 8);
    /* Set the icon properties that will be marked on Yahoo map */
	var myImage = new YImage();
	    myImage.size = new YSize(12,20);
	    myImage.offsetSmartWindow = new YCoordPoint(5,14);
        
    /**	METHOD - initXMLHTTPRequest - check to see if the browser is compatible and if IE has ActiveX object
        */
    initXMLHTTPRequest = function() {
    	if (window.XMLHttpRequest) // check other browsers XMLHTTP Request object
    	{
    		xmlhttp = new XMLHttpRequest();
    		xmlhttp.overrideMimeType('text/xml');
    	} else if (window.ActiveXObject)  // check IE ActiveX object
    	{
    		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    	}
    	return xmlhttp;
    }

    /**	METHOD - sendRequest - sends request to Yahoo API or my own PHP file
    	PARAM -  target : string - the target URI of the proxy php
    	PARAM - service : string - what kind of service the user is requesting
         */
    sendRequest = function(target, service) {
    	if (target == "http://www.phuson.com/projects/ajax/read.php") {
    		var url = 'myproxy.php?' + encodeURI(target);
    	}
    	else {
    		var url = 'yahooproxy.php?' + encodeURI(target);
    	}
        xmlhttp.open('GET', url, true);
        xmlhttp.onreadystatechange = function() {
            if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
              //document.getElementById('result').innerHTML = '';
              document.getElementById('loading').innerHTML = "<div id='loadingText' style='visibility: hidden'>Loading...</div>";
                    parseResult(xmlhttp.responseText, service);
                    // SEE THE INNER XML - document.getElementById('result').innerHTML = xmlhttp.responseText;
            } else {
            //document.getElementById('result').innerHTML = "Loading...";
            document.getElementById('loading').innerHTML = "<div id='loadingText' style='visibility: show'>Loading...</div>";
            }
        };
        xmlhttp.send(null);
    }

    /**	METHOD - parseResult - parse the result XML file and create map markers
    	PARAM -  parseMeString : string - XML stream
    	PARAM - service : string - what kind of service the user is requesting
        */
    parseResult = function(parseMeString, service) {
    	var parser = new DOMImplementation();
    	var domDoc = parser.loadXML(parseMeString);
    	if (domDoc == null) {
    		alert("There was a problem parsing search results.");
    		return;
    	}
    	var docRoot = domDoc.getDocumentElement();
    	switch (service) {
            case "traffic":
                var items = docRoot.getElementsByTagName("Result");
        		for (var i =0; i < items.length; i++) {
        			var lat = items.item(i).getElementsByTagName("Latitude").item(0).getFirstChild().getNodeValue();
        			var lon = items.item(i).getElementsByTagName("Longitude").item(0).getFirstChild().getNodeValue();
        			var title = items.item(i).getElementsByTagName("Title").item(0).getFirstChild().getNodeValue();
        			var descr = items.item(i).getElementsByTagName("Description").item(0).getFirstChild().getNodeValue();
        			var severity = items.item(i).getElementsByTagName("Severity").item(0).getFirstChild().getNodeValue();
        			var type = items.item(i).getAttribute("type");
        			var smart = "<span style='color: red; font-size: 80%;'><strong>" + title + "</strong><br />" + "Type: " + type +  "<br />" + "Severity: " + severity + "<br />" + descr +"</span>";
        			iconType = "accident";
        			gmap.addOverlay(createGoogleMarker (new GLatLng(parseFloat(lat), parseFloat(lon)), i, smart, iconType));	
	      			ymap.addOverlay(createYahooMarker (new YGeoPoint(parseFloat(lat), parseFloat(lon)), i, smart, iconType));
	      			$("sbInstruction").style.visibility = "visible";
        		}
                break;
            case "local":
                var items = docRoot.getElementsByTagName("Result");
        		for (var i =0; i < items.length; i++) {
        			var lat = items.item(i).getElementsByTagName("Latitude").item(0).getFirstChild().getNodeValue();
        			var lon = items.item(i).getElementsByTagName("Longitude").item(0).getFirstChild().getNodeValue();
        			var title = items.item(i).getElementsByTagName("Title").item(0).getFirstChild().getNodeValue();
        			var ratings = items.item(i).getElementsByTagName("Rating");
        			if (ratings.item(0).getElementsByTagName("AverageRating").item(0).getFirstChild() != null)
        			{
        				var avRat = ratings.item(0).getElementsByTagName("AverageRating").item(0).getFirstChild().getNodeValue();
        			} else { avRat = "n/a"}
        			if (ratings.item(0).getElementsByTagName("TotalRatings").item(0).getFirstChild() != null)
        			{
        				var totRat = ratings.item(0).getElementsByTagName("TotalRatings").item(0).getFirstChild().getNodeValue();
        			} else { avRat = "n/a"}
        			var url = items.item(i).getElementsByTagName("Url").item(0).getFirstChild().getNodeValue();
        			var smart = "<span style='color: #666; font-size: 80%; word-wrap: break-word;'><strong>" + title + "</strong><br />" + "Average Rating: " + avRat +  "<br />" + "Total Ratings: " + totRat + "<br /><a href='" + url + "' title='' target='_blank' style='font-size: 80%'>[More Info]</a></span>";
        			iconType = "white"; // define the iconType before passing it to overlay
        			gmap.addOverlay(createGoogleMarker (new GLatLng(parseFloat(lat), parseFloat(lon)), i, smart, iconType));
	      			ymap.addOverlay(createYahooMarker (new YGeoPoint(parseFloat(lat), parseFloat(lon)), i, smart, iconType));
	      			$("sbInstruction").style.visibility = "visible";	
        		}
                break;
            case "geocode":
        		var items = docRoot.getElementsByTagName("Result");
        		for (var i =0; i < items.length; i++) {
        			var lat = items.item(i).getElementsByTagName("Latitude").item(0).getFirstChild().getNodeValue();
        			var lon = items.item(i).getElementsByTagName("Longitude").item(0).getFirstChild().getNodeValue();
        			gmap.panTo(new GLatLng(parseFloat(lat), parseFloat(lon)));
        			ymap.panToLatLon(new YGeoPoint(parseFloat(lat), parseFloat(lon)));
        		}
                break;
            case "geosync":
        		var items = docRoot.getElementsByTagName("Result");
        		for (var i =0; i < items.length; i++) {
        			var lat = items.item(i).getElementsByTagName("Latitude").item(0).getFirstChild().getNodeValue();
        			var lon = items.item(i).getElementsByTagName("Longitude").item(0).getFirstChild().getNodeValue();
        			gmap.panTo(new GLatLng(parseFloat(lat), parseFloat(lon)));
        			ymap.panToLatLon(new YGeoPoint(parseFloat(lat), parseFloat(lon)));
        		}	
                break;
            case "plottraffic":
                var items = docRoot.getElementsByTagName("Result");
        		for (var i =0; i < items.length; i++) {
        			var speed = items.item(i).getElementsByTagName("Speed").item(0).getFirstChild().getNodeValue();
        			var lat = items.item(i).getElementsByTagName("Latitude").item(0).getFirstChild().getNodeValue();
        			var lon = items.item(i).getElementsByTagName("Longitude").item(0).getFirstChild().getNodeValue();
        			var time = items.item(i).getElementsByTagName("Time").item(0).getFirstChild().getNodeValue();
        			var street = items.item(i).getElementsByTagName("Street").item(0).getFirstChild().getNodeValue();
        			var direction = items.item(i).getElementsByTagName("Direction").item(0).getFirstChild().getNodeValue();

        			var smart = "<span style='color: #666; font-size: 80%;'><strong>Speed: " + speed +"MPH</strong><br /><strong>Time:</strong> " + time + "<br /><strong>Lat:</strong> " + lat + "&nbsp;&nbsp;<strong>Long:</strong> " + lon + "<br /><strong>Street:</strong> " + street + "<br /><strong>Direction:</strong> " + direction + "</span>";

        			var speedInt = parseInt(speed);
        			if (speedInt <= 25) { iconType = "red";} 
        				else if (speedInt < 50) {	iconType = "orange";	} 
        				else { iconType = "green"; }
        			gmap.addOverlay(createGoogleMarker (new GLatLng(parseFloat(lat), parseFloat(lon)), i, smart, iconType));
        			ymap.addOverlay(createYahooMarker (new YGeoPoint(parseFloat(lat), parseFloat(lon)), i, smart, iconType));
        			$("sbInstruction").style.visibility = "visible";
        		}
                break;
            default:
                break;
        }
    	// list the markers on the side
    	listMarkers();
    }

    /**	METHOD - createMarker - create marker on map according the params
    	PARAM -  point : string - the GPoint maker point object that contains the latitude and longitude
    	PARAM - index : string - index (not in used)
    	PARAM -  msg : string - the marker's attached message
    	PARAM - iconType : string - type of icon that will be drawn
        */
    createGoogleMarker = function(point, index, msg, iconType) {
    	smIcon.image = "http://www.phuson.com/projects/ajax/icons/" + iconType + ".png";
    	var marker = new GMarker(point, smIcon);
    	marker.iconType = iconType;
    	marker.msg = "<span style='white-space:nowrap;' class='markerMsg'>"+msg+"</span>";
    	// Show this marker's index in the info window when it is clicked.
    	GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(marker.msg)});
    	gmarkers.push(marker); // push marker into array
    	return marker;
    }
    
    createYahooMarker = function(geopoint, num, msg, iconType) {
	  myImage.src = "http://www.phuson.com/projects/ajax/icons/" + iconType + ".png";
	  var marker = new YMarker(geopoint,myImage);
	  marker.Lat = geopoint.Lat;
	  marker.Lon = geopoint.Lon;
	  marker.msg = "<span style='white-space:nowrap;' class='markerMsg'>"+msg+"</span>";
	  //var label= "<img src=http://us.i1.yimg.com/us.yimg.com/i/us/ls/gr/" + num + ".gif>";
	  var label = "";
	  marker.addLabel(label);
	  YEvent.Capture(marker,EventsList.MouseClick, function() { marker.openSmartWindow(marker.msg) });
	  ymarkers.push(marker);
	  return marker;
	}

    /**	METHOD - addTraffic - add traffic or accident from Yahoo API
        */
    $E.addListener("addTraffic", "click", addTraffic = function() {
    	var center = gmap.getCenter();
    	var zoomLevel = 5; 	
    	var uri = "http://api.local.yahoo.com/MapsService/V1/trafficData?appid=" + appid + "&latitude=" + center.y + "&longitude=" + center.x + "&radius=" + zoomLevel + "&severity=3";
    	sendRequest(uri, "traffic");
    }
    );

    /**	METHOD - addLocal - add local search query from Yahoo API
        */
    $E.addListener("addLocalButton", "click", addLocal = function() {
    	var center = gmap.getCenter();
    	var zoomLevel = gmap.getZoom() * 5; 
    	var query = document.getElementById("localquery").value;
    	var uri = "http://api.local.yahoo.com/LocalSearchService/V3/localSearch?appid=" + appid + "&query=" + query + "&latitude=" + center.y + "&longitude=" + center.x + "&radius=" + zoomLevel + "&results=" + 20;
    	sendRequest(uri, "local");
    });

    /**	METHOD - addGeocode - Geocode an address or location from Yahoo Geocode API (not in used)
        */
    $E.addListener("addGeocodeButton", "click", addGeocode = function() {
    	var query = document.getElementById("geoquery").value;
    	var uri = "http://api.local.yahoo.com/MapsService/V1/geocode?appid=" + appid + "&location=" + query;
    	sendRequest(uri, "geocode");
    });

    /**	METHOD - geoSync - Sync the map up with a given address or location using Yahoo! Geocode API
    					Was used to sync up Google and Yahoo maps.
    	PARAM -  addr : string - the given query value
        */
    geoSync = function(addr) {
    	var query = addr;
    	var uri = "http://api.local.yahoo.com/MapsService/V1/geocode?appid=" + appid + "&location=" + query;
    	sendRequest(uri, "geosync");
    }

    /**	METHOD - geoSync - Plot custom input values from MySQL database - data sources coming from mobile devices
        */
    $E.addListener("plotTraffic", "click", plotTraffic = function() {
    	//clearMap();
    	var uri = "http://www.phuson.com/projects/ajax/read.php";
    	sendRequest(uri, "plottraffic");
    });

    /**	METHOD - Array.prototype.clear - Prototype the Array method to add clearing functionality
        */
    Array.prototype.clear = function() {
        return this.splice(0,this.length); // clear array
    }

    /**	METHOD - clearMap - Clear the map and sidebar of markers and their info
        */
    $E.addListener("clearMap", "click", (clearMap = function() {
    	gmap.clearOverlays();
    	ymap.removeMarkersAll();
    	document.getElementById("sb").innerHTML = "<center>-- Empty --</center>"; // clear the sidebar list and replace it with Empty
    	gmarkers.clear(); // clear the array
    	ymarkers.clear(); // clear the array
    	$("sbInstruction").style.visibility = "hidden";
    }));
    


	syncMaps = function(e) {
		if (e == "y2g") {
			var center = ymap.getCenterLatLon();
			gmap.panTo(new GLatLng(parseFloat(center.Lat), parseFloat(center.Lon)));
		} else if (e == "g2y") {
			var center = gmap.getCenter();
			ymap.panToLatLon(new YGeoPoint(parseFloat(center.y), parseFloat(center.x)));
		}
		center = null;
	};
	
    /**	METHOD - act -  Picks up the click and opens the corresponding sidebar window
        */
    act = function(i) {
    	gmarkers[i].openInfoWindowHtml(gmarkers[i].msg);
    	ymap.panToLatLon(new YGeoPoint(ymarkers[i].Lat,ymarkers[i].Lon)); //fix for yahoo! map going blank
    	ymarkers[i].openSmartWindow(ymarkers[i].msg);
    }

    /**	METHOD - listMarkers -  List out the markers on the sidebar from the array
        */
    listMarkers = function() {
    	// this variable will collect the html which will eventually be placed in the sidebar
    	var sidebar_html = "";
    	// scan through the gmarkers[] array assembling the sidebar html
    	for (var i=0; i < gmarkers.length; i++) {
    		//sidebar_html += '<div class="sideItem" onMouseOver="javascript:act(' + i + ')"><span style="font-family: Georgia; font-size: 120%;">' + (i+1) + '</span>. <a href="javascript:act(' + i + ')">' + gmarkers[i].msg + '</a></div>';
    		sidebar_html += '<div class="sideItem" onClick="javascript:act(' + i + ')"><span style="font-family: Georgia; font-size: 120%;">' + (i+1) + '</span>. ' + gmarkers[i].msg + '</div>';
    	}
    	document.getElementById("sb").innerHTML = sidebar_html; // put the assembled sidebar_html contents into the sidebar div
    }
	  

	initXMLHTTPRequest();
	// init google map
	gmap = new GMap2(document.getElementById("gmap"));
	gmap.addControl(new GLargeMapControl());
	//gmap.addControl(new GMapTypeControl());
	gmap.setCenter(new GLatLng(37.34, -122.02), 11);
	
	//init Yahoo! map
	ymap = new YMap(document.getElementById("ymap"));
	//add controls
	ymap.addPanControl();
	ymap.addZoomLong();
	// set type to REG
	ymap.setMapType(YAHOO_MAP_REG);
	// Display the map centered on a latitude and longitude 
	ymap.drawZoomAndCenter(new YGeoPoint(37.40,-122.008), 7);
	
	//Get valid map types, returns array [YAHOO_MAP_REG, YAHOO_MAP_SAT, YAHOO_MAP_HYB]
	var myMapTypes = ymap.getMapTypes(); 
	
	// point to coordinate given and clear map
	geoSync('Irvine, CA'); clearMap();
    document.getElementById("sb").innerHTML = "<center>-- Empty --</center>";
    
    // add event to sync maps from Yahoo! to Google
	YEvent.Capture(ymap, EventsList.endPan, function() { syncMaps("y2g");});
	// add event to sync maps from Google to Yahoo!
	GEvent.addListener(gmap, 'dragend', function() { syncMaps("g2y");});
	
	$("sbInstruction").style.visibility = "hidden";
});

$E.addListener(window, "unload", function() {GUnload(); purge(document);});
