/*
* Script:   czoom.js
* Class:    CZoom
* Author:   UMG
* Requires: browser.js, crect.js
* Descrpition: Zoom/pan feedback class.
*/

// constructor
function CZoom() {
  this.extent        = new CRect();
  this.imgHeight     = 0;
  this.imgWidth      = 0;
  this.isActive      = false;
  this.method        = ""
  this.rect          = new CRect();
  this.leftOffset    = 0;
  this.topOffset     = 0;

  this.feedbackMove  = _czoomFeedbackMove;
  this.feedbackStart = _czoomFeedbackStart;
  this.feedbackStop  = _czoomFeedbackStop;
  this.initElements  = _czoomInitElements;
  this.validate      = _czoomValidate
  this.zoomFeedback  = _czoomZoomFeedback

  this._downX  = 0;
  this._downY  = 0;
  this._img    = null;
  this._els    = new Array();
  this._nms    = new Array("tzl","tzr","tzt","tzb");
  this._clip   = _czoomClip;
  this._toggle = _czoomToggle;
}

function _czoomClip() {
  var r = this.rect.makeNormalized();
  var nX = this.leftOffset, nY = this.topOffset, nW = 1;
  browserClipElement(this._els[2],r.left+nX,    r.top+nY,      r.right+nX,  r.top+nY+nW);
  browserClipElement(this._els[0],r.left+nX,    r.top+nY,      r.left+nX+nW,r.bottom+nY);
  browserClipElement(this._els[1],r.right+nX-nW,r.top+nY,      r.right+nX,  r.bottom+nY);
  browserClipElement(this._els[3],r.left+nX,    r.bottom+nY-nW,r.right+nX,  r.bottom+nY);
}

function _czoomInitElements(sMapImgTag,sTran,nLeft,nTop,nWidth,nHeight) {
  var i, sImg = "<img src=\""+sTran+"\" width=1 height=1>";
  this.leftOffset = nLeft;
  this.topOffset = nTop;
  this.imgWidth   = nWidth;
  this.imgHeight = nHeight;
  //alert(nLeft+"/"+nTop+"/"+nWidth+"/"+nHeight);
  for (i=0;i<4;i++) {
    browserCreateElement(this._nms[i],nLeft,nTop,nWidth,nHeight,false,sImg);
    this._els[i] = browserFindElement(this._nms[i]);
    browserSetBgColor(this._els[i],"red");
  }
  this._img = browserFindElement(sMapImgTag);
}

function _czoomFeedbackMove(nMouseX,nMouseY) {
  if (this.isActive) {
    this.rect.right = nMouseX; this.rect.bottom = nMouseY;
    if ((this.method == "zoomin") || (this.method == "zoomout")) {
       this._clip();
    } else {
      var nX = nMouseX-this._downX;
      var nY = nMouseY-this._downY;
      var el = this._img;
      if (el != null) browserMoveElement(el,nX,nY);
    }
  }
}

function _czoomFeedbackStart(sMethod,nMouseX,nMouseY) {
  this.method = sMethod; this.isActive = true;
  this._downX = nMouseX; this._downY = nMouseY;
  this.rect.put(nMouseX,nMouseX,nMouseY,nMouseY);
  if ((this.method == "zoomin") || (this.method == "zoomout")) {
    this._clip(); this._toggle(true);
  }
}

function _czoomFeedbackStop(nMouseX,nMouseY) {
  if (this.isActive) {
    this.isActive = false;
    if ((this.method == "zoomin") || (this.method == "zoomout")) {
      this._toggle(false); this.zoomFeedback();
    } else this.zoomFeedback();
  }
}

function _czoomToggle(bVisible) {
  var el;
  for (var i=0;i<4;i++) {el = this._els[i]; browserToggleElement(el,bVisible);}
}

function _czoomValidate(bInternal) {
  var n,nCen,nW,nH,nX,nY,nPctX,nPctY,nPct180L,nPct180R,nPct90T,nPct90B;

  // ensure that we aren't zoomed in to much
  nW = this.extent.getWidth(); nH = this.extent.getHeight();
  n = 0.001;
  if (!bInternal) n = 0.006;
  if (nW < n) {
    nCen = this.extent.left + (nW / 2);
    this.extent.left  = nCen - (n / 2);
    this.extent.right = nCen + (n / 2);
  }
  if (nH < n) {
    nCen = this.extent.bottom + (nH / 2);
    this.extent.bottom = nCen - (n / 2);
    this.extent.top    = nCen + (n / 2);
  }

  // ensure that we aren't zoomed out to much
  nW = this.extent.getWidth(); nH = this.extent.getHeight();
  n = 486;
  if (nW > n) {
    nCen = this.extent.left + (nW / 2);
    this.extent.left  = nCen + (n / 2);
    this.extent.right = nCen - (n / 2);
    this.extent.left = -243; this.extent.right = 243;
  }
  n = 360;
  if (nH > n) {
    nCen = this.extent.bottom + (nH / 2);
    this.extent.bottom = nCen + (n / 2);
    this.extent.top    = nCen - (n / 2);
    this.extent.top = 180; this.extent.bottom = -180
  }

  // ensure that a portion of the map is always visible
  nW = this.extent.getWidth(); nH = this.extent.getHeight();
  nPct180L = ((180 - this.extent.left) / nW);
  nPct180R = ((-180 - this.extent.left) / nW);
  nPct90B  = ((90 - this.extent.bottom) / nH);
  nPct90T  = ((-90 - this.extent.bottom) / nH);
  if (nPct180L < 0.2) {
    nPctX = (0.2 - nPct180L); nX = nPctX * nW;
    this.extent.right = this.extent.right - nX;
    this.extent.left  = this.extent.left - nX;
  } else if (nPct180R > 0.8) {
    nPctX = (nPct180R - 0.8); nX = nPctX * nW;
    this.extent.right = this.extent.right + nX;
    this.extent.left  = this.extent.left + nX;
  }
  if (nPct90B < 0.3) {
    nPctY = (0.3 - nPct90B); nY = nPctY * nH;
    this.extent.top    = this.extent.top - nY;
    this.extent.bottom = this.extent.bottom - nY;
  } else if (nPct90T > 0.7) {
    nPctY = (nPct90T - 0.7); nY = nPctY * nH;
    this.extent.top    = this.extent.top + nY;
    this.extent.bottom = this.extent.bottom + nY;
  }

}

function _czoomZoomFeedback() {
  var nX, nY;
  var r  = this.rect.makeNormalized();
  var nW = this.extent.getWidth();
  var nH = this.extent.getHeight();
  var nPixelX = nW / this.imgWidth;
  var nPixelY = nH / this.imgHeight;
  if (this.method == "pan") {
    var nX2 = this.rect.right - this.rect.left;
    var nY2 = this.rect.top   - this.rect.bottom;
    var nX  = nPixelX * nX2;
    var nY  = nPixelY * nY2;
    this.extent.left   = this.extent.left   - nX;
    this.extent.right  = this.extent.right  - nX;
    this.extent.top    = this.extent.top    - nY;
    this.extent.bottom = this.extent.bottom - nY;
  } else {
    if ((r.getWidth() < 2) && (r.getHeight() < 2)) {
      nX  = (nPixelX * r.left) + this.extent.left;
      nY  = (nPixelY * (this.imgHeight - r.bottom)) + this.extent.bottom;
      var nX2 = nW / 2;
      var nY2 = nH / 2;
      var nFactor = 2;
      if (this.method == "zoomin") {
        this.extent.left   = nX - (nX2/nFactor);
        this.extent.right  = nX + (nX2/nFactor);
        this.extent.top    = nY + (nY2/nFactor);
        this.extent.bottom = nY - (nY2/nFactor);
      } else {
        this.extent.left   = nX - (nW*nFactor/2);
        this.extent.right  = nX + (nW*nFactor/2);
        this.extent.top    = nY + (nH*nFactor/2);
        this.extent.bottom = nY - (nH*nFactor/2);
      }
    } else {
      if (this.method == "zoomin") {
        var nLeft = this.extent.left, nTop = this.extent.top;
        this.extent.left   = (nPixelX * r.left)  + nLeft;
        this.extent.right  = (nPixelX * r.right) + nLeft;
        this.extent.top    = nTop - (r.top * nPixelY);
        this.extent.bottom = nTop - (r.bottom * nPixelY);
      } else {
        var nXRatio = this.imgWidth  / r.getWidth();
        var nYRatio = this.imgHeight / r.getHeight();
        nX = nXRatio * nW / 2;
        nY = nYRatio * nH / 2;
        this.extent.left   = this.extent.left   - nX;
        this.extent.right  = this.extent.right  + nX;
        this.extent.top    = this.extent.top    + nY;
        this.extent.bottom = this.extent.bottom - nY;
      }
    }
  }
  this.validate(true);
}



