// Title: Scaler
// Description: find projection parameters and scale to it
// Copyright: Copyright (c) 2010
// Company: SiG Software Integration GmbH
// Author: Dr. Horst Walther
//  ----------------------------------------------------------------------------

function Scaler (min, max, len) {
  this.id = 'Scaler';
  this.wordy = false;
  this.valMin = 0.0;
  this.valMax = 0.0;
  this.valInc = 0.0;
  this.scalingFactor = 0.0;
  this.viewLen = 0.0;
  this.valMinOld = 0.0;
  this.valMaxOld = 0.0;
  this.valIncOld = 0.0;
  this.scalingFactorOld = 0.0;
  this.viewLenOld = 0.0;
  this.nValInc = 0;
  this.nValIncOld = 0;
  this.places = 2;
  this.walMath = new WalMath ();

//  ----------------------------------------------------------------------------
  this.initScaler = function(min, max, len) {
    if (this.wordy)
      alert( this.id+".initScaler (" + min + ", " + max + ", " + len + ")");
    this.min = min;
    this.max = max;
    this.len = len;
    return this.autoScale(min, max, len);
  }

  //  ----------------------------------------------------------------------------
  this.init = function(min, max, len) {
    return this.initScaler(min, max, len);
  }

  //  ----------------------------------------------------------------------------
  this.getFactor = function () {
      return this.scalingFactor;
    }

//  ----------------------------------------------------------------------------
  this.getValMin = function () {
      return this.valMin;
    }

//  ----------------------------------------------------------------------------
  this.getValMax = function () {
      return this.valMax;
    }

//  ----------------------------------------------------------------------------
  this.getValInc = function () {
      return this.valInc;
    }

//  ----------------------------------------------------------------------------
  this.getNumInc = function () {
      return this.nValInc;
    }

//  ----------------------------------------------------------------------------
  this.getViewInc = function () {
      return this.viewLen / this.nValInc;
    }

//  ----------------------------------------------------------------------------
  this.getPlaces = function () {
      return this.places;
    }

//  methods  -------------------------------------------------------------------
  this.getClass = function() {
    return 'Scaler';
  }  

//  ----------------------------------------------------------------------------
  this.changed = function () {
      if (this.wordy) {
        if (this.valMin != this.valMinOld) alert(this.valMin + " != " + this.valMinOld);
        if (this.valMax != this.valMaxOld) alert(this.valMax + " != " + this.valMaxOld);
        if (this.valInc != this.valIncOld) alert(this.valInc + " != " + this.valIncOld);
        if (this.scalingFactor != this.scalingFactorOld) alert(this.scalingFactor + " != " + this.scalingFactorOld);
        if (this.viewLen != this.viewLenOld) alert(this.viewLen + " != " + this.viewLenOld);
      }
      return !((this.valMin == this.valMinOld) &&
               (this.valMax == this.valMaxOld) &&
               (this.valInc == this.valIncOld) &&
               (this.scalingFactor == this.scalingFactorOld) &&
               (this.viewLen == this.viewLenOld) &&
               (this.nValInc == this.nValIncOld));
    }

//  ----------------------------------------------------------------------------
  this.autoScale = function( min,  max,  len)  {
    if (this.wordy) alert (this.id+'.autoScale ('+min+',  '+max+', '+len+')')
    if ((min==undefined) || (max==undefined) ||(len==undefined)) 
      return this;
    if (max <= min) { // >
      alert ('### err: '+this.id+'.autoScale: max ('+max+') <= min ('+min+')');  // >
      return this;
    }
    this.valMinOld = this.valMin;
    this.valMaxOld = this.valMax;
    this.valIncOld = this.valInc;
    this.scalingFactorOld = this.scalingFactor;
    this.viewLenOld = this.viewLen;
    this.nValIncOld = this.nValInc;
    this.viewLen = len ? len : this.viewLen;

    var iValInc = 1;
    var imax =  this.walMath.iPotenz(max - min); //    var imax =  this.walMath.Log10(max - min); >
    var neg = (imax < 0);
    if (neg)
      imax = Math.abs(imax);
    for (var i = 1; i <= imax; i++) // >
      iValInc *= 10;
    if (this.wordy)
      alert("max - min=" + (max - min) + ", imax=" + imax + ", iValInc=" + iValInc + " - ");
    var iValMin = (Math.floor (neg ? Math.abs(min) * iValInc : Math.abs(min) / iValInc)) * this.walMath.sign (min) + (this.walMath.sign (min) > 0 ? 0 : -1);
    var iValMax = (Math.floor (neg ? Math.abs(max) * iValInc : Math.abs(max) / iValInc)) * this.walMath.sign (max) + (this.walMath.sign (max) > 0 ? 1 :  0);
    this.valMin = neg ? iValMin / iValInc : iValMin * iValInc;
    this.valMax = neg ? iValMax / iValInc : iValMax * iValInc;
    var vDelta = 1.001 * (this.valMax - this.valMin);
    this.valInc = neg ? 1.0 / iValInc : iValInc;
    this.nValInc =  Math.floor (neg ? vDelta * iValInc : vDelta / iValInc);
    this.scalingFactor = this.viewLen / vDelta;
    this.places = Math.max(0, -this.walMath.iPotenz (this.valInc));
    if (this.wordy)
      alert("min : " + min + " --> " + this.valMin +
                    ", max : " + max + " --> " + this.valMax +
                    ", inkrement = " + this.valInc + " * " + this.nValInc +
                    ", scaling factor = " + this.scalingFactor+
                    ", places = "+this.places);
    return this;
  }

//  ----------------------------------------------------------------------------
  this.manualScale = function ( min,  max,  inc) {
    if (this.wordy) alert(""+this.id+".manualScale ...");
    if (max <= min) {
      alert("### err: "+this.id+".manualScale: max <= min");
      return this;
    }
    this.valMin = min;
    this.valMax = max;
    this.valInc = inc;
    this.nValInc =  ( (this.valMax - this.valMin) / this.valInc);
    this.scalingFactor = this.viewLen / (this.valMax - this.valMin);
    return this;
  }

  //  --------------------------------------------------------------------------->
  this.calcValue = function (i) {
    return this.getValMin() + i * this.getValInc();
  };

//  --------------------------------------------------------------------------->
  this.scaleValue = function (v) {
    if (this.wordy) alert("scaled Value = "+ (v-this.valMin) * this.scalingFactor+" = "+ v+"-"+this.valMin+") * "+this.scalingFactor);
    return (v-this.valMin) * this.scalingFactor;
  }

//  ----------------------------------------------------------------------------
  this.unScale = function (s) {
    if (this.wordy) alert("unscaled Value = "+ (s / this.scalingFactor + this.valMin) +" = "+ s+"/"+this.scalingFactor+") + "+this.valMin);
    return s / this.scalingFactor + this.valMin;
  }

//  ----------------------------------------------------------------------------
  this.toString = function() {
    return this.id+": min : " + this.valMin + ", max : "  + this.valMax + ", increment = " + this.valInc + " * " + this.nValInc + ", scaling factor = " + this.scalingFactor;
  }

//  ----------------------------------------------------------------------------
  this.init(min, max, len);
}
