// global vars for mosaic ol
var map = null;

var default_marker_icon = false;

var on_print_mode = false;

var markers;
var current_tooltip_marker = null;
var drag_control = null;
var vector_layer = null;
var marker_layer = null;
var route_layer  = null;


function initMosaic()
{
	Mosaic.enableZoomBar(true);
  // important to set server url BEFORE setting base map, because configs are retrieved from server url before
  Mosaic.setMapServerURL(Sensus.mapUrl);    
  Mosaic.setBaseMap(Sensus.mapName);      
	//Mosaic.insertMap(configureMap);	
  Mosaic.insertMap(function (argMap) {configureMap(argMap);} );	
  //setTimeout(' addCallback("zoom", function(evt) {alert("zoomend");}); ', 1000);
  //setTimeout(' addCallback("move", function(evt) {alert("move");}); ', 1000);
  //setTimeout(' addEventCallback("popupopen" , function(evt) {alert("popup open"); }); ', 1000);
  //setTimeout(' addEventCallback("popupclose", function(evt) {alert("popup close");}); ', 1000);
}


//Einem Breitengrad entsprechen etwa pi · 12714 km / 360  111 km.
//Einem Längengrad entsprechen etwa pi · 12756 km · cos f / 360 (f  geografische Breite), in unseren Breiten (Berlin) also etwa 64.75 km.
function getCenterGeo() {
  var bounds = getCurrentMapExtent();
  var center = bounds.getCenterLonLat();
  var scale = 111000 * Math.abs(bounds.top - bounds.bottom);  
  return {"lon": center.lon, "lat": center.lat, "scale": scale };
}

function mapExport(format) {
  var width=800;
  var height=560;
  format = "jpg";

//  var geo = getCenterGeo();
  var bounds = getCurrentMapExtent();
    
//var url = Sensus.urlMake("content/export?width="+width+"&height="+height+"&lon="+geo.lon+"&lat="+geo.lat+"&scale="+geo.scale+"&format="+format);
    
  //var url = "http://service.ikinokta.com/geomap/GetMap?width="+width+"&height="+height+"&longitude="+geo.lon+"&latitude="+geo.lat+"&scale="+geo.scale+"&type="+format+"&theme=http%3A%2F%2Fservice.ikinokta.com%2Fmosaic%2FMosaic.getTheme%3Fsource%3DOSM%26data%3Dhttp-ikinokta%26view%3Dlinear%26layout%3Dikinokta%26gui%3Dsimple%26overlay%3Dscalebar";
  
  var url = Sensus.urlMake("content/export?bbox="+bounds.left+","+bounds.bottom+","+bounds.right+","+bounds.top+"&height="+height+"&width="+width);
  
  exp = window.open(url, "exp", "width="+width+",height="+height);
  if (window.focus) exp.focus();
  //return false;
}


function addEventCallback(action, func) { // "moveend", "zoomend", poi-click  

  if (action == "popupopen") {
    map.events.register(action, map, func);
    return;
  }
  if (action == "popupclose") {
    map.events.register(action, map, func);
    return;  
  }

  if (action == "move") action = "moveend";
  if (action == "zoom") action = "zoomend";
  map.events.register(action, map, func);
}

// popup that uses harita specific placement
HaritaPopup = OpenLayers.Class(OpenLayers.Popup.Anchored, {

    initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
                        closeBoxCallback) {
        var newArguments = [id, lonlat, contentSize, contentHTML, anchor, closeBox, closeBoxCallback];
        OpenLayers.Popup.Anchored.prototype.initialize.apply(this, newArguments);
    },

    calculateNewPx:function(px) {
        var newPx = px.offset(this.anchor.offset);
            
        //use contentSize if size is not already set
        var size = this.size || this.contentSize;
        
        var top = (this.relativePosition.charAt(0) == 't');
        newPx.y += (top) ? -size.h + this.anchor.size.h : 0;
            
        var left = (this.relativePosition.charAt(1) == 'l');
        newPx.x += (left) ? -size.w : this.anchor.size.w;

        return newPx;   
    },

    CLASS_NAME: "HaritaPopup"
});



function setMapDim(w,h) {
  var mt = document.getElementById('map');
  mt.style.width  = w + 'px';
  mt.style.height = h + 'px';
/*  // needed for ie6
  var t = document.getElementById('table');
  t.style.width  = w + 'px';
  t.style.height = h + 'px';
*/  
}

function setMapFormat(str) {
  //russian
  ar = 1.41; // aspect ratio (real: 1.41, but because of borders)
  base = 600;
  factor = 1.5; // in reality 2, but then ie6 cuts again :(

var h=getInnerHeight();
var w=getInnerWidth(); 
var arMonitor = 16/10; // worsest case
 
  switch (str) {
    case 'portrait' : { setMapDim(parseInt(h/0.75), h); break;}
    case 'landscape': { setMapDim(parseInt(h*1.6) , h); break;}
  
    case 'a4h': { setMapDim(base     , base*ar); break;}
    case 'a4q': { setMapDim(base*ar  ,base); break;}
    case 'a3h': { setMapDim(base*factor   , base*factor*ar); break;}
    case 'a3q': { setMapDim(base*factor*ar, base*factor); break;}
  }
  //correctMapHeight();
  mapUpdateSize();  
}

function focusPrint() {
		document.getElementById("map").focus();
    window.print();

}

function mapPrint(argOnOff) // ie6 seems to have some probs addressing selectors as it was before :)
{
	if(argOnOff)
	{
		on_print_mode = true;
    document.getElementById("rootBody").className = "printMode";    
document.getElementById("map").style.left = "0px";      
document.getElementById("map").style.top = "0px";          
correctMapHeight();  
    document.getElementById("header").style.display = "none";    
    document.getElementById("leftcontent").style.display = "none"; // needed for ie6
document.getElementById("abortPrint").className = "printMode";    
//    document.getElementById("abortPrint").style.display = "block";     
    setMapFormat("portrait");         
		//setTimeout(focusPrint, 1000);
	}
	else
	{
		on_print_mode = false;    
    document.getElementById("rootBody").className = "";    
document.getElementById("map").style.left = "320px";    
document.getElementById("map").style.top = "75px";            
correctMapHeight();      
    document.getElementById("header").style.display = "block";        
    document.getElementById("leftcontent").style.display = "block";   
document.getElementById("abortPrint").className = "";        
    //document.getElementById("abortPrint").style.display = "none";     
  }
  //correctMapHeight(); // whats this`? its not working with divs anymore :)
  mapUpdateSize();
}

function mapUpdateSize()
{
	if(map != null)
	{
		map.updateSize();
	}
}

var permaLinks = []; // id, label, handler,  ...
function addPermaLink(json) {
}


function configureMap(argMap) {
 
    map = argMap;
    
    // create a vector layer for drawing features
    //vector_layer = new OpenLayers.Layer.Vector("POIVector");

    //map.addLayer(vector_layer);

    // for routing
    route_layer = new OpenLayers.Layer.Vector("RouteVector");
    map.addLayer(route_layer);
    // create a marker layer for POIs
    marker_layer = new OpenLayers.Layer.Markers("POIMarkers");
    map.addLayer(marker_layer);

    // add scale bar
    map.addControl(new OpenLayers.Control.ScaleLine());

    if (MosaicInternal.enableControls) {        
        // add print link
        var lp_link = document.createElement("a");        
        var print_link  = document.createElement("a");
        var jpg_link = document.createElement("a");
        var rp_link = document.createElement("a");
        
        //print_link.target = "_blank";
        lp_link.innerHTML = Sensus.tr("toggle panel");        
        rp_link.innerHTML  = Sensus.tr("toggle region pins");
        print_link.innerHTML  = Sensus.tr("Print");
        jpg_link.innerHTML = Sensus.tr("JPG");

        
        //print_control = new OpenLayers.Control.Permalink(print_link, Sensus.urlMake("print"), { 'displayClass' : 'olControlPrintlink'});
        //print_control = new OpenLayers.Control.Permalink(print_link, "javascript:mapPrint(true);//", { 'displayClass' : 'alternativeDivPrintClass'});
        print_control = new OpenLayers.Control.Permalink(print_link, "javascript:mapPrint(true);//", { 'displayClass' : 'olControlPrintlink'});
        jpg_control = new OpenLayers.Control.Permalink(jpg_link, "javascript:mapExport('jpg'); OpenLayers.Event.stop(this); //", { 'displayClass' : 'olControlJpg'});

        rp_control = new OpenLayers.Control.Permalink(rp_link, "javascript:toggleRegionPins('provinces'); OpenLayers.Event.stop(this); //", { 'displayClass' : 'olControlRegionPins'});

        lp_control = new OpenLayers.Control.Permalink(lp_link, "javascript:toggleLeftPanel(); OpenLayers.Event.stop(this); //", { 'displayClass' : 'olControlTogglePanel'});
/*        
        map.addControl(lp_control);
        map.addControl(rp_control);
        map.addControl(jpg_control);
        map.addControl(print_control);
        
        lp_control.div.appendChild(lp_link);
        rp_control.div.appendChild(rp_link);
        print_control.div.appendChild(print_link);
        jpg_control.div.appendChild(jpg_link);
*/
        // add drag control for editing poi position
        //drag_control = new OpenLayers.Control.DragFeature(vector_layer);
        //drag_control.onComplete = dragPoiComplete;
        //map.addControl(drag_control);

        // add overview map
        var overview = new OpenLayers.Control.OverviewMap({
            mapOptions : MosaicInternal.miniMapOptions
        });
        map.addControl(overview);
        overview.maximizeControl();
    }

rebuildMenus();

	if (typeof HaritaCameras != "undefined")
	{
		HaritaCameras.init();
	}
    
}

function getCurrentMapExtent() {
    return map.getExtent().transform(map.projection, map.displayProjection);
}

function setMapCenter(lon, lat, zoom) {
    var center = new OpenLayers.LonLat(lon,lat).transform(map.displayProjection, map.projection);
    map.setCenter(center, zoom);
}

var poiEventMode = "click";
function setPoiEventMode(mode) {
  poiEventMode = mode;
}

function showPoisInMap(json) {

    marker_layer.clearMarkers();
    for (var i = 0; i < json.results.length; ++i) {
        
				var pointerUri = Sensus.urlMake("images/pointer.png");
				
        var val = json.results[i];

        // create marker
        var icon_url = Sensus.urlMake("/icons/" + val.cid + ".png");
        var number = poiOffset + i + 1;
				
        var text =
            "<div class=\"poimarker2\"> \
               <div align=\"center\"><img src=\"" + icon_url + "\" /></div> \
               <div align=\"center\">" + number + "</div> \
             </div>\
             <div class=\"omx_marker_pointer\"></div>";
          
        var lonlat = new OpenLayers.LonLat(parseFloat(val.lon), parseFloat(val.lat));
        lonlat = lonlat.transform(map.displayProjection, map.projection);
        var icon = new TwoPoints.TextIcon(text, {});
        
        var marker = new OpenLayers.Marker(lonlat, icon);
        marker.poi = val;
        
        // register event listener
        //marker.events.register('mousedown', marker, function(evt) { markerMouseDown(this, evt); OpenLayers.Event.stop(evt); });
        
// later you can specify two different behaviors: mouseover OR click (+ explicit click on close)        
if (poiEventMode == "hover") {        
        marker.events.register('mouseover', marker, function(evt) { markerMouseOver(this, evt); OpenLayers.Event.stop(evt); });
        marker.events.register('mouseout', marker, function(evt) { markerMouseOut(this, evt); OpenLayers.Event.stop(evt); });
}
if (poiEventMode == "click") {        

        marker.events.register('dblclick', marker, function(evt) { map.zoomTo(14); openMarkerTooltip(this, true); OpenLayers.Event.stop(evt); });

        marker.events.register('click', marker, function(evt) { openMarkerTooltip(this, true); OpenLayers.Event.stop(evt); });
        // in the poi overlay provide a click button for "CLOSE" with js-func  markerMouseOut(this, evt); 
}        
        // add marker
        marker_layer.addMarker(marker);
        
        // update marker icon offset (icon size can de determined only after marker has been added)
        icon.offset = new OpenLayers.Pixel(0, -icon.imageDiv.offsetHeight);
        icon.imageDiv.style.zIndex = '1000';
        icon.draw();
        
        
    }
}

function isLeaving(event, element) {
    var toElement = event.relatedTarget;
    if (event.relatedTarget)
        toElement = event.relatedTarget;
    else if (event.toElement)
        toElement = event.toElement;

    while (toElement && toElement != element)
        toElement = toElement.parentNode;
    return (!toElement);
}


function markerMouseOver(marker, event) {
    openMarkerTooltip(marker);
}

function markerMouseOut(marker, event) {
    if (isLeaving(event, marker.icon.imageDiv) && marker == current_tooltip_marker)
        closeCurrentMarkerTooltip();
}

function markerMouseDown(marker, event) {
    if (OpenLayers.Event.isLeftClick(event))
        openPoiPage(marker.poi.pid);
}

//function getMarkerByPoiId(id) {
//   for (var i = 0; i < markers.length; ++i) {
//       var marker = markers[i];
//       if (marker.poi.pid == id)
//           return marker;
//   }
//   return null;
//}

function getMarkerByPoiId(id) {
	   if (!marker_layer){
		   return null;
	   }
	   if (!marker_layer.markers){
		   return null;
	   }
	   for (var i = 0; i < marker_layer.markers.length; ++i) {
	       var marker = marker_layer.markers[i];
	       if (marker.poi.pid){
		       if (marker.poi.pid == id)
		           return marker;
	       }
	   }
	   return null;
}


function openMarkerTooltip(marker, centerTo) {
    centerTo = centerTo || false;

    if (marker == current_tooltip_marker)
        return;
    
    if (current_tooltip_marker != null)
        closeCurrentMarkerTooltip();
    
    var icon_div = marker.icon.imageDiv.firstChild;
    marker.icon.imageDiv.style.zIndex = '1001';
    icon_div.innerHTMLBackup = icon_div.innerHTML;
    current_tooltip_marker = marker;
    
		var link_line = "<div align=\"right\">";
		
		if(allowPoiEdit)
		{
			poi_uri = Sensus.urlMake("/map?poi=" + marker.poi.pid);
			link_line = link_line + " <a href=\"" + poi_uri + "\" onclick=\"window.open('" + poi_uri + "');return(false);\">" + Sensus.tr("link") + "</a>";
			link_line = link_line + " <a href=\"javascript:void(0)\" onclick=\"editPoi(" + marker.poi.pid + ");return(false);\">" + Sensus.tr("edit") + "</a>";
		}
		link_line = link_line + " <a href=\"javascript:void(0)\" onclick=\"openPoiPage(" + marker.poi.pid + ");return(false);\">" + Sensus.tr("details...") + "</a>";
    
    if (poiEventMode == "click") {
		  link_line = link_line + " <a href=\"javascript:void(0)\" onclick=\"closeCurrentMarkerTooltip(); OpenLayers.Event.stop(event); return false; \">" + Sensus.tr("close") + "</a>";
    }
		
		link_line = link_line + "</div>";
		
    $.get(Sensus.urlMake('content/poi?id='+marker.poi.pid+'&format=html'), null, function (data, textStatus) {
        if (current_tooltip_marker == null)
            return;
        var icon = current_tooltip_marker.icon;
        var icon_div = icon.imageDiv.firstChild;
        icon_div.innerHTML = data + link_line;
        icon.offset = new OpenLayers.Pixel(0, -icon.imageDiv.offsetHeight);
        icon.draw();
        
if (centerTo) {
        var lonlat = new OpenLayers.LonLat(parseFloat(marker.poi.lon), parseFloat(marker.poi.lat));
        lonlat = lonlat.transform(map.displayProjection, map.projection);
        map.panTo(lonlat);
}        
        
//TODO: trigger popupopen event
map.events.triggerEvent("popupopen", {marker: marker});
        
    }, "html");
		
    
    
    
} 
var testicon;
var testmarker;

function closeCurrentMarkerTooltip() {
    if (current_tooltip_marker == null)
        return;
    
    var icon = current_tooltip_marker.icon;
    var icon_div = icon.imageDiv.firstChild;    
    icon_div.innerHTML = icon_div.innerHTMLBackup;
    
    icon.offset = new OpenLayers.Pixel(0, -icon.imageDiv.offsetHeight);
    icon.imageDiv.style.zIndex = '1000';
    icon.draw();
//TODO: trigger popupclose event    
map.events.triggerEvent("popupclose", {marker: current_tooltip_marker});

    current_tooltip_marker = null;
}


function dragPoiComplete(feature, pixel) {

    if (feature == null)
        return;

    var point = feature.geometry;
    var marker = markers[feature.name];
    var lonlat = new OpenLayers.LonLat(point.x, point.y);
    lonlat = lonlat.transform(map.projection, map.displayProjection);
    updateMarker2(marker, lonlat.lon, lonlat.lat);
    feature.lon = lonlat.lon;
    feature.lat = lonlat.lat;
    if (feature.name == 'routfeat1'){
    	$('#staddr').val(''+lonlat.lon+','+lonlat.lat+'');
    	if (routfeat1 != null && routfeat2 != null)  nwtxRoute();
    }else if (feature.name == 'routfeat2'){
    	$('#toaddr').val(''+lonlat.lon+','+lonlat.lat+'');
    	if (routfeat1 != null && routfeat2 != null)  nwtxRoute();
    }else if (feature.name == 'SearchPoint'){
    	$('#ptaddr').val(''+lonlat.lon+','+lonlat.lat+'');
    }else if (feature.name == 'createPoiMarker'){
        if (document['poi-edit']){
    	    document['poi-edit'].lon.value = lonlat.lon;
    	    document['poi-edit'].lat.value = lonlat.lat;
        }
    }
    
}

function updateMarker2 (marker,lon,lat){
	if (typeof (marker) == 'undefined')
		return;
	
	if (marker && marker.CLASS_NAME == "OpenLayers.Marker") {
		var lonlat = new OpenLayers.LonLat(lon, lat);
		lonlat = lonlat.transform(map.displayProjection, map.projection);
		marker_layer.removeMarker(marker);
		marker.lonlat = lonlat;
		marker_layer.addMarker(marker);
	} 
}

// **************************
//    interface for harita
//**************************

var createPoiMarker = null;
function startPoiPosEdit(id) {
    
    stopPoiPosEdit();
    
    var marker, lon, lat;
    
	marker = getMarkerByPoiId(id);
	if (!marker){
		return;
	}
	lon = marker.lonlat.lon;
	lat = marker.lonlat.lat;

	var lonlat = new OpenLayers.LonLat(lon,lat).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject());         

    map.setCenter(lonlat,map.getZoom());
    
    var point = new OpenLayers.Geometry.Point(lon, lat);
    var feature = new OpenLayers.Feature.Vector(point);
    
    feature.marker = marker;
        
    vector_layer.addFeatures(feature);
    drag_control.activate();
    
}

function startPoiPosCreate() {
    
    stopPoiPosEdit();
    
    var lon, lat;
    
  	lon=lastGeo.lon;
	lat=lastGeo.lat;
	    
	var lonlat = new OpenLayers.LonLat(lon,lat).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject());         

    map.setCenter(lonlat,map.getZoom());
   
    var point = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);
    var feature = new OpenLayers.Feature.Vector(point);
    removeMarker   ("createPoiMarker");
    var image_url = Sensus.urlMake("images/marker_yellow.png");
    addImageMarker ("createPoiMarker", image_url, lon, lat, 20, 32, -10, -32);
	var marker = markers["createPoiMarker"];
	if (marker){
		feature.marker = marker;
		feature.name   = "createPoiMarker";
	}
	for (var i=0;i<vector_layer.features.length;i++){
		if (vector_layer.features[i].name == 'createPoiMarker')
			vector_layer.features[i].destroy();
		
	}
	vector_layer.addFeatures(feature);
	
    drag_control.activate();
    
}


function stopPoiPosEdit() {
try {removeMarker("createPoiMarker");} catch (e) {}
for (var i=0;i<vector_layer.features.length;i++){
	if (vector_layer.features[i].name == 'createPoiMarker')
		vector_layer.features[i].destroy();	
}
//if (createPoiMarker != null) marker_layer.removeMarker(createPoiMarker);
//    if (!drag_control.active)
//        return;
    
    drag_control.deactivate();
    //vector_layer.destroyFeatures();
}

function goToPOI(id, notooltip) {    
    var poi = getJsonById('pois', id);
    var lon = parseFloat(poi.lon);
    var lat = parseFloat(poi.lat);
    
	var lonlat = new OpenLayers.LonLat(lon,lat).transform(new OpenLayers.Projection("EPSG:4326"),map.getProjectionObject());         

    map.setCenter(lonlat,map.getZoom());
    
    if (typeof notooltip == 'undefined') {
    	openPOITooltip(id, false);
    }else if (notooltip == true){
    	openPOITooltip(id, true);
    }else{
    	openPOITooltip(id, false);
    }
}

function closeCurrentPOITooltip() {    
    closeCurrentMarkerTooltip();
}

function openPOITooltip(id, onlyIfVisible, panTo) {
    
	open_marker_id = id;
	
    var marker = getMarkerByPoiId(id);
    if (marker == null)
        return;
    
    if (onlyIfVisible) {
        
        var poi = getJsonById('pois', id);
        var lon = parseFloat(poi.lon);
        var lat = parseFloat(poi.lat);

        var bbox = getCurrentMapExtent();
        if (lon < bbox.left || lon > bbox.right || lat < bbox.bottom || lat > bbox.top)
            return;
    }
    
    openMarkerTooltip(marker, panTo);
      
}


OpenLayers.Control.DragMarker = OpenLayers.Class.create();
OpenLayers.Control.DragMarker.prototype = 
  OpenLayers.Class.inherit(OpenLayers.Control.DragFeature, {

    /**
     * @param {OpenLayers.Layer.Vector} layer
     * @param {Object} options
     */
    initialize: function(layer, options) {
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
        this.layer = layer;
        this.dragCallbacks = OpenLayers.Util.extend({down: this.downFeature,
                                                     move: this.moveFeature,
                                                     up: this.upFeature,
                                                     out: this.cancel,
                                                     done: this.doneDragging
                                                    }, this.dragCallbacks);
        this.dragHandler = new OpenLayers.Handler.Drag(this, this.dragCallbacks);
        this.featureCallbacks = OpenLayers.Util.extend({over: this.overFeature,
                                                        out: this.outFeature
                                                       }, this.featureCallbacks);
        var handlerOptions = {geometryTypes: this.geometryTypes};
        this.featureHandler = new OpenLayers.Handler.Marker(this, this.layer,
                                                        this.featureCallbacks,
                                                        handlerOptions);
    },
    
    /**
     * Called when the drag handler detects a mouse-move.  Also calls the
     * optional onDrag method.
     * 
     * @param {OpenLayers.Pixel} pixel
     */
    moveFeature: function(pixel) {
        var px = this.feature.icon.px.add(pixel.x - this.lastPixel.x, pixel.y - this.lastPixel.y);;
        this.feature.moveTo(px);
        this.lastPixel = pixel;
        this.onDrag(this.feature, pixel);
    },

    /** @final @type String */
    CLASS_NAME: "OpenLayers.Control.DragMarker"
});
