
/*
 * Rotate pdf feature vertices by angle (rad)
 * @param float angle (rad)
 */
Feature.prototype.rotate = function(angle) {
  if (angle != null && angle != 0) {
            
    // Center
    var center = this.getCentroid();
    var cx = center.vertices[0].x;
    var cy = center.vertices[0].y;

    for (var i = 0; i < this.vertices.length; i++) {
      var vertx = this.vertices[i].x;
      var verty = this.vertices[i].y;
      
      // move to origin
      var x = vertx - cx;
      var y = verty - cy;
      
      // rotate
      var xp = x * Math.cos(angle) - y * Math.sin(angle);
      var yp = x * Math.sin(angle) + y * Math.cos(angle);
      
      var newx = this.vertices[i].x - x + xp;
      var newy = this.vertices[i].y - y + yp;
      this.vertices[i].x = newx;
      this.vertices[i].y = newy;
    }
  }
}


/*************** Display Tools **********************/

/**
 * Creates a rotate feature tool (see Display.mouseAction)
 * @param aDisplay display object
 */
function RotateFeatureTool(aDisplay) {
  xHide(aDisplay.eventPad);
  aDisplay.docObj.style.cursor = "move";
  xDisableDrag(aDisplay.rootDisplayLayer);
};
RotateFeatureTool.prototype.onMouseOver = function(aDisplay, ex, ey) {
  // over map
  if (umo.className.indexOf(layerCN) == -1) {
    var cn = umo.className;
    if (cn.indexOf(vertexCN) != -1) { // on a vertex
        var dShape = umo;
        aDisplay.mode = 'rotate';
    } else {
        var dShape = xParent(xParent(umo, true), true); // clicked on a line of a polyline or polygon
        xEnableDrag(dShape, aDisplay.dragStart, null, aDisplay.dragEnd);
        aDisplay.mode = 'drag';
    }
  }
};
RotateFeatureTool.prototype.onMouseOut = function(aDisplay, ex, ey) {
  if (!umo) {
    return;
  }
  // over map
  if (umo.className.indexOf(layerCN) == -1) {
    var cn = umo.className;
    if (cn.indexOf(vertexCN) != -1) { // clicked on a vertex
        var dShape = umo;
    } else {
        // clicked on a line of a polyline or polygon
        var dShape = xParent(xParent(umo, true), true);
        xDisableDrag(dShape);
    }
  }
};
RotateFeatureTool.prototype.onMouseDown = function(aDisplay, ex, ey) {
  if (aDisplay.mode == 'drag') {
      return;
  }
  if (!umo) return;
  // clicked on map

  if (umo.className.indexOf(layerCN) != -1) {
    aDisplay._map.selectedFeature = undefined;
    if (aDisplay._map.onUnselectFeatures) aDisplay._map.onUnselectFeatures();
    changeStatus(aDisplay.currentLayer, _OFF, true, true);
  } else {
    var cn = umo.className;
    var dShape = xParent(xParent(umo, true), true);
//    if (cn.indexOf(_SEL) == -1) changeStatus(aDisplay.currentLayer, _OFF, true, true);
//    changeStatus(dShape, _SEL, true, true);
  
    var feature = aDisplay.getMapFeature(dShape);
    if (feature.operation != 'insert') feature.operation = 'update';
    aDisplay._map.updateFeaturesCount();
    aDisplay._map.selectedFeature = feature;
    aDisplay.prevx = ex;
    aDisplay.prevy = ey;
    aDisplay.dShape = dShape;
    if (aDisplay._map.onFeatureSelected)
      aDisplay._map.onFeatureSelected(feature);
      
    // moving points
    if (!aDisplay.dmpts)
      aDisplay.dmpts = aDisplay.drawLine(aDisplay.currentLayer, 0, 0, 0, 0); // container
  }
  
  // TODO select a feature if no one selected
    
    // TODO if feature selected, get the clicked point and
    // rotate on mouse move vertically or horizontally
};
RotateFeatureTool.prototype.onMouseUp = function(aDisplay, ex, ey) {
  if (aDisplay.mode == 'drag') {
      return;
  }
  var feature = aDisplay.getMapFeature(aDisplay.dShape);
  aDisplay.currentLayer.removeChild(aDisplay.dShape);
  aDisplay.drawFeature(aDisplay.currentLayer, feature, _OFF, false);
  
  aDisplay.prevx = undefined;
  aDisplay.prevy = undefined;

  aDisplay.dmpts.innerHTML = "";
  
  if (aDisplay._map.onFeatureChange) aDisplay._map.onFeatureChange(feature);
  
  // update angle displayed in interface
  updatePdfAngleInterface(aDisplay.angle);
  
};
RotateFeatureTool.prototype.onMouseMove = function(aDisplay, ex, ey) {
  if (aDisplay.mode == 'drag') {
      return;
  }
  if (typeof aDisplay.prevx != "undefined" &&
      typeof aDisplay.prevy != "undefined") {
    
    aDisplay.dmpts.innerHTML = "";
    var xmin = aDisplay._map.extent.xmin;
    var ymin = aDisplay._map.extent.ymin;
    var xmax = aDisplay._map.extent.xmax;
    var ymax = aDisplay._map.extent.ymax;
    
    var feature = aDisplay.getMapFeature(aDisplay.dShape);
  
    var center = feature.getCentroid();
    var cx = geo2Pix(center.vertices[0].x, xmin, xmax, 0, aDisplay._width);
    var cy = geo2Pix(center.vertices[0].y, ymax, ymin, 0, aDisplay._height);
  
    // move to origin
    var x1 = aDisplay.prevx - cx;
    var y1 = aDisplay.prevy - cy;
    var x2 = ex - cx;
    var y2 = ey - cy;

    // calculate angle between 2 points  
    var angle1 = getAngle(x1, y1);
    var angle2 = getAngle(x2, y2);
    var angle = angle2 - angle1;
    
    feature.rotate(angle);
    for (var i = 0; i < feature.vertices.length; i++) {
      aDisplay.drawPoint(aDisplay.dmpts,
        geo2Pix(feature.vertices[i].x, xmin, xmax, 0, aDisplay._width),
        geo2Pix(feature.vertices[i].y, ymax, ymin, 0, aDisplay._height),
        null, null, _OFF);
    }
    
    aDisplay.angle = aDisplay.angle + angle;    
    aDisplay.prevx = ex;
    aDisplay.prevy = ey;
  }
  
  // update angle displayed in interface
  updatePdfAngleInterface(aDisplay.angle);
}

RotateFeatureTool.prototype.onDrag = function(elt, x, y) {

};
RotateFeatureTool.prototype.onDragEnd = function(elt, x, y) {
  var aDisplay = elt._display;
  if (aDisplay.mode == 'rotate') {
      return;
  }
  
  var cn = elt.className;
  var currentLayer = aDisplay._map.currentLayer;
  var xmin = aDisplay._map.extent.xmin;
  var xmax = aDisplay._map.extent.xmax;
  var ymin = aDisplay._map.extent.ymin;
  var ymax = aDisplay._map.extent.ymax;
  
//  if (cn.indexOf(vertexCN) != -1) { // clicked on a vertex
//  } else {// complete feature moved
    // get the corresponding map feature
    for (i = 0; i < currentLayer.features.length;i++) {
      if (aDisplay.id + "_" + currentLayer.features[i].id == elt.id) {
        var feature = currentLayer.features[i];
        if (feature.operation != 'insert') feature.operation = 'update';
        continue;
      }
    }
        
    // change all the coordinates 
    if (!feature) {
      alert ("drag on feature which not defined");
      return;
    }
    for (i = 0; i< feature.vertices.length;i++) {
      feature.vertices[i].x += (x - elt.startX) * (xmax - xmin) / aDisplay._width;
      feature.vertices[i].y += (y - elt.startY) * (ymin - ymax) / aDisplay._height;
    }
//  }
  aDisplay.dragon = false;
  if (aDisplay._map.onFeatureChange) aDisplay._map.onFeatureChange(feature);
};

/************* Generic fonction ***********/

function getAngle(x, y) {
  var angle;
  if (x != 0)
    angle = Math.atan(Math.abs(y / x));
  else
    angle = Math.PI / 2;
    
  if (x < 0 && y < 0)
    angle = Math.PI - angle; //Math.PI + angle;
  else if (x < 0)
    angle = Math.PI + angle;//Math.PI - angle;
  else if (y < 0)
    angle = angle; //Math.PI / 2 + angle;//2 * Math.PI - angle;
  else
    angle = 2 * Math.PI - angle; //angle;
    
  return angle;
}


/* fake functions */

function updatePdfAngleInterface() {}
