/* Copyright 2005 Camptocamp SA. 
   Licensed under the GPL (www.gnu.org/copyleft/gpl.html) */

var libre = false;
var coordObj = null;

function hidePdfFeature(event) {
  mainmap.removePdfFeature(mainmapid);
}
function addToolPdfListeners() {

  for (var i = 0; i < cw3_tools.length; i++ )    {
    if (cw3_tools[i] != 'pdfrotate') {
      elt = xGetElementById(cw3_tools[i]);
      xAddEventListener(elt, 'click', hidePdfFeature, false);
      elt = xGetElementById(cw3_tools[i] + "_icon");
      xAddEventListener(elt, 'click', hidePdfFeature, false);
    }
  }
}
EventManager.Add(window, 'load', addToolPdfListeners, false);



/***** PDF tools ****/

/**
  * Construye una feature (parametro) a partir de los datos del formulario
  * @param feature feaure
  * @param aDisplay display object
  * @author Cartoweb's Developers
  */
Map.prototype.form2PdfFeature = function(feature, aDisplay) {

  var marginx = myform.pdfMarginX.value;
  var marginy = myform.pdfMarginY.value;

  if (xGetElementById('pdfLibrex').value == ""){ // al cargar la herramienta
      this.boxInViewport(feature, aDisplay); // crea box visible en el viewport
  } else {

    var paperx = xGetElementById('pdfLibrex').value;
    var papery = xGetElementById('pdfLibrey').value;

    var medidaH = myform.medidaH_box.value;
    var medidaV = myform.medidaV_box.value;

    var scale = myform.pdfScale.value;
    var sizex = (paperx) / 1000 * scale / 2;
    var sizey = (papery) / 1000 * scale / 2;
    sizex = (sizex/30)/3600; // conversion de metro a grado (necesita cambios)
    sizey = (sizey/30)/3600; // conversion de metro a grado (necesita cambios)

    feature.vertices = Array();
    var vertex;
    vertex = new Vertex(-sizex, -sizey);
    vertex.index = 0;
    feature.vertices.push(vertex);
    vertex = new Vertex(-sizex, sizey);
    vertex.index = 1;
    feature.vertices.push(vertex);
    vertex = new Vertex(sizex, sizey);
    vertex.index = 2;
    feature.vertices.push(vertex);
    vertex = new Vertex(sizex, -sizey);
    vertex.index = 3;
    feature.vertices.push(vertex);
    vertex = new Vertex(-sizex, -sizey);
    vertex.index = 4;
    feature.vertices.push(vertex);

    aDisplay.angle = parseFloat(myform.pdfMapAngle.value);
    if (isNaN(aDisplay.angle)) {
      aDisplay.angle = 0;
    }
    var cx = parseFloat(myform.pdfMapCenterX.value);
    var cy = parseFloat(myform.pdfMapCenterY.value);
    if (isNaN(cx) || isNaN(cy)) {
      cx = (this.extent.xmax + this.extent.xmin) / 2;
      cy = (this.extent.ymax + this.extent.ymin) / 2;
    }
    for (var i = 0; i < feature.vertices.length; i++) {
      feature.vertices[i].x = feature.vertices[i].x + cx;
      feature.vertices[i].y = feature.vertices[i].y + cy;
    }
    feature.rotate(aDisplay.angle);

  }
}

/**
  * Construye una feature a partir del box dibujado manualmente
  * @param feature feaure
  * @param aDisplay display object
  * @param coordObj coordinates object (arreglo donde cada elem: coordx,coordy)
  * @author Armando Batista
  */
Map.prototype.drawbox2PdfFeature = function(feature, aDisplay, coordObj) {

  feature.vertices = Array();
  var par;
  var vertex;
  
  par = coordObj[3].split(",");
  vertex = new Vertex(par[0], par[1]);
  vertex.index = 0;
  feature.vertices.push(vertex);
  
  par = coordObj[0].split(",");
  vertex = new Vertex(par[0], par[1]);
  vertex.index = 1;
  feature.vertices.push(vertex);
  
  par = coordObj[1].split(",");
  vertex = new Vertex(par[0], par[1]);
  vertex.index = 2;
  feature.vertices.push(vertex);
  
  par = coordObj[2].split(",");
  vertex = new Vertex(par[0], par[1]);
  vertex.index = 3;
  feature.vertices.push(vertex);
  
  par = coordObj[3].split(",");
  vertex = new Vertex(par[0], par[1]);
  vertex.index = 4;
  feature.vertices.push(vertex);

}

Map.prototype.getPdfFeature = function(aDisplay) {
  var feature = null;
  for (var i=0; i < this.currentLayer.features.length; i++) { 
    if (this.currentLayer.features[i].id == "pdf_overview") {
      feature = this.currentLayer.features[i];
    }
  }
  
  if (feature == null) {
    var feature = new Feature("POLYGON((0 0 1 1))");
    this.form2PdfFeature(feature, aDisplay);

    feature.id = "pdf_overview";
    this.currentLayer.addFeature(feature);
  }  
  return feature;
}

/**
  * Comprueba que el area a exportar a dibujar en pantalla no sea mayor que
  * el contenedor del mapa
  * @param feature feaure
  * @param aDisplay display object
  * @author Armando
  */
Map.prototype.checkPdfFeature = function(feature, aDisplay) {
  var mapcSIx = this.extent.xmin;
  var mapcSIy = this.extent.ymax;
  var mapcIDx = this.extent.xmax;
  var mapcIDy = this.extent.ymin;
  var boxcSIx = feature.vertices[1].x;
  var boxcSIy = feature.vertices[1].y;
  var boxcIDx = feature.vertices[3].x;
  var boxcIDy = feature.vertices[3].y;
  if (mapcSIx > boxcSIx || mapcSIy < boxcSIy ||
                           mapcIDx < boxcIDx || mapcIDy > boxcIDy)
    return false;
  return true;
}

/** Cambia las coordenadas del area a exportar
  * @param feature feaure
  * @param aDisplay display object
  * @author Armando
  */
Map.prototype.changePdfFeature = function(cSIx, cSIy, cIDx, cIDy) {

  var aDisplay = this.getDisplay(mainmapid);
  var feature = this.getPdfFeature(aDisplay);

  feature.vertices[0].x = cSIx;
  feature.vertices[0].y = cIDy;
  feature.vertices[1].x = cSIx; // param
  feature.vertices[1].y = cSIy; // param
  feature.vertices[2].x = cIDx;
  feature.vertices[2].y = cSIy;
  feature.vertices[3].x = cIDx; // param
  feature.vertices[3].y = cIDy; // param
  feature.vertices[4].x = cSIx;
  feature.vertices[4].y = cIDy;

  var dist_x = feature.vertices[1].x - feature.vertices[2].x;
  var dist_y = feature.vertices[1].y - feature.vertices[2].y;
  var medidaH = Math.sqrt(dist_x * dist_x + dist_y * dist_y);
  medidaH = medidaH*30*3600*1000;
  dist_x = feature.vertices[1].x - feature.vertices[0].x;
  dist_y = feature.vertices[1].y - feature.vertices[0].y;
  var medidaV = Math.sqrt(dist_x * dist_x + dist_y * dist_y);
  medidaV = medidaV*30*3600*1000;

  myform.medidaH_box.value = medidaH;
  myform.medidaV_box.value = medidaV;

  actualizarEscalaPdf();

  // enviar las coordenadas del centro (Feature.getCentroid) al formulario
  var center = feature.getCentroid();
  myform.pdfMapCenterX.value = center.vertices[0].x;
  myform.pdfMapCenterY.value = center.vertices[0].y;

  //mainmap.updatePdfFeature('map');
  this.hidePdfFeature(mainmapid);
  if (!this.checkPdfFeature(feature, aDisplay)){
    mainmap.pdfRecenter();
  }
  else
    this.showPdfFeature(mainmapid);

}

Map.prototype.hidePdfFeature = function(aDisplayName) {

/*
  var aLayer = xGetElementById('map_drawing');
  aLayer.innerHTML = '';
*/
  var aDisplay = this.getDisplay(aDisplayName);

  var feature = this.getPdfFeature(aDisplay);
  if (aDisplay.getDisplayFeature(feature) != null) {
    var pdfLayer = xGetElementById(aDisplay.id + "_drawing"); // see Map.prototype.pdfrotate
    var removedNode = pdfLayer.removeChild(aDisplay.getDisplayFeature(feature));
    delete removedNode;
  }
}

Map.prototype.showPdfFeature = function(aDisplayName) {
  var aDisplay = this.getDisplay(aDisplayName);
  var feature = this.getPdfFeature(aDisplay);
  if (aDisplay.getDisplayFeature(feature) == null) {
    aDisplay.drawFeature(aDisplay.currentLayer, feature, _OFF, false);     
  }
  // Adicionado (Armando)
  updatePdfCoordInterface();
}

Map.prototype.updatePdfFeature = function(aDisplayName) {
  this.hidePdfFeature(aDisplayName);
  var aDisplay = this.getDisplay(aDisplayName);
  var feature = this.getPdfFeature(aDisplay);
  this.form2PdfFeature(feature, aDisplay);

  // Adicionado (Armando)

  if (!this.checkPdfFeature(feature, aDisplay)){
    mainmap.pdfRecenter();
  } else
    this.showPdfFeature(aDisplayName);

}

Map.prototype.removePdfFeature = function(aDisplayName) {
  this.hidePdfFeature(aDisplayName);
  var aDisplay = this.getDisplay(aDisplayName);
  var feature = this.getPdfFeature(aDisplay);
  this.currentLayer.features.pop(feature);  
}

/**
* remove feature and reset angle and position, redisplay new feature centered with angle = 0
*/
Map.prototype.resetPdfFeature = function(aDisplayName) {
  this.removePdfFeature(aDisplayName);
  // reset angle and center
  myform.pdfMapAngle.value = null;
  myform.pdfMapCenterX.value = null;
  myform.pdfMapCenterY.value = null;
  updatePdfAngleInterface(0);

  this.showPdfFeature(aDisplayName);
}

Map.prototype.pdfrotate = function(aDisplay) {
  this.resetMapEventHandlers();

  this.setCurrentLayer('drawing');
  this.getDisplay(aDisplay).currentLayer = xGetElementById(this.getDisplay(aDisplay).id + "_" + this.getDisplay(aDisplay)._map.currentLayer.id);
  this.getDisplay(aDisplay).mouseAction = new RotateFeatureTool(this.getDisplay(aDisplay));

  // reset current display dmpts (solve bug of feature going crazy after changing scale (bug id 1685))
  delete this.getDisplay(aDisplay).dmpts;

  // Adicionado (Armando)

  var feature = this.getPdfFeature(this.getDisplay(aDisplay));
  var renderBox = mainmap.checkPdfFeature(feature, aDisplay);
  if (!renderBox){
//     Ext.Msg.alert('Informaci&oacute;n',
//                 "La zona a exportar queda fuera del mapa. "
//                 + "El zoom se ajustara para que se muestre completamente.");
    this.boxInViewport(feature, aDisplay);
    // send center coords (Feature.getCentroid), angle to the form
    var center = feature.getCentroid();
    myform.pdfMapCenterX.value = center.vertices[0].x;
    myform.pdfMapCenterY.value = center.vertices[0].y;
    myform.pdfMapAngle.value = this.getDisplay(aDisplay).angle;

    this.showPdfFeature(aDisplay);
  }
  else {
    this.showPdfFeature(aDisplay);
  }

  this.onFeatureSelected = function(aFeature) {
    // hide pdf_overview
    emptyForm();
  }
  
  this.onFeatureChange = function(aFeature) {

    var feature = aFeature;
    var fuera = false;

    // Adicionado (Armando)

    var xmin = this.getDisplay(aDisplay)._map.extent.xmin;
    var xmax = this.getDisplay(aDisplay)._map.extent.xmax;
    var ymin = this.getDisplay(aDisplay)._map.extent.ymin;
    var ymax = this.getDisplay(aDisplay)._map.extent.ymax;

    if (xmin < mapminx) xmin = mapminx;
    if (ymin < mapminy) ymin = mapminy;
    if (xmax > mapmaxx) xmax = mapmaxx;
    if (ymax > mapmaxy) xmay = mapmaxy;

    for (var i = 0; i < feature.vertices.length; i++) {
      if (feature.vertices[i].x > xmax) { fuera = true; break; }
      if (feature.vertices[i].x < xmin) { fuera = true; break; }
      if (feature.vertices[i].y > ymax) { fuera = true; break; }
      if (feature.vertices[i].y < ymin) { fuera = true; break; }
    }

    if (fuera) {
      this.removePdfFeature(mainmapid);

      this.getDisplay(aDisplay).angle = parseFloat(myform.pdfMapAngle.value);
      if (isNaN(this.getDisplay(aDisplay).angle)) {
        this.getDisplay(aDisplay).angle = 0;
      }
      var cx = parseFloat(myform.pdfMapCenterX.value);
      var cy = parseFloat(myform.pdfMapCenterY.value);
      if (isNaN(cx) || isNaN(cy)) {
        cx = (xmax + xmin) / 2;
        cy = (ymax + ymin) / 2;
      }
      for (var i = 0; i < feature.vertices.length; i++) {
        feature.vertices[i].x = feature.vertices[i].x + cx;
        feature.vertices[i].y = feature.vertices[i].y + cy;
      }
      feature.rotate(aDisplay.angle);
      this.showPdfFeature(mainmapid);
    } else {
      // send center coords (Feature.getCentroid), angle to the form
      var center = aFeature.getCentroid();
      myform.pdfMapCenterX.value = center.vertices[0].x;
      myform.pdfMapCenterY.value = center.vertices[0].y;
      myform.pdfMapAngle.value = this.getDisplay(aDisplay).angle;

      updatePdfCoordInterface();
    }
  }

  this.onToolUnset = function() {
      if(VExpImpresion){ VExpImpresion.hide(); } // Armando
  }
}

/*
 * Rotate pdf feature by x degree
 * @param float angledegree
 * @param bool absolute, ignore feature current angle
 */
Map.prototype.rotatePdfFeature = function(angledegree, absolute) {

  // convert degree to radian
  var anglerad = angledegree * Math.PI / 180;

  // update current angle
  if (!absolute) {
    var currentangle = this.getDisplay(mainmapid).angle;
    var nangle = currentangle + anglerad;
  } else {
    var nangle = anglerad;
  }

  // update stored angle
  myform.pdfMapAngle.value = nangle;

  // update interface
  updatePdfAngleInterface(nangle);

  // update feature
  this.updatePdfFeature(mainmapid);
}

/**
 * update pdf angle interface
 * @param float angle (rad)
 */
function updatePdfAngleInterface(angle) {
  var elm = Ext.getCmp('txfAngulo');
  if (elm){
    angledegree = angle * 180 / Math.PI;
    if (angledegree < 0) {
      angledegree = 360 + angledegree;
    }
    elm.setValue(Math.round(angledegree));
  }

  // No permitir cambio de coordenadas por textbox si esta rotada el area

  var fieldSIXg = xGetElementById('txbCoordSIXg');
  var fieldSIXm = xGetElementById('txbCoordSIXm');
  var fieldSIXs = xGetElementById('txbCoordSIXs');

  var fieldSIYg = xGetElementById('txbCoordSIYg');
  var fieldSIYm = xGetElementById('txbCoordSIYm');
  var fieldSIYs = xGetElementById('txbCoordSIYs');

  var fieldIDXg = xGetElementById('txbCoordIDXg');
  var fieldIDXm = xGetElementById('txbCoordIDXm');
  var fieldIDXs = xGetElementById('txbCoordIDXs');

  var fieldIDYg = xGetElementById('txbCoordIDYg');
  var fieldIDYm = xGetElementById('txbCoordIDYm');
  var fieldIDYs = xGetElementById('txbCoordIDYs');
  
  if (fieldSIXg != null && fieldSIXm != null && fieldSIXs != null &&
              fieldSIYg != null && fieldSIYm != null && fieldSIYs != null &&
              fieldIDXg != null && fieldIDXm != null && fieldIDXs != null &&
              fieldIDYg != null && fieldIDYm != null && fieldIDYs != null ){
    if (angle != 0){
      fieldSIXg.disable();
      fieldSIXm.disable();
      fieldSIXs.disable();
      fieldSIYg.disable();
      fieldSIYm.disable();
      fieldSIYs.disable();
      fieldIDXg.disable();
      fieldIDXm.disable();
      fieldIDXs.disable();
      fieldIDYg.disable();
      fieldIDYm.disable();
      fieldIDYs.disable();
    }
    else{
      fieldSIXg.enable();
      fieldSIXm.enable();
      fieldSIXs.enable();
      fieldSIYg.enable();
      fieldSIYm.enable();
      fieldSIYs.enable();
      fieldIDXg.enable();
      fieldIDXm.enable();
      fieldIDXs.enable();
      fieldIDYg.enable();
      fieldIDYm.enable();
      fieldIDYs.enable();
    }
  }
}

/**
  * Construye un box (y la geometria respectiva) visible en el viewport
  * @author Armando Batista
  */
Map.prototype.boxInViewport = function(feature, aDisplay) {
    var marginH = (this.extent.xmax - this.extent.xmin)/10;
    var marginV = (this.extent.ymax - this.extent.ymin)/10;

    var x0box = mapminx + marginH;
    var y0box = mapminy + marginV;
    var x1box = mapminx + marginH;
    var y1box = mapmaxy - marginV;
    var x2box = mapmaxx - marginH;
    var y2box = mapmaxy - marginV;
    var x3box = mapmaxx - marginH;
    var y3box = mapminy + marginV;

    if (this.extent.xmin > mapminx) x0box = x1box = this.extent.xmin + marginH;
    if (this.extent.ymin > mapminy) y0box = y3box = this.extent.ymin + marginV;
    if (this.extent.xmax < mapmaxx) x2box = x3box = this.extent.xmax - marginH;
    if (this.extent.ymax < mapmaxy) y1box = y2box = this.extent.ymax - marginV;

    var x4box = x0box;
    var y4box = y0box;

    feature.vertices = Array();
    var vertex;
    vertex = new Vertex(x0box, y0box);
    vertex.index = 0;
    feature.vertices.push(vertex);
    vertex = new Vertex(x1box, y1box);
    vertex.index = 1;
    feature.vertices.push(vertex);
    vertex = new Vertex(x2box, y2box);
    vertex.index = 2;
    feature.vertices.push(vertex);
    vertex = new Vertex(x3box, y3box);
    vertex.index = 3;
    feature.vertices.push(vertex);
    vertex = new Vertex(x4box, y4box);
    vertex.index = 4;
    feature.vertices.push(vertex);

    aDisplay.angle = 0;

    var dist_x = feature.vertices[1].x - feature.vertices[2].x;
    var dist_y = feature.vertices[1].y - feature.vertices[2].y;
    var medidaH = Math.sqrt(dist_x * dist_x + dist_y * dist_y);
    medidaH = medidaH*30*3600*1000;
    dist_x = feature.vertices[1].x - feature.vertices[0].x;
    dist_y = feature.vertices[1].y - feature.vertices[0].y;
    var medidaV = Math.sqrt(dist_x * dist_x + dist_y * dist_y);
    medidaV = medidaV*30*3600*1000;

    myform.medidaH_box.value = medidaH;
    myform.medidaV_box.value = medidaV;

    actualizarEscalaPdf();
}

/** Actualiza las coordenadas del area a exportar en la interfaz
  * @param 
  * @author Armando
  */
function updatePdfCoordInterface() {
  var fieldSIXg = xGetElementById('txbCoordSIXg');
  var fieldSIXm = xGetElementById('txbCoordSIXm');
  var fieldSIXs = xGetElementById('txbCoordSIXs');
  
  var fieldSIYg = xGetElementById('txbCoordSIYg');
  var fieldSIYm = xGetElementById('txbCoordSIYm');
  var fieldSIYs = xGetElementById('txbCoordSIYs');
  
  var fieldIDXg = xGetElementById('txbCoordIDXg');
  var fieldIDXm = xGetElementById('txbCoordIDXm');
  var fieldIDXs = xGetElementById('txbCoordIDXs');

  var fieldIDYg = xGetElementById('txbCoordIDYg');
  var fieldIDYm = xGetElementById('txbCoordIDYm');
  var fieldIDYs = xGetElementById('txbCoordIDYs');

  var aDisplay = mainmap.getDisplay(mainmapid);
  var feature = mainmap.getPdfFeature(aDisplay);

  var f1x = feature.vertices[1].x;
  var f1y = feature.vertices[1].y;
  var f3x = feature.vertices[3].x;
  var f3y = feature.vertices[3].y;

  var gf1x = parseInt(f1x);
  var mf1x = parseInt((Mod(f1x) - Mod(gf1x)) * 60);
  var sf1x = (((Mod(f1x) - Mod(gf1x)) * 60) - Mod(mf1x)) * 60;
  sf1x = Redondear(sf1x);

  var gf1y = parseInt(f1y);
  var mf1y = parseInt((Mod(f1y) - Mod(gf1y)) * 60);
  var sf1y = (((Mod(f1y) - Mod(gf1y)) * 60) - Mod(mf1y)) * 60;
  sf1y = Redondear(sf1y);

  var gf3x = parseInt(f3x);
  var mf3x = parseInt((Mod(f3x) - Mod(gf3x)) * 60);
  var sf3x = (((Mod(f3x) - Mod(gf3x)) * 60) - Mod(mf3x)) * 60;
  sf3x = Redondear(sf3x);

  var gf3y = parseInt(f3y);
  var mf3y = parseInt((Mod(f3y) - Mod(gf3y)) * 60);
  var sf3y = (((Mod(f3y) - Mod(gf3y)) * 60) - Mod(mf3y)) * 60;
  sf3y = Redondear(sf3y);

  if (fieldSIXg != null && fieldSIXm != null && fieldSIXs != null &&
              fieldSIYg != null && fieldSIYm != null && fieldSIYs != null &&
              fieldIDXg != null && fieldIDXm != null && fieldIDXs != null &&
              fieldIDYg != null && fieldIDYm != null && fieldIDYs != null ){
    fieldSIXg.value = gf1x;
    fieldSIXm.value = mf1x;
    fieldSIXs.value = sf1x;
    fieldSIYg.value = gf1y;
    fieldSIYm.value = mf1y;
    fieldSIYs.value = sf1y;
    fieldIDXg.value = gf3x;
    fieldIDXm.value = mf3x;
    fieldIDXs.value = sf3x;
    fieldIDYg.value = gf3y;
    fieldIDYm.value = mf3y;
    fieldIDYs.value = sf3y;
  }
}

function validaPdfXCoordInterface() {
    var X1g = Ext.getCmp('txbCoordSIXg');
    var X2g = Ext.getCmp('txbCoordIDXg');
    var X1m = Ext.getCmp('txbCoordSIXm');
    var X2m = Ext.getCmp('txbCoordIDXm');
    var X1s = Ext.getCmp('txbCoordSIXs');
    var X2s = Ext.getCmp('txbCoordIDXs');

    var valX1g = parseFloat(Ext.getCmp('txbCoordSIXg').getValue());
    var valX2g = parseFloat(Ext.getCmp('txbCoordIDXg').getValue());
    var valX1m = parseFloat(Ext.getCmp('txbCoordSIXm').getValue());
    var valX2m = parseFloat(Ext.getCmp('txbCoordIDXm').getValue());
    var valX1s = parseFloat(Ext.getCmp('txbCoordSIXs').getValue());
    var valX2s = parseFloat(Ext.getCmp('txbCoordIDXs').getValue());

    var valX1 = coordGMS2coordGD(valX1g, valX1m, valX1s);
    var valX2 = coordGMS2coordGD(valX2g, valX2m, valX2s);


    if (Redondear(valX1, 4) < Redondear(mapminx, 4)) {
        X1g.markInvalid();
        X1g.invalidText = "La coordenada X1 debe ser mayor que "
                        + GD2GMS(mapminx) + ".";
        X1m.markInvalid();
        X1m.invalidText = "La coordenada X1 debe ser mayor que "
                        + GD2GMS(mapminx) + ".";
        X1s.markInvalid();
        X1s.invalidText = "La coordenada X1 debe ser mayor que "
                        + GD2GMS(mapminx) + ".";
        return false;
    }

    if (Redondear(valX2, 4) > Redondear(mapmaxx, 4)) {
        X2g.markInvalid();
        X2g.invalidText = "La coordenada X2 debe ser menor que "
                        + GD2GMS(mapmaxx) + ".";
        X2m.markInvalid();
        X2m.invalidText = "La coordenada X2 debe ser menor que "
                        + GD2GMS(mapmaxx) + ".";
        X2s.markInvalid();
        X2s.invalidText = "La coordenada X2 debe ser menor que "
                        + GD2GMS(mapmaxx) + ".";
        return false;
    }

    if (valX1 == valX2) {
        X1g.markInvalid();
        X1g.invalidText = "El valor debe ser menor que "
                        + valX2g + ".";
        X2g.markInvalid();
        X2g.invalidText = "El valor debe ser mayor que "
                        + valX1g + ".";
        X1m.markInvalid();
        X1m.invalidText = "El valor debe ser mayor que "
                        + valX2m + ".";
        X2m.markInvalid();
        X2m.invalidText = "El valor debe ser menor que "
                        + valX1m + ".";
        X1s.markInvalid();
        X1s.invalidText = "El valor debe ser mayor que "
                        + valX2s + ".";
        X2s.markInvalid();
        X2s.invalidText = "El valor debe ser menor que "
                        + valX1s + ".";
        return false;
    }
    if (valX1 >= valX2) {
        if (valX1g >= valX2g) {
            if (valX1g > valX2g) {
                X1g.markInvalid();
                X1g.invalidText = "El valor debe ser menor o igual que "
                                + valX2g + ".";
                X2g.markInvalid();
                X2g.invalidText = "El valor debe ser mayor o igual que "
                                + valX1g + ".";
                X1m.clearInvalid();
                X2m.clearInvalid();
                X1s.clearInvalid();
                X2s.clearInvalid();
                return false;
            }
            else {
                if (valX1m <= valX2m) {
                    if (valX1m < valX2m) {
                        X1m.markInvalid();
                        X1m.invalidText = "El valor debe ser mayor o igual que "
                                        + valX2m + ".";
                        X2m.markInvalid();
                        X2m.invalidText = "El valor debe ser menor o igual que "
                                        + valX1m + ".";
                        X1g.clearInvalid();
                        X2g.clearInvalid();
                        X1s.clearInvalid();
                        X2s.clearInvalid();
                        return false;
                    }
                    else {
                        if (valX1s < valX2s) {
                            X1s.markInvalid();
                            X1s.invalidText = "El valor debe ser mayor que "
                                            + valX2s + ".";
                            X2s.markInvalid();
                            X2s.invalidText = "El valor debe ser menor que "
                                            + valX1s + ".";
                            X1g.clearInvalid();
                            X2g.clearInvalid();
                            X1m.clearInvalid();
                            X2m.clearInvalid();
                            return false;
                        }
                    }
                }
            }
        }
    }
    else {
      X1g.clearInvalid();
      X2g.clearInvalid();
      X1m.clearInvalid();
      X2m.clearInvalid();
      X1s.clearInvalid();
      X2s.clearInvalid();
      return true;
    }
}

function validaPdfYCoordInterface() {
    var Y1g = Ext.getCmp('txbCoordSIYg');
    var Y2g = Ext.getCmp('txbCoordIDYg');
    var Y1m = Ext.getCmp('txbCoordSIYm');
    var Y2m = Ext.getCmp('txbCoordIDYm');
    var Y1s = Ext.getCmp('txbCoordSIYs');
    var Y2s = Ext.getCmp('txbCoordIDYs');

    var valY1g = parseFloat(Ext.getCmp('txbCoordSIYg').getValue());
    var valY2g = parseFloat(Ext.getCmp('txbCoordIDYg').getValue());
    var valY1m = parseFloat(Ext.getCmp('txbCoordSIYm').getValue());
    var valY2m = parseFloat(Ext.getCmp('txbCoordIDYm').getValue());
    var valY1s = parseFloat(Ext.getCmp('txbCoordSIYs').getValue());
    var valY2s = parseFloat(Ext.getCmp('txbCoordIDYs').getValue());

    var valY1 = coordGMS2coordGD(valY1g, valY1m, valY1s);
    var valY2 = coordGMS2coordGD(valY2g, valY2m, valY2s);

    if (valY1 > mapmaxy) {
        Y1g.markInvalid();
        Y1g.invalidText = "La coordenada Y1 debe ser menor que "
                        + GD2GMS(mapmaxy) + ".";
        Y1m.markInvalid();
        Y1m.invalidText = "La coordenada Y1 debe ser menor que "
                        + GD2GMS(mapmaxy) + ".";
        Y1s.markInvalid();
        Y1s.invalidText = "La coordenada Y1 debe ser menor que "
                        + GD2GMS(mapmaxy) + ".";
        return false;
    }

    if (valY2 < mapminy) {
        Y2g.markInvalid();
        Y2g.invalidText = "La coordenada Y2 debe ser mayor que "
                        + GD2GMS(mapminy) + ".";
        Y2m.markInvalid();
        Y2m.invalidText = "La coordenada Y2 debe ser mayor que "
                        + GD2GMS(mapminy) + ".";
        Y2s.markInvalid();
        Y2s.invalidText = "La coordenada Y2 debe ser mayor que "
                        + GD2GMS(mapminy) + ".";
        return false;
    }

    if (valY1 == valY2) {
        Y1g.markInvalid();
        Y1g.invalidText = "El valor debe ser mayor que "
                        + valY2g + ".";
        Y2g.markInvalid();
        Y2g.invalidText = "El valor debe ser menor que "
                        + valY1g + ".";
        Y1m.markInvalid();
        Y1m.invalidText = "El valor debe ser menor que "
                        + valY2m + ".";
        Y2m.markInvalid();
        Y2m.invalidText = "El valor debe ser mayor que "
                        + valY1m + ".";
        Y1s.markInvalid();
        Y1s.invalidText = "El valor debe ser menor que "
                        + valY2s + ".";
        Y2s.markInvalid();
        Y2s.invalidText = "El valor debe ser mayor que "
                        + valY1s + ".";
        return false;
    }
    if (valY1 <= valY2) {
        if (valY1g <= valY2g) {
            if (valY1g < valY2g) {
                Y1g.markInvalid();
                Y1g.invalidText = "El valor debe ser mayor o igual que "
                                + valY2g + ".";
                Y2g.markInvalid();
                Y2g.invalidText = "El valor debe ser menor o igual que "
                                + valY1g + ".";
                Y1m.clearInvalid();
                Y2m.clearInvalid();
                Y1s.clearInvalid();
                Y2s.clearInvalid();
                return false;
            }
            else {
                if (valY1m <= valY2m) {
                    if (valY1m < valY2m) {
                        Y1m.markInvalid();
                        Y1m.invalidText = "El valor debe ser mayor o igual que "
                                        + valY2m + ".";
                        Y2m.markInvalid();
                        Y2m.invalidText = "El valor debe ser menor o igual que "
                                        + valY1m + ".";
                        Y1g.clearInvalid();
                        Y2g.clearInvalid();
                        Y1s.clearInvalid();
                        Y2s.clearInvalid();
                        return false;
                    }
                    else {
                        if (valY1s < valY2s) {
                            Y1s.markInvalid();
                            Y1s.invalidText = "El valor debe ser mayor que "
                                            + valY2s + ".";
                            Y2s.markInvalid();
                            Y2s.invalidText = "El valor debe ser menor que "
                                            + valY1s + ".";
                            Y1g.clearInvalid();
                            Y2g.clearInvalid();
                            Y1m.clearInvalid();
                            Y2m.clearInvalid();
                            return false;
                        }
                    }
                }
            }
        }
    }
    else {
      Y1g.clearInvalid();
      Y2g.clearInvalid();
      Y1m.clearInvalid();
      Y2m.clearInvalid();
      Y1s.clearInvalid();
      Y2s.clearInvalid();
      return true;
    }
}

/** Convierte tres valores (g, m, s) a decimal
  * @param coordG
  * @param coordM
  * @param coordS
  * @author Armando
  */
function coordGMS2coordGD(coordG, coordM, coordS){

    var coordD = Mod(coordG) + coordM/60 + coordS/3600;
    if (coordG < 0) coordD = coordD * -1;

    return coordD;
}

/** Actualiza el box cuando se modifican los campos de texto de las coordenadas
  * @param dimMy
  * @param dimMn
  * @author Armando
  */
function actualizarBoxPorFormulario(){
    var fieldSIXg = parseFloat(Ext.get('txbCoordSIXg').getValue());
    var fieldSIXm = parseFloat(Ext.get('txbCoordSIXm').getValue());
    var fieldSIXs = parseFloat(Ext.get('txbCoordSIXs').getValue());

    var fieldSIYg = parseFloat(Ext.get('txbCoordSIYg').getValue());
    var fieldSIYm = parseFloat(Ext.get('txbCoordSIYm').getValue());
    var fieldSIYs = parseFloat(Ext.get('txbCoordSIYs').getValue());

    var fieldIDXg = parseFloat(Ext.get('txbCoordIDXg').getValue());
    var fieldIDXm = parseFloat(Ext.get('txbCoordIDXm').getValue());
    var fieldIDXs = parseFloat(Ext.get('txbCoordIDXs').getValue());

    var fieldIDYg = parseFloat(Ext.get('txbCoordIDYg').getValue());
    var fieldIDYm = parseFloat(Ext.get('txbCoordIDYm').getValue());
    var fieldIDYs = parseFloat(Ext.get('txbCoordIDYs').getValue());

    var f1x = coordGMS2coordGD(fieldSIXg, fieldSIXm, fieldSIXs);
    var f1y = coordGMS2coordGD(fieldSIYg, fieldSIYm, fieldSIYs);
    var f3x = coordGMS2coordGD(fieldIDXg, fieldIDXm, fieldIDXs);
    var f3y = coordGMS2coordGD(fieldIDYg, fieldIDYm, fieldIDYs);

    mainmap.changePdfFeature(f1x, f1y, f3x, f3y);
}

/** Actualiza la escala en relacion al tamanno del papel establecido
  * @param dimMy
  * @param dimMn
  * @author Armando
  */
function actualizarEscalaPdf(){

    var escala = 0;
    var mH = xGetElementById('pdfMargin' + myform.pdfFormat.value + 'x').value;
    var mV = xGetElementById('pdfMargin' + myform.pdfFormat.value + 'y').value;
    if (mH == "") mH = xGetElementById('pdfMarginX').value;
    if (mV == "") mV = xGetElementById('pdfMarginY').value;

    var paperx = xGetElementById('pdf' + myform.pdfFormat.value + 'x').value;
    var papery = xGetElementById('pdf' + myform.pdfFormat.value + 'y').value;

    paperx = paperx - 2 * mH;
    papery = papery - 2 * mV;

//     paperx = paperx;
//     papery = papery;

    if (document.getElementById('lsp').checked == true) {
      var papertmp = paperx;
      paperx = papery;
      papery = papertmp;
    }

    var medidaH = myform.medidaH_box.value;
    var medidaV = myform.medidaV_box.value;

//     alert("medidaH: " + medidaH + " medidaV: " + medidaV);
    var escalaH = medidaH/paperx;
    var escalaV = medidaV/papery;
    if (escalaH >= escalaV) escala = escalaH;
    else escala = escalaV;

    document.getElementById('pdfLibrex').value = medidaH/escala;
    document.getElementById('pdfLibrey').value = medidaV/escala;

    // Adicionar valor a select tpl (necesita cambio)
    var comboTpl = document.getElementById("pdfScale");
    var elOptNew = document.createElement('option');
    elOptNew.text = escala;
    elOptNew.value = escala;
    elOptNew.selected = 'selected';
    try {
      comboTpl.add(elOptNew, null); // standards compliant; doesn't work in IE
    }
    catch(ex) {
      comboTpl.add(elOptNew); // IE
    }

    if (document.getElementById("cb_scale"))
      document.getElementById("cb_scale").value = parseInt(escala); // combo ext
    //return escala;
}


/*
 * Recenter on pdf feature
 */
Map.prototype.pdfRecenter = function() {
  Logger.trace('pdfRecenter');
  // get current pdf caneva largest diagonal dimension
  var aDisplay = this.getDisplay(mainmapid);
  var feature = this.getPdfFeature(aDisplay);
  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.0;

  // 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
  CartoWeb.trigger('Location.Recenter', 'formItemSelected()');

}

/*
 * 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') {

      // Adicionado (Armando)

//       updatePdfCoordInterface();

      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);

  // Adicionado (Armando)
//   updatePdfCoordInterface();

}

RotateFeatureTool.prototype.onDrag = function(elt, x, y) {
    alert("fljghkfjvb");
};

RotateFeatureTool.prototype.onDragEnd = function(elt, x, y) {
  var aDisplay = elt._display;

  if (aDisplay.mode == 'rotate') {
      // Adicionado (Armando)

//       updatePdfCoordInterface();
      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;
}

