/**
 * Main map functions
 *  Author: Peter Gyorffy
 */
MAPUTILS  = function () {
    
    //global map object
    MAPUTILS.prototype.map;
    MAPUTILS.prototype.counter = 0;
    
    //default map settings
    MAPUTILS.prototype.currentLat =  20.821592;
    MAPUTILS.prototype.currentLng =  -156.356049;
    MAPUTILS.prototype.currentZoom = 10;
    
    MAPUTILS.prototype.mapSizeW = 500;
    MAPUTILS.prototype.mapSizeH = 500;
    
    
    MAPUTILS.prototype.initMap = function() {
        
        //check if map object has been loaded or created
        try{
            document.getElementById('map').innerHTML;
        }catch(e){
            if (this.counter > 60) { 
                alert('Can\'t load map! Can\'t find map object!');
            } else { 
                setTimeout("maputil.initMap()", 1000);                 
            } 
            return false; 
        }
    
        //If gmaps main.js didn't load try to call init again after 60 tries we give up
        if (typeof GMap != "function") { 
            if (this.counter > 60) { 
                document.getElementById('map').innerHTML = 'Can\'t load map! Gmap server timeout! ';
            } else { 
                setTimeout("maputil.initMap()", 1000); 
            } 
            this.counter++; 
            return false; 
        }
        
        //if browser not compatible update map tag with error msg
        if (!GBrowserIsCompatible()) { 
            document.getElementById('map').innerHTML = 'Can\'t load map because your browser is too old or key is invalid!';
            return false;
        }
    
        //init gmaps object
        this.map = new GMap2(document.getElementById("map"));
        
                    
        //set center of the map
        this.map.setCenter(new GLatLng(this.currentLat, this.currentLng), this.currentZoom);  
        //this.map.setMapType(G_HYBRID_MAP);        
        
        //add controls and mouse functions
        this.map.enableDoubleClickZoom();
        this.map.enableContinuousZoom();
        this.map.enableScrollWheelZoom();
        
        //control
        this.map.addControl(new GLargeMapControl3D());
        this.map.addControl(new GMenuMapTypeControl());

        // Add the Terrain Map Type
        this.map.addMapType(G_PHYSICAL_MAP);
        // Create a Hierercical map type control
        
        
        
        var decodeUrl = window.location.hash.substring(1).split('=');
        if(decodeUrl.length>2){
             if(parseInt(decodeUrl[1])) this.currentLat = parseInt(decodeUrl[1]) / 1000000;    
             if(parseInt(decodeUrl[2])) this.currentLng = parseInt(decodeUrl[2]) / 1000000;    
             if(parseInt(decodeUrl[3])) this.currentZoom = parseInt(decodeUrl[3]);
             maputil.map.setCenter(new GLatLng(this.currentLat, this.currentLng), this.currentZoom);      
         }

        GEvent.addListener(maputil.map, "dragend", function() {                      
             maputil.setSiteUrl();
        });
    	
    	GEvent.addListener(maputil.map, "zoomend", function() {                      
            maputil.setSiteUrl();
            marker.clearMarkers();               
            marker.getMarkers(1);
        });
        
        GEvent.addListener(maputil.map, "dragend", function() {                      
            maputil.setSiteUrl();            
            marker.getMarkers();
        });
        
        
        GEvent.addListener(maputil.map, "infowindowopen", function() {                      
            marker.ajax('ajx/getdetails.php?pid='+marker.currentPid, marker.showResults); 
        });
        
        
        marker.getMarkers(1);
        
        
    }
    

    MAPUTILS.prototype.setMapSize = function (){
        document.getElementById("map").style.width = this.mapSizeW + 'px';
        document.getElementById("map").style.height = this.mapSizeH + 'px';
    }
    
    MAPUTILS.prototype.lookUpAddress = function(latlng){  
            geocoder = new GClientGeocoder();
            geocoder.getLocations(latlng, function(addresses) {
                if(addresses.Status.code != 200) {
                    //alert("reverse geocoder failed to find an address for " + latlng.toUrlValue());
                    //latlng.toUrlValue();
                } else { 
                    var result = addresses.Placemark[0];                
                    //var street = result.address.split(',');
                    document.getElementById("mapaddress").value=result.address ; 
                   //document.getElementById("mapcity").value=street[1] ;                   
                }
            });            
        }

       MAPUTILS.prototype.searchAddress = function(str){  
            geocoder = new GClientGeocoder();
            geocoder.getLocations(str, function(addresses) {
                if(addresses.Status.code != 200) {
                    alert("Geocoder failed to find an address for " + str);
                    //latlng.toUrlValue();
                } else { 
                    var result = addresses.Placemark[0];                
                    point = new GLatLng(result.Point.coordinates[1], result.Point.coordinates[0]);
                    maputil.map.setCenter(point);
                    //document.getElementById('latbox').value = point.lat();
                    //document.getElementById('lonbox').value = point.lng();  
                }
            });  
            return false;
        }

	MAPUTILS.prototype.setSiteUrl = function(){              
        	var center = maputil.map.getCenter(); 
        	maputil.mapLink = 'lat=' + Math.round(center.y*1000000)  + '|lng=' + Math.round(center.x*1000000) + '|zoom=' + maputil.map.getZoom();
        window.location = window.location.pathname + '#' +  maputil.mapLink;
	}

}

MARKERS  = function () {
    //this will store the markers
    MARKERS.prototype.markersDb = new Array();        
    
    //store circles
    MARKERS.prototype.markersDb2 = new Array();        
    
    //define icons path
    MARKERS.prototype.markerIconsPath = 'imgs/';  
    
    //store bounds
    MARKERS.prototype.bounds = new GLatLngBounds();      

    MARKERS.prototype.showPointLabel = function (anchor){
        marker.showLabel(anchor.id);
        anchor.style.zIndex=4;                    
        return false;
    }
    
    MARKERS.prototype.hidePointLabel = function (anchor){
        anchor.style.zIndex=1;         
        this.hidePointLabelElement();
        return false;
    }
    
    MARKERS.prototype.hidePointLabelElement = function (){
        try{
            document.getElementById("infoLabel").style.display = 'none'; 
        }catch(e){}
    }
    
    MARKERS.prototype.processMarkeres = function(){   
        var pointsHtml = '';
        
        //go through markersDb and build up a layer for the map
        for(i=0;i<this.markersDb.length;i++) if(this.markersDb[i].length>5){        
            p = this.markersDb[i].split("\|");
            //console.log(p[1] +' '+p[2]);
            //calculate marker positions in pixel
            var pos = maputil.map.fromLatLngToDivPixel(new GLatLng( p[1],  p[2]));
            //extends bounds
            this.bounds.extend(new GLatLng( p[1], p[2]));
            
            //set offset params to center marker to position
            var x = parseInt(pos.x) -11;
            var y = parseInt(pos.y) -38;                    
            
            //create a ne marker achor
            pointsHtml += '<a href="javascript:void(0)" '; 
            
            //set style  and icon
            pointsHtml += 'style="height:39px;width:27px;position:absolute;z-index:1;';                         
            pointsHtml += "background:url('" + this.markerIconsPath + 'marker.png' + "') no-repeat;";              
            pointsHtml += 'top:' + y + 'px;left:' + x + 'px;" ';
            pointsHtml += 'id="marker_' + p[0] + '" ';
            
            //hover text
            pointsHtml += "rel='" + p[3] + ' ' + p[4] + "' ";
                            
            //add events to markers
            pointsHtml += 'onmouseover="marker.showPointLabel(this)" ';
            pointsHtml += 'onmouseout="marker.hidePointLabel(this)" ';
           // pointsHtml += 'onclick="marker.showBubble(this)"';            
            pointsHtml += 'onclick="marker.infoWindow('+p[1]+','+p[2]+',\''+p[0]+'\')"'; 
            pointsHtml += '></a>';            
            
        }  
        
        for(i=0;i<this.markersDb2.length;i++) if(this.markersDb2[i].length>5){        
            p = this.markersDb2[i].split("\|");
            //console.log(p[1] +' '+p[2]);
            //calculate marker positions in pixel
            var pos = maputil.map.fromLatLngToDivPixel(new GLatLng( p[1],  p[2]));
            //extends bounds
            //this.bounds.extend(new GLatLng( p[1], p[2]));
            
            //set offset params to center marker to position
            var x = parseInt(pos.x) -11;
            var y = parseInt(pos.y) -38;                          
            
            //create a ne marker achor
            pointsHtml += '<a href="javascript:void(0)"'; 
            
            //set style  and icon
            pointsHtml += 'style="height:39px;width:27px;position:absolute;z-index:0;';                          
            pointsHtml += "background:url('" + this.markerIconsPath + 'markers/' + p[3]+ '.png' + "') no-repeat center;";              
            pointsHtml += 'top:' + y + 'px;left:' + x + 'px;" ';
            pointsHtml += 'id="marker_' + p[0] + '" ';
            
            //hover text
            pointsHtml += "rel='" + p[4] + "' ";
                            
            //add events to markers
            pointsHtml += 'onmouseover="marker.showPointLabel(this)" ';
            pointsHtml += 'onmouseout="marker.hidePointLabel(this)" ';
            pointsHtml += 'onclick="marker.infoWindow('+p[1]+','+p[2]+','+p[0]+')"';            
            pointsHtml += '></a>';            
            
        }  
        
        
        maputil.map.getPane(G_MAP_MARKER_MOUSE_TARGET_PANE).innerHTML = pointsHtml;
        //console.log(pointsHtml);
    }
    
    MARKERS.prototype.currentPid = 0;
    //MARKERS.prototype.lat = 0;
    //MARKERS.prototype.lng = 0;
    
    MARKERS.prototype.infoWindow = function(lat,lng,pid){ 
        //this will fire a infowindow event which will make an ajax call and show details
        if(pid != this.pid) maputil.map.openInfoWindow(new GLatLng(lat,lng), '<div id="infoWin">Please wait...</div>');
        this.currentPid = pid;
        //this.lat = lat;
        //this.lng = lng;
        //marker.ajax('ajx/getdetails.php?pid='+marker.currentPid, marker.showResults)
        //setTimeout("marker.ajax('ajx/getdetails.php?pid='+marker.currentPid, marker.showResults)", 500);
         
         
    }
    
    MARKERS.prototype.ajax = function(url,action) {    
            try {
        		xmlhttp = window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); 
        	} catch (e) { } 		
        	xmlhttp.onreadystatechange = action; 		
        	xmlhttp.open("GET", url, true); 		
        	xmlhttp.send(null);          
    }
    
    
    MARKERS.prototype.showResults = function(){ 
        if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) {  
            //console.log( xmlhttp.responseText);         
            document.getElementById('infoWin').innerHTML = xmlhttp.responseText;   
            //maputil.map.openInfoWindowHtml(new GLatLng(marker.lat,marker.lng), xmlhttp.responseText);
            
            if(xmlhttp.responseText.length>0){    			
               // document.getElementById('infoWin').innerHTML = xmlhttp.responseText;    
    			var ra = xmlhttp.responseText.split('\n');
    			var inJs = false;
    			var js = '';			
    			for(i=0; i<ra.length; i++) {
    				if(ra[i].match(/<\/script/i)) inJs = false;
    				if(inJs) js += ra[i]+"\n";
    				if(ra[i].match(/<script/i)) inJs = true;
    			}

    			try {
    				eval(js);
    			} catch(e) {
    				console.log(e);
    			}
            }
        }    
    }
    
    
    MARKERS.prototype.clearMarkers = function(){           
        var element = maputil.map.getPane(G_MAP_MARKER_MOUSE_TARGET_PANE);  
        while (element.firstChild) {
            element.removeChild(element.firstChild);        
        }                  
    }
    
    MARKERS.prototype.showLabel = function (markerObj){              
        //try to get label element if not in the body add it
        try{
            document.getElementById('infoLabel').innerHTML;
            var label = document.getElementById('infoLabel');        
        }catch(e){
            var label = document.createElement('div');
            label.setAttribute('id','infoLabel');             
            label.onclick = function(){marker.hidePointLabelElement()}
            document.body.appendChild(label);            
        }
                
        //calculate absolute postion of the label
        var m = document.getElementById(markerObj); 
        var mapPos = this.findPos(document.getElementById('map'));
        var lY = (maputil.map.getSize().height - (maputil.map.getSize().height/2 + maputil.map.fromLatLngToDivPixel(maputil.map.getCenter()).y - parseInt(m.style.top))) + mapPos[1] ;
        var lX = (maputil.map.getSize().width - (maputil.map.getSize().width/2 + maputil.map.fromLatLngToDivPixel(maputil.map.getCenter()).x - parseInt(m.style.left))) + mapPos[0] ;
        
        //check if label in map
        if(lY<mapPos[1]+20) return false;
        if(lX<mapPos[0]+20) return false;        
        if(lY>(document.getElementById('map').offsetHeight+mapPos[1])) return false;
        if(lX>(document.getElementById('map').offsetWidth+mapPos[0])) return false;
        
        //show label
        label.style.display='block';
        
        //set attributes
        //if you need to move the label offset you can change it here
        label.style.top = (lY - 16)  + 'px';
        label.style.left = (lX + 22) + 'px';    
        label.innerHTML = '<span class="mapBubbleTxt">' + m.rel + '</span><span class="mapBubbleEnd"></span>';         
    }
    
    
    
    MARKERS.prototype.hideBubble = function (){ 
        try{
            document.getElementById('map_bubble').style.display = 'none';             
        }catch(e){}
    }

    MARKERS.prototype.findPos = function(obj) {        
        if (obj.offsetParent) {
            var curleft = obj.offsetLeft
            var curtop = obj.offsetTop
            while (obj = obj.offsetParent) {                    
                curleft += obj.offsetLeft
                curtop += obj.offsetTop
            }
            return [curleft,curtop];
        }    
    }
    
    MARKERS.prototype.getZoomLevel = function() {
        return maputil.map.getBoundsZoomLevel(marker.bounds);
    }
    
    MARKERS.prototype.getMarkerCenter = function() {
        return marker.bounds.getCenter();
    }    
    
    var maxx = 0, maxy = 0, minx = 0, miny = 0;
    
    MARKERS.prototype.getMarkers = function (force){
       
        var bounds = maputil.map.getBounds();
         yt = bounds.getNorthEast().y.toFixed(3);
         xt = bounds.getNorthEast().x.toFixed(3);
         yb = bounds.getSouthWest().y.toFixed(3);
         xb = bounds.getSouthWest().x.toFixed(3);         
        //console.log('yt:'  + yt + ' yb:'  + yb + ' xt:'  + xt + ' xb:'  + xb);
        if(xt>maxx || yt>maxy || xb<minx || yb<miny || force > 0){
            var detx = xt - xb; 
            var dety = yt - yb;    
            
            maxx = (xt*1 + detx).toFixed(3)*1;            
            maxy = (yt*1 + dety).toFixed(3)*1;
            minx = (xb*1 - detx).toFixed(3)*1;            
            miny = (yb*1 - dety).toFixed(3)*1;  
           
            if(maputil.map.getZoom()>16){maxy += 0.01;maxx += 0.01;miny -= 0.01;minx -= 0.01;  } 
            
            var getUrl = "ajx/getpoints.php?yt=" + maxy.toFixed(3) + "&xt=" + maxx.toFixed(3) + "&xb=" + minx.toFixed(3) + "&yb=" + miny.toFixed(3) +"&zoom=" +  maputil.map.getZoom();
            if(force>1) getUrl += '&nocache=1'
           
        	xmlhttp2 = window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP");     		
        	
            xmlhttp2.onreadystatechange =  this.downloadMarkeres;
            xmlhttp2.open("GET", getUrl, true); 		    	
            xmlhttp2.send(null);
            
        }
            
    }    
    
    MARKERS.prototype.downloadMarkeres = function(){
        if ((xmlhttp2.readyState == 4) && (xmlhttp2.status == 200)) { 	
            var rows = xmlhttp2.responseText.split("\n");
            marker.markersDb2 = rows;
            marker.processMarkeres();
            var tmp = '';
            for(i=0;i<rows.length-1;i++){
                var row = rows[i].split("\|");
                tmp += '<li ';
                tmp += 'onmouseover="marker.showPointLabel(document.getElementById(\'marker_'+row[0]+'\'))" ';
                tmp += 'onmouseout="marker.hidePointLabel(document.getElementById(\'marker_'+row[0]+'\'))" ';
                tmp += 'onclick="maputil.map.setCenter(new GLatLng('+row[1]+','+row[2]+'),16);marker.processMarkeres();marker.infoWindow('+row[1]+','+row[2]+','+row[0]+')" ';
                tmp += '>' + row[4]+ ' <span>' + row[5] +'</span></li>';
            }
            document.getElementById('mostShared').innerHTML = tmp;
        }
    }
   
}

STREETVIEW  = function () {
    
    STREETVIEW.prototype.lat = 0;
    STREETVIEW.prototype.lng = 0;
    
    STREETVIEW.prototype.yaw = 0;
    STREETVIEW.prototype.pitch = 0;
    STREETVIEW.prototype.zoom = 0;

    STREETVIEW.prototype.isset = false;
    STREETVIEW.prototype.isOverlayset = false;
    STREETVIEW.prototype.marker = null;
    
    STREETVIEW.prototype.init = function() {
        if(this.data.length<1) return false;
        streetview.isset = true;
	    this.load();
    }

    STREETVIEW.prototype.load = function() {
    	var location = new GLatLng(streetview.lat, streetview.lng);
        this.yaw = this.yaw;
        var street = new GStreetviewClient();
        street.getNearestPanoramaLatLng(location,streetview.show);
       // if(!this.isOverlayset) this.addSvOverlay();
    }
    
    STREETVIEW.prototype.show = function(latlng) { 
       if(latlng == null){
           document.getElementById("streetview").innerHTML = "Custom Street View Not Available";
           return false;
       }
       
       var pov1 = { yaw: streetview.yaw, pitch: streetview.pitch, zoom: streetview.zoom }   
       panoramaOptions = { latlng:latlng, pov:pov1 };
       document.getElementById("streetview").innerHTML = "";
        var myPano = new GStreetviewPanorama(document.getElementById("streetview"), panoramaOptions);
       
        GEvent.addListener(myPano, 'initialized', function(pano) {
            document.getElementById("streetviewlat").value = pano.latlng.lat();
            document.getElementById("streetviewlng").value = pano.latlng.lng();            
        });

        GEvent.addListener(myPano, 'yawchanged', function(newyaw){
            document.getElementById("streetviewyaw").value = newyaw;
        });

        GEvent.addListener(myPano, 'pitchchanged', function(newpitch) {
            document.getElementById("streetviewpitch").value = newpitch;
          
        });

        GEvent.addListener(myPano, 'zoomchanged', function(newzoom) {
            document.getElementById("streetviewzoom").value = newzoom;
        });
        
        
        // document.getElementById("streetview").style.display = "block";
         //document.getElementById("streetview").innerHTML = '';
         //if(streetview.marker != null) streetview.marker.setLatLng(latlng);
         
    }
    
    STREETVIEW.prototype.addSvOverlay = function() {
        maputil.map.addOverlay(new GStreetviewOverlay());
        this.isOverlayset = true;
        this.marker = new GMarker(maputil.map.getCenter(), { draggable: true})
        maputil.map.addOverlay(this.marker);

        //marker.enableDragging();

        GEvent.addListener(this.marker, "dragend", function(latlng){
            streetview.data = new Array(latlng.y,latlng.x,0);
	        streetview.load();
            //console.log(latlng);
        });
        
    } 
    
    STREETVIEW.prototype.tryStreetView = function(lat,lng) { 
        var location = new GLatLng(lat,lng);
        var street = new GStreetviewClient();
        street.getNearestPanoramaLatLng(location,streetview.showthumb);
    }
    
    STREETVIEW.prototype.showLayer = function() { 
        document.getElementById("streetview").style.display = "block";
    }
    
    STREETVIEW.prototype.showthumb = function(latlng) { 
       if(latlng == null){
           //document.getElementById("streetview").innerHTML = "Street View Not Available";
           return false;
       }
       
       document.getElementById("streetviewBtn").style.display = "block";
       
       panoramaOptions = { latlng:latlng};
       document.getElementById("streetview").innerHTML = "";
        var myPano = new GStreetviewPanorama(document.getElementById("streetview"), panoramaOptions);
    }
}

var streetview = new STREETVIEW;


//create maputil class
var maputil = new MAPUTILS;
//create markers class
var marker = new MARKERS;


//after page has been closed try to free up memory
window.onunload = function(){
    try{
        GUnload();
    }catch(e){}
}