/* Copyright 2005 Camptocamp SA.
   Licensed under the GPL (www.gnu.org/copyleft/gpl.html) */

nachkomma = 5 ;
/**
 * Double clic parameters
 * (DblClick emulation is required for some browsers)
 */
dbl_click_delay = 200; // ms
dbl_click_tol = 3; // pixels
/**
 * Min distance betwwen vertex when drawing lines
 * on mouse move event
 */
vertexDistance = 10;

/**
 *
 */
snappingDistance = 10;

/**
 * class names parameters (in concordance with css styles)
 */
// user defined class names for the drawing elements
layerCN = "layer";
vertexCN = "vertex";
linepointCN = "linepoint";
boxCN = "box";
boxfillCN = "boxfill";
polygonfillCN = "polygonfill";

// user defined status for the drawing elements
_OFF = "_off";
_SEL = "_selected";

/**
 * HTML ids in html page
 */
div_geo_id = "floatGeo"; // Geo coordinates
div_geo_X = "floatGeoX"; // Geo coordinates
div_geo_Y = "floatGeoY"; // Geo coordinates
div_distance_id = "floatDistance"; // distance measure
div_surface_id = "floatSurface"; // surface measure
div_features_num_id = "features_num"; // total number of features
div_inserted_num_id = "inserted_features_num"; // number of inserted features
div_updated_num_id = "modified_features_num"; // number of updated features
div_deleted_num_id = "deleted_features_num"; // number of deleted features

/**
 * User defined functionnalities
 * Function called on window onload event
 */
createMap = function() {
  myform = document.forms['carto_form'];

  // create a new map object with a className as argument
  mainmap = new Map("map");

  mainmap.geoTag = xGetElementById(div_geo_id);
  
  if (mainmap.geoTag != null) {
    mainmap.geoUnits = mainmap.geoTag.innerHTML;
    mainmap.geoTag.innerHTML = sprintf(mainmap.geoUnits, "_", "_");
    xShow(mainmap.geoTag);
    
   }
  //------------------------------------------------
/*  mainmap.geoTagX = xGetElementById(div_geo_X);
  mainmap.geoTagY = xGetElementById(div_geo_Y);
  if (mainmap.geoTagX != null) {
    mainmap.geoUnitX = mainmap.geoTagX.innerHTML;
    mainmap.geoTagX.innerHTML = sprintf(mainmap.geoUnitX, "_");
    xShow(mainmap.geoTagX);
  }
  if (mainmap.geoTagY != null) {
    mainmap.geoUnitY = mainmap.geoTagY.innerHTML;
    mainmap.geoTagY.innerHTML = sprintf(mainmap.geoUnitY, "_");
    xShow(mainmap.geoTagY);
  }
  */
  //------------------------------------------------
  mainmap.distanceTag = xGetElementById(div_distance_id);
  if (mainmap.distanceTag != null) {
    mainmap.distanceUnits = mainmap.distanceTag.innerHTML;
  }
  mainmap.surfaceTag = xGetElementById(div_surface_id);
  if (mainmap.surfaceTag != null) {
    mainmap.surfaceUnits = mainmap.surfaceTag.innerHTML;
  }

  initMap();

  mainmap.displayFeaturesCount();
  mainmap.snap("map");

  // initial selected tool
  if (typeof cw3_initial_selected_tool != "undefined") {
    // prevent interface failure if last selected tool was pdfrotate, set it to default zoomin
    cw3_initial_selected_tool = cw3_initial_selected_tool.replace(/pdfrotate/g, "zoomin");
   //       eval (cw3_initial_selected_tool);
  }

  xHide(xGetElementById('loadbarDiv'));
};

/**
 * Store the values (coords and type) in the form
 * Used for the navigation tools (zoomin, zoomout, etc ...)
 * @param aFeature
 */
fillForm = function(aFeature) {
  // TODO let the possibility to send more than one feature
  var coords = new String();
  for (var i=0;i<aFeature.vertices.length;i++) {
    coords += aFeature.vertices[i].x + "," + aFeature.vertices[i].y + ";";
  }
  coords = coords.substring(0, coords.length -1);
  myform.selection_coords.value = coords;
  switch (aFeature.type) {
    case "point" :
      var shapeType = "point";
      break;
    case "polyline" :
      var shapeType = "polyline";
      break;
    case "polygon" :
      var shapeType = "polygon";
      break;
  }
  myform.selection_type.value = shapeType;
};

/**
 * Empty the inputs (coords and type) in the form
 */
emptyForm = function() {
  myform.selection_coords.value = "";
  myform.selection_type.value = "";
};

/**
 * Fills the feature form input with the edited features of the current layer
 */
storeFeatures = function() {
  for (var i=0;i < mainmap.currentLayer.features.length; i++) {
    var aFeature = mainmap.currentLayer.features[i];
    for (var j=0; j < mainmap.editAttributeNames.length; j++) {
      if (mainmap.editAttributeTypes[j] == "")
              continue;
      var input = eval("myform['edit_feature_" + aFeature.id + "[" + mainmap.editAttributeNames[j] + "]']");
      if (!validateFormInput(mainmap.editAttributeTypes[j], input.value)) {
        return false;
      }
    }
    if (aFeature.operation != 'undefined') {
      // store geometry
      createInput(myform, "edit_feature_" + aFeature.id + "[WKTString]", aFeature.getWKT(), 'hidden');
      // store operation
      createInput(myform, "edit_feature_" + aFeature.id + "[operation]", aFeature.operation, 'hidden');
    }
  }
  return true;
};

/**
 * Store the feature operation in the form
 */
setFeatureOperation = function(aFeature, operation) {
  aFeature.operation = operation;
  mainmap.displayFeaturesCount();
};

/**
 * Creates an form input
 * @param form form name
 * @param name name of the input
 * @param value value of the input
 */
createInput = function(elt, name, value, type) {
  if (document.all) {
    var str = '<input type="'+type+'" name="'+name+'" value="'+value+'" />';
    var input = xCreateElement(str);
  }
  else {
    var input = xCreateElement("input");
    input.type = type;
    input.name = name;
    input.value = value;
  }
  xAppendChild(elt, input);
  return input;
}

/**
 * Submits the form
 */
doSubmit = function() {
  xShow(xGetElementById('loadbarDiv'));
  var myform = document.forms['carto_form'];
  
  window.setTimeout("myform.submit()",500);
  
  //window.document.carto_form.submit();
};
//--------------------------------------------------
EventManager.Add(window, 'load', createMap, false);
//--------------------------------------------------


Map.prototype.snap = function(aDisplay) {
  this.getDisplay(aDisplay).useSnapping =
    (typeof myform['snapping'] != "undefined" && myform['snapping'].checked)? true : false;
};

Map.prototype.resetMapEventHandlers = function() {
  if (this.onToolUnset != undefined) {
    this.onToolUnset();
  }
  this.onToolUnset = undefined;
  this.onFeatureInput = undefined;
  this.onClic = undefined;
  this.onSelPoint = undefined;
  this.onFeatureChange = undefined;
  this.onNewFeature = undefined;
  this.onCancel = function() {
    createMap();
  }
  this.onMove = function(geoX, geoY) {
    // display geo coordinates
    if (this.geoTag) {
      nachk = Math.pow(10,nachkomma);
      this.geoTag.innerHTML = sprintf(this.geoUnits, Math.round(geoX*nachk)/nachk, Math.round(geoY*nachk)/nachk);
     
     //lon_map =  xGetElementById('lon_map');
     //lat_map =  xGetElementById('lat_map');
     //if (lon_map != null) {
  	 document.carto_form.lon_map.value = Math.round(geoX*10000)/10000;
         document.carto_form.lat_map.value = Math.round(geoY*10000)/10000;
     //}
 /*     this.geoTagX.innerHTML = sprintf(this.geoUnitX, Math.round(geoX*nachk)/nachk, Math.round(geoY*nachk)/nachk);
      this.geoTagY.innerHTML = sprintf(this.geoUnitY, Math.round(geoX*nachk)/nachk, Math.round(geoY*nachk)/nachk);
 */    
      }
  }
};

Map.prototype.displayFeaturesCount = function() {
  var div_features_num = xGetElementById(div_features_num_id);
  var div_inserted_num = xGetElementById(div_inserted_num_id);
  var div_updated_num = xGetElementById(div_updated_num_id);
  var div_deleted_num = xGetElementById(div_deleted_num_id);
  this.updateFeaturesCount();
  if (div_features_num != null)
    div_features_num.innerHTML = this.featuresNum;
  if (div_inserted_num != null)
    div_inserted_num.innerHTML = this.insertedNum;
  if (div_updated_num != null)
    div_updated_num.innerHTML = this.updatedNum;
  if (div_deleted_num != null)
    div_deleted_num.innerHTML = this.deletedNum;
};



Map.prototype.notoolbar = function() {} ;
/**
 * Tools specific functionnalities
 */
/***** LOCATION ****/
Map.prototype.zoomout = function(aDisplay) {
  this.resetMapEventHandlers();



  this.setCurrentLayer('drawing');
  this.getDisplay(aDisplay).setTool('sel.point');
  this.onSelPoint = function(x, y) {
    myform.selection_coords.value = x + "," + y;
    myform.selection_type.value = "point";    
    storeFeatures();
    
    var MminX = xGetElementById('Mminx');
    var MmaxX = xGetElementById('Mmaxx');
    var MminY = xGetElementById('Mminy');
    var MmaxY = xGetElementById('Mmaxy');


    if (MminX != null) {
        
        var dx = MmaxX.value - MminX.value ;
        var dy = MmaxY.value - MminY.value ;
        
        // Faktor 2 vergrößern
        var xmin = x - dx;
        var xmax = x + dx;
        var ymin = y - dy ;
        var ymax = y + dy ;
    }
    var box_xmin = xGetElementById('box_xmin');
    var box_xmax = xGetElementById('box_xmax');
    var box_ymin = xGetElementById('box_ymin');
    var box_ymax = xGetElementById('box_ymax');
        
    if (box_xmin != null) {  
         
       box_xmin.value = Math.min(xmin,xmax) ; 
       box_ymin.value = Math.min(ymin,ymax) ;    
       box_xmax.value = Math.max(xmin,xmax) ; 
       box_ymax.value = Math.max(ymin,ymax) ;  
       
    }
    
    doSubmit();
  }
};

Map.prototype.selectionBox = function(aDisplay, action) {
  this.resetMapEventHandlers();

  this.setCurrentLayer('drawing');
  this.getDisplay(aDisplay).setTool('sel.box');
  this.onSelBox = function(x1, y1, x2, y2) {
    myform.selection_coords.value = x1 + "," + y1 + ";" + x2 + "," + y2;
    myform.selection_type.value = "rectangle";
    storeFeatures();
    doSubmit();
  }
};

Map.prototype.zoomin = function(aDisplay) {
  this.selectionBox(aDisplay, 'Location.Zoom');
};

Map.prototype.fullextent = function(aDisplay) {
  doSubmit();
}

Map.prototype.Help = function(aDisplay) {
  //this.selectionBox(aDisplay, 'Query.Perform');
  this.getDisplay(aDisplay).docObj.style.cursor = "help";
};

Map.prototype.Move = function(aDisplay) {
  this.resetMapEventHandlers();
  this.getDisplay(aDisplay).setTool('pan');
  mainmap.onPan = function(x, y) {
    myform.selection_coords.value = x + "," + y;
    myform.selection_type.value = "point";
    storeFeatures();
    doSubmit();
  }
};
/***** LocalGravity ****/

Map.prototype.LocalGravity = function(aDisplay) {
  this.resetMapEventHandlers();

  this.setCurrentLayer('gravpoint');
  this.getDisplay(aDisplay).setTool('sel.point');
  
  this.onSelPoint = function(x, y) {
    myform.selection_coords.value = x + "," + y;
    myform.selection_type.value = "point";
    storeFeatures();
    
    myform.gravity_ok.value = 1 ;
    
    var inputx = xGetElementById('gravp_x');
    var inputy = xGetElementById('gravp_y');
    var inputh = xGetElementById('gravp_h');
    inputx.value = x ;
    inputy.value = y ;
    inputh.value = '' ;
    
    doSubmit();
  }
  this.onNewFeature = function(aFeature) {
    this.onToolUnset();
  };
  this.onFeatureInput = function(aFeature) {
    aFeature.operation = "";
  };
  this.onToolUnset = function() {
    //clear the distance's display layer
    this.getDisplay(aDisplay).clearLayer('gravpoint');
    this.onCancel();
  };
  this.onCancel = function(aFeature) {
    this.distanceTag.style.display = "none";
  };
  
};
/***** Simple Point ****/

Map.prototype.mpoint = function(aDisplay) {
  this.resetMapEventHandlers();

  this.setCurrentLayer('gravpoint');
  this.getDisplay(aDisplay).setTool('draw.point');
  
  this.onSelPoint = function(x, y) {
    myform.selection_coords.value = x + "," + y;
    myform.selection_type.value = "point";
    storeFeatures();
    
    
    var inputx = xGetElementById('gravp_x');
    var inputy = xGetElementById('gravp_y');
    inputx.value = x ;
    inputy.value = y ;
    
    //doSubmit();
  }
  this.onNewFeature = function(aFeature) {
    this.onToolUnset();
  };
  this.onFeatureInput = function(aFeature) {
    aFeature.operation = "";
  };
  

  this.onToolUnset = function() {
    //clear the distance's display layer
    this.getDisplay(aDisplay).clearLayer('gravpoint');
    this.onCancel();
  };
  
  this.onCancel = function(aFeature) {
    this.distanceTag.style.display = "none";
  };
}

/***** GRAVZONE ****/

Map.prototype.GravityZone = function(aDisplay) {
  this.resetMapEventHandlers();

  this.setCurrentLayer('zoneref');
  this.getDisplay(aDisplay).setTool('draw.point');
  
  this.onSelPoint = function(x, y) {
    myform.selection_coords.value = x + "," + y;
    myform.selection_type.value = "point";
    storeFeatures();
    
    
    var inputx = xGetElementById('Elon');
    var inputy = xGetElementById('Elat');
    inputx.value = x ;
    inputy.value = y ;
    
    //doSubmit();
  }
 
  this.onNewFeature = function(aFeature) {
    this.onToolUnset();
  };
  this.onFeatureInput = function(aFeature) {
    aFeature.operation = "";
  };
  

  this.onToolUnset = function() {
    //clear the distance's display layer
    this.getDisplay(aDisplay).clearLayer('zoneref');
    this.onCancel();
  };
  
  this.onCancel = function(aFeature) {
    this.distanceTag.style.display = "none";
  };
}
/***** CITY ****/

Map.prototype.CitySearch = function(aDisplay) {
}

/***** THEMES ****/

Map.prototype.Maplayer = function(aDisplay) {
}

 
/***** STATICTOOLS ****/
Map.prototype.distance = function(aDisplay) {
  this.resetMapEventHandlers();
  this.setCurrentLayer('distance');
  this.getDisplay(aDisplay).setTool('draw.line');
  this.getDisplay(aDisplay).useSnapping = false;
  this.onClic = function(aFeature) {
    //var distance = aFeature.getLength();   
    //distance = (factor == 1000) ? Math.round(distance  * 100) / 100 : Math.round(distance);
  
   
   //-----------------------------------------------------
   // Strecke auf dem Ellipsoid berechnen
    var distance = aFeature.ellDist();
    distance = Math.round(distance)/1000 ; // in km
    
    this.distanceTag.innerHTML = sprintf(this.distanceUnits, distance);
    this.distanceTag.style.display = "block";
    
    //--------------------------------------------------
    // NEU: Punkte und Distanz in Listenfeld eintragen
    //var liste = window.document.getElementsByName("distlist")[0];
    //var neupunkt = window.document.createElement("option");
    
    xx = Math.round(geoX*100)/100 ;
    yy = Math.round(geoY*100)/100 ;
    
    //--------------------------------------------------
    var tarea     = window.document.getElementById("distarea");
    var areanr    = window.document.getElementById("areanr");
    
    if (tarea != null) {
      areanr.value = areanr.value*1.0 + 1.0 ;	
      anr = areanr.value  ;
      val = tarea.value ;
      
      xtext = xx+' ';  
      last  = xtext.lastIndexOf(" ") ;
      while (last<6) {
      	xtext = xtext+' '; 
      	last = last+1 ; 
      }
      ytext = yy+' ';  
      last  = ytext.lastIndexOf(" ") ;
      while (last<5) {
      	ytext = ytext+' ';  
      	last = last+1 ; 
      }
      
      tarea.value =  val.concat('\r\n'+anr+': '+xtext+' '+ytext+' -> '+distance) ;
    }
    
    
    //--------------------------------------------------    
    
    
  if (this.distanceTag.style.position == "absolute")
      xMoveTo(this.distanceTag, mouse_x, mouse_y);
  }
  this.onNewFeature = function(aFeature) {
    this.onToolUnset();
  };
  this.onFeatureInput = function(aFeature) {
    aFeature.operation = "";
  };
  this.onToolUnset = function() {
    //clear the distance's display layer
    this.getDisplay(aDisplay).clearLayer('distance');
    this.onCancel();
  };
  this.onCancel = function(aFeature) {
    this.distanceTag.style.display = "none";
    
    // Liste löschen
    //var liste = window.document.getElementsByName("distlist")[0];
    //liste.options[liste.length-1] = null;
    //liste.options[0] = null ;
    var tarea    = window.document.getElementById("distarea");
    var areanr    = window.document.getElementById("areanr");
    
    if (tarea != null) {
      areanr.value =0 ;
      tarea.value ='NR  LON     LAT   -> DIST(km)' ;
    }
    };
};

/***********  Flächenberechnung  ***************/
Map.prototype.surface = function(aDisplay) {
  this.resetMapEventHandlers();
  this.setCurrentLayer('surface');
  this.getDisplay(aDisplay).setTool('draw.poly');
  this.getDisplay(aDisplay).useSnapping = false;
  this.onClic = function(aFeature) {
  	
  	
    var surface = aFeature.getArea2();
    surface = Math.round(surface*10)/10 ;
    //surface = (factor == 1000) ? Math.round(surface / 1000000 * 10000) / 10000 : Math.round(surface);
    this.surfaceTag.innerHTML = sprintf(this.surfaceUnits, surface);
    this.surfaceTag.style.display = "block";
    
    //--------------------------------------------------
    // NEU: Punkte und Distanz in Listenfeld eintragen
    /*var liste = window.document.getElementsByName("surflist")[0];
    var neupunkt = window.document.createElement("option");
    
    xx = Math.round(geoX*100)/100 ;
    yy = Math.round(geoY*100)/100 ;
    neupunkt.text = '('+(liste.length)+'): '+xx+' '+yy+' -> '+ surface ;
    //neupunkt.value = distance ;
    var FolgendeOption = null;
    if (document.all)
        FolgendeOption = liste.length;
    liste.add(neupunkt, FolgendeOption);
   */ 
    //--------------------------------------------------
    
    if (this.surfaceTag.style.position == "absolute")
      xMoveTo(this.surfaceTag, mouse_x, mouse_y);
  }
  this.onNewFeature = function(aFeature) {
    this.onToolUnset();
  };
  this.onFeatureInput = function(aFeature) {
    aFeature.operation = "";
  };
  this.onToolUnset = function() {
    //clear the surface's display layer
    this.getDisplay(aDisplay).clearLayer('surface');
    this.onCancel();
  };
  this.onCancel = function(aFeature) {
    this.surfaceTag.style.display = "none";
    // Liste löschen
    
  };
};
/***** OUTLINE ****/
Map.prototype.outline_poly = function(aDisplay) {
  this.resetMapEventHandlers();
  this.setCurrentLayer('outline_poly');
  this.getDisplay(aDisplay).setTool('draw.poly');


  
  
  
  this.onNewFeature = function(aFeature) {
          this.onToolUnset();
  };
  this.onFeatureInput = this.onFeatureChange = function(aFeature) {
    fillForm(aFeature);
    if (typeof addLabel == 'undefined')
      doSubmit();
    else
      addLabel(polyDefaultLabel, mouse_x, mouse_y);
  };
  this.onToolUnset = function() {
    //clear the outline_poly's display layer
    this.getDisplay(aDisplay).clearLayer('outline_poly');
    this.onCancel();
  };
  this.onCancel = function() {
    if (typeof hideLabel != 'undefined')
      hideLabel();
    emptyForm();
  };
};

Map.prototype.outline_line = function(aDisplay) {
  this.resetMapEventHandlers();
  this.setCurrentLayer('outline_line');
  this.getDisplay(aDisplay).setTool('draw.line');

  this.onNewFeature = function(aFeature) {
          this.onToolUnset();
  };
  this.onFeatureInput = this.onFeatureChange = function(aFeature) {
    fillForm(aFeature);
    if (typeof addLabel == 'undefined')
      doSubmit();
    else
      addLabel(lineDefaultLabel, mouse_x, mouse_y);
  };
  this.onToolUnset = function() {
    //clear the outline_poly's display layer
    this.getDisplay(aDisplay).clearLayer('outline_line');
    this.onCancel();
  };
  this.onCancel = function() {
    if (typeof hideLabel != 'undefined')
      hideLabel();
    emptyForm();
  };
};

Map.prototype.outline_rectangle = function(aDisplay) {
  this.resetMapEventHandlers();
  this.setCurrentLayer('outline_rectangle');
  this.getDisplay(aDisplay).setTool('draw.box');



  this.onNewFeature = function(aFeature) {
          this.onToolUnset();
  };
  this.onFeatureInput = this.onFeatureChange = function(aFeature) {
    fillForm(aFeature);
    if (typeof addLabel == 'undefined')
      doSubmit();
    else
      addLabel(rectangleDefaultLabel, mouse_x, mouse_y);
  };
  this.onToolUnset = function() {
    //clear the outline_poly's display layer
    this.getDisplay(aDisplay).clearLayer('outline_rectangle');
    this.onCancel();
  };
  this.onCancel = function() {
    if (typeof hideLabel != 'undefined')
      hideLabel();
    emptyForm();
  };
};

Map.prototype.outline_point = function(aDisplay) {
  this.resetMapEventHandlers();
  this.setCurrentLayer('outline_point');
  this.getDisplay(aDisplay).setTool('draw.point');

  this.onNewFeature = function(aFeature) {
          this.onToolUnset();
  };
  this.onFeatureInput = this.onFeatureChange = function(aFeature) {
    fillForm(aFeature);
    if (typeof addLabel == 'undefined')
      doSubmit();
    else
      addLabel(pointDefaultLabel, mouse_x, mouse_y);
  };
  this.onToolUnset = function() {
    //clear the outline_poly's display layer
    this.getDisplay(aDisplay).clearLayer('outline_point');
    this.onCancel();
  };
  this.onCancel = function() {
    if (typeof hideLabel != 'undefined')
      hideLabel();
    emptyForm();
  };
};
