var manualFeatureId = 'manualFeature';

Map.prototype.geoshop_manual = function(aDisplay) {
  this.resetMapEventHandlers();
  
  // set no action on the map
  this.getDisplay(aDisplay).setTool('');

}

function manualDrawFeature() {
  mainmap.setCurrentLayer('drawing');
  var aDisplay = mainmap.getDisplay('map');

  // recover coord from interface
  var x1 = $('feature_x1').value;
  var x2 = $('feature_x2').value;
  var y1 = $('feature_y1').value;
  var y2 = $('feature_y2').value;
  // generate wkt
  var featureGeom = 'POLYGON((' +
                    x1 + ' ' + y1 + ',' +
                    x2 + ' ' + y1 + ',' +
                    x2 + ' ' + y2 + ',' +
                    x1 + ' ' + y2 + ',' +
                    x1 + ' ' + y1 + '))';

  // check if feature already exist, remove it in that case
  var fl = mainmap.currentLayer.features.length;
  for (var i = 0; i < fl; i++) {
    if (mainmap.currentLayer.features[i].id == manualFeatureId) {
      mainmap.currentLayer.delFeature(mainmap.currentLayer.features[i], manualFeatureId);
    }
  }
  // clear displayed layer
  aDisplay.clearLayer('drawing');

  // create and display feature
  var feature = new Feature(featureGeom);
  feature.id = manualFeatureId;
  mainmap.currentLayer.addFeature(feature);
	aDisplay.drawFeature(aDisplay.currentLayer, feature, _OFF, false);
  storeDxfFeatures();
  mainmap.geoshopRecenter(feature);
}

function redrawFeatures() {
  var aDisplay = mainmap.getDisplay('map');
  if (aDisplay.currentLayer.id != 'map_drawing'){
    mainmap.setCurrentLayer('drawing');
  }

  // clear layer
  aDisplay.clearLayer('drawing');
  
  var cTool = $('tool').value;
  var fl = mainmap.currentLayer.features.length;
  if (cTool != 'geoshop_manual') {
    // hide manual feature form
    toogleManualFeature();
    // redraw dxf_rect/poly feature
    for (var i = 0; i < fl; i++) {
      if (mainmap.currentLayer.features[i].id != manualFeatureId) {
        aDisplay.drawFeature(aDisplay.currentLayer, mainmap.currentLayer.features[i], _OFF, false);
      }
    } 
  } else {
    // show manual feature form
    toogleManualFeature(true);
    // redraw manual feature
    for (var i = 0; i < fl; i++) {
      if (mainmap.currentLayer.features[i].id == manualFeatureId) {
        aDisplay.drawFeature(aDisplay.currentLayer, mainmap.currentLayer.features[i], _OFF, false);
      }
    }    
  }
}

/*
 * Recenter on pdf feature
 */
Map.prototype.geoshopRecenter = function(feature) {

  /* it should be possible to factorize this code with the related code in exportPdf plugin */

  Logger.trace('geoshopRecenter');
  
  var recentering = true;
  // only recenter if the feature is really smaller than the bbox
  var minmax = getFeatureMinMax(feature);
  var fw = minmax[2] - minmax[0];
  var fh = minmax[3] - minmax[1];
  var rw = fw / mainmap.extent.width;
  var rh = rw / mainmap.extent.height;
  var rmax = Math.max(rw,rh);
  if (rmax >= 0.3 && rmax < 1){
    recentering = false;
  }

  // check if feature is out of current bbox
  if (minmax[2] < mainmap.extent.xmin || minmax[0] > mainmap.extent.xmax ||
      minmax[3] < mainmap.extent.ymin || minmax[1] > mainmap.extent.ymax) {
    recentering = true;
  }

  if (!recentering) {
    return;
  }

  // get current geoshop feature caneva largest diagonal dimension
  var aDisplay = this.getDisplay(mainmapid);
  var center = feature.getCentroid();
  var cx = center.vertices[0].x;
  var cy = center.vertices[0].y;
  var cxl = Array();
  var cyl = Array();

  for (var i = 0; i < feature.vertices.length; i++){
    cxl[i] = feature.vertices[i].x;
    cyl[i] = feature.vertices[i].y;
  }
  cxl.sort();
  cyl.sort();

  cxmin = cxl[0];
  cxmax = cxl[cxl.length-1];
  cymin = cyl[0];
  cymax = cyl[cyl.length-1];

  var cxm = feature.vertices[0].x - cx;
  var cym = feature.vertices[0].y - cy;
  var dl = Math.sqrt((cxm * cxm) + (cym * cym));

  // add small buffer around enclosing bbox
  dl = dl * 1.5;

  // generate a recentering bbox
  var nbbox_minx = cx - dl;
  var nbbox_maxx = cx + dl;
  var nbbox_miny = cy - dl;
  var nbbox_maxy = cy + dl;
  var nbbox = nbbox_minx+','+nbbox_miny+','+nbbox_maxx+','+nbbox_maxy;
  
  // set in dom the recenter_bbox input+value
  var rbbox = document.carto_form['recenter_bbox'];
  if (typeof(rbbox) == 'undefined') {
    // create an input
    var rbbox = document.createElement("input");
    rbbox.setAttribute("type", "hidden");
    rbbox.setAttribute("name", "recenter_bbox");
    rbbox.setAttribute("id", "recenter_bbox");
    rbbox.setAttribute("value", nbbox);
    document.carto_form.appendChild(rbbox);
  } else {
    rbbox.value = nbbox;
  }
  // call recentering (not ajax because it's easier to redraw automaticaly the feature this way, ajax could be used but the geobestellung plugin would have to return something to trigger the onAfterAjaxCallGeneral stage)
  FormItemSelected();

}

/**
 * update coords in manual feature form after the user has moved the feature
 */
function updateFeatureCoords() {
  var currentFeature = getCurrentDisplayedFeatureId();
  if (currentFeature == 'manualFeature') {
    var fl = mainmap.currentLayer.features.length;
    for (var i = 0; i < fl; i++) {
      if (mainmap.currentLayer.features[i].id == manualFeatureId) {
        var feature = mainmap.currentLayer.features[i];
        var minmax = getFeatureMinMax(feature);
        $('feature_x1').value = Math.round(minmax[0]);
        $('feature_x2').value = Math.round(minmax[2]);
        $('feature_y1').value = Math.round(minmax[1]);
        $('feature_y2').value = Math.round(minmax[3]);
        return;
      }
    } 
  }
}

function getFeatureMinMax(feature) {
  var minx = feature.vertices[0].x, miny = feature.vertices[0].y, maxx = feature.vertices[0].x, maxy = feature.vertices[0].y;
  for (var j = 0; j < feature.vertices.length; j++) {
    if (feature.vertices[j].x > maxx) maxx = feature.vertices[j].x;
    if (feature.vertices[j].x < minx) minx = feature.vertices[j].x;
    if (feature.vertices[j].y > maxy) maxy = feature.vertices[j].y;
    if (feature.vertices[j].y < miny) miny = feature.vertices[j].y;
  }
  return Array(minx, miny, maxx, maxy);
}

/* show/hide feature form */
function toogleManualFeature(state) {
  var el = $('manualFeatureContainer');
  if (state) {
    el.style.display = 'block';
  } else {
    el.style.display = 'none';
  }
}

var featureFormFieldState = [];
// clear feature coords input on focus
function clearFeatureFormField(e) {
  var el;
  if (window.event && window.event.srcElement)
      el = window.event.srcElement;
  if (e && e.target)
      el = e.target;
  if (!el) return;
  
  var elp = featureFormFieldState[el.id];
  if (typeof(elp) == 'undefined') {
    featureFormFieldState[el.id] = true;
    el.value = '';
  }
}

// event listeners
function addFeatureFormListener() {
  var eles = Array('x1','x2','y1','y2');
  for (var i = 0; i < eles.length; i++) {
    var el = $('feature_' + eles[i]);
    EventManager.Add(el, 'focus', clearFeatureFormField, false);
  }
  // hide manual feature form if another geoshop tool is selected
  for (var i = 0; i < cw3_tools.length; i++ )    {
    if (cw3_tools[i] == 'dxf_rect' || cw3_tools[i] == 'dxf_polygon' || cw3_tools[i] == 'geoshop_manual') {
      var elt = $(cw3_tools[i] + '_icon');
      EventManager.Add(elt, 'click', redrawFeatures, false);      
    }
  }
}
EventManager.Add(window, 'load', addFeatureFormListener, false);

