//
// Tool to facilitate dragging a zoom rectangle and zoom in or out depending
// on which button was used.
//
// Dependencies:
//
//    gtTool.js
//

gtToolZoom.prototype = new gtTool();  // Sets gtToolPan to be a subclass of gtTool!
gtToolZoom.prototype.constructor = gtTool;
gtToolZoom.superclass = gtTool.prototype;


function gtToolZoom()
{
  // Member variables
  this.m_map          = null;  // The map (document, canvas, selection, etc) to operate upon.
  this.m_zoomin       = true;  // The default action of a left click, and is here to enable separate
                               // zoomin and zoomout tools for the user.
  this.m_startX       = 0;
  this.m_startY       = 0;
  this.m_button_down  = false;
  this.m_rect         = null;

  this.m_clickLimit   = 10;
} // end gtToolZoom() Constructor



// Methods

gtToolZoom.prototype.deselect = function(map, next)
{
  this.m_button_down = false;
}; // end deselect()


gtToolZoom.prototype.select = function(map, prev)
{
  this.m_map = map; // Assumed to be an IFRAME augmented with calling gtBeMapJS() on it...
  this.m_map.setCursor("crosshair");
} // end select()



gtToolZoom.prototype.buttonDown = function(evt)
{
  // The template-based maps we use here are reloaded after each zoom-operation.
  // At the same time the zoom-rectangle is also reloaded, so we must obtain
  // pointers to these objects every time we press the mouse button!
  this.m_img          = this.m_map.m_img;
  this.m_rect         = this.m_map.m_rect;
  this.m_rect.m_tool  = this; // Point back to me! (used in rect's event handlers)

  // Forward rectangle's event handlers to the tool
  addGTHandlers(this.m_rect);
  
  // Since this tool is used by both template based and image based maps, we must make sure
  // it works for both...
  // If this is not image based, we must create a stub method relEvt() in the map image which
  // will be called from the event handlers below.
  if (this.m_img != this.m_map)
  {
    this.m_img.relEvt = function gtMapJS_relEvt(evt)
    {
      return evt;
    }; // end relEvt()
  }
  
  this.m_rect.m_img = this.m_img;
  this.m_rect.gtMouseDown = function(evt) { this.m_img.relEvt(evt); this.m_tool.buttonDown(evt); };
  this.m_rect.gtMouseUp   = function(evt) { this.m_img.relEvt(evt); this.m_tool.buttonUp  (evt); };
  this.m_rect.gtMouseMove = function(evt) { this.m_img.relEvt(evt); this.m_tool.mouseMove (evt); };

  // Set some constant attributes on the rectangle
  this.m_rect.style.padding = 0;
  this.m_rect.style.margin  = 0;
  this.m_rect.style.cursor  = this.m_img.style.cursor;


  this.m_button_down = true;

  gtSetVisibility (this.m_rect, "visible");
  gtSetLeft       (this.m_rect, evt.gtX);
  gtSetTop        (this.m_rect, evt.gtY);
  gtSetWidth      (this.m_rect, 0);
  gtSetHeight     (this.m_rect, 0);

  this.m_startX = evt.gtX;
  this.m_startY = evt.gtY;

  gtCancelBubble(evt);
  return gtPreventDefault(evt);
}; // end buttonDown()



gtToolZoom.prototype.mouseMove = function(evt)
{
  if (this.m_button_down)
  {
    var x = evt.gtX;
    var y = evt.gtY;
    gtSetWidth  (this.m_rect, Math.abs(this.m_startX - x));
    gtSetHeight (this.m_rect, Math.abs(this.m_startY - y));
    gtSetLeft   (this.m_rect, Math.min(x, this.m_startX));
    gtSetTop    (this.m_rect, Math.min(y, this.m_startY));
  }
  gtCancelBubble(evt);
  return gtPreventDefault(evt);
}; // end mouseMove()



gtToolZoom.prototype.buttonUp = function(evt)
{
  this.m_button_down = false;
  gtSetVisibility (this.m_rect, "hidden");

  var x = evt.gtX;
  var y = evt.gtY;

  var w = Math.abs(this.m_startX - x);
  var h = Math.abs(this.m_startY - y);

//  document.title = "button: " + evt.gtButton;

  var zoomin = this.m_zoomin ? (evt.gtButton < 2) : (evt.gtButton == 2);
  if (w < this.m_clickLimit && h < this.m_clickLimit)
  {
    if (zoomin)
      zf = 0.5;
    else
      zf = 2;
  }
  else
  {
    var zf = (w + h) / (this.m_img.width + this.m_img.height);
    if (!zoomin)
      zf = 1 / zf;
  }

  var url = this.m_map.m_url;

  // Ensure that map scale is still "nice"
  var old_scale = parseFloat(url.getParam("s"));
//  var new_scale = niceScale(old_scale * zf);
  var new_scale = old_scale * zf;
  zf = new_scale / old_scale;

//  document.title = "w: " + w + ", h:" + h + ", new_scale: " + new_scale + ", old_scale: " + old_scale + ", zf: " + zf;

  url.setParam("cmd",   "zoomin");
  url.setParam("map.x", (this.m_startX + x) / 2);
  url.setParam("map.y", (this.m_startY + y) / 2);
  url.setParam("zf",    zf);
  this.m_map.showMap(url);
  gtCancelBubble(evt);
  return gtPreventDefault(evt);
}; // end buttonUp()


gtToolZoom.prototype.click = function(evt)
{
  gtCancelBubble(evt);
  return gtPreventDefault(evt);
} // end click()


// This tool does not depend on the current selection!
gtToolZoom.prototype.canHandleSelection = function (selection) { return true; };


