// =============================================================================
// flowchart_scalar.js
if(!Base)
  alert('flowchart_strman: Base.js undefined');

// CPoint()
//   .x = 0
//   .y = 0
// CPoint(x,y)
// CPoint(CPoint)
var CPoint = Base.extend({
  constructor: function()
  {
    if (typeof arguments[0]!='undefined')
    {
      if (typeof arguments[1]!='undefined')
      { // x,y
        this.x = arguments[0];
        this.y = arguments[1];
      }
      else
      { // CPoint
        this.x = arguments[0].x;
        this.y = arguments[0].y;
      }
    }
    else
    {
      this.x = 0;
      this.y = 0;
    }
  },
  
  add: function(pt) {this.x+=pt.x;this.y+=pt.y;return this;},
  subtract: function(pt) {this.x-=pt.x;this.y-=pt.y;return this;},
  multiply: function(pt) {this.x*=pt.x;this.y*=pt.y;return this;},
  divide: function(pt) {this.x/=(pt.x?pt.x:1);this.y/=(pt.y?pt.y:1);return this;},

  floor: function() {this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this;},
  ceil: function() {this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this;},
  
  slope: function()
  {
    var pt=((typeof (arguments[0])!='undefined') ? arguments[0] : new CPoint());
    pt.x=this.x-pt.x;
    return((this.y-pt.y)/(pt.x?pt.x:1));
  }
  
});


// CRect()
//  .left = 0
//  .top = 0
//  .right = 0
//  .bottom = 0
//  .ptInRect(CPoint)
//  .ptInRect(x,y)
//    returns true if the point is within the rectangle, otherwise false
//  .rectInRect(CRect)
//    returns true if supplied rect is within current rect, otherwise false
//  .rectRelation(CRect)
//    return rect of offsets from current (<0 (< left,top); >0 (> width,height))
// CRect(left,top,right,bottom)
// CRect(CRect)
var CRect = Base.extend({
  constructor: function()
  {
    if (typeof arguments[0]=='undefined')
    {
      this.left=this.top=this.right=this.bottom=0;
    }
    else if (typeof arguments[3]!='undefined')
    {
      this.left=arguments[0];
      this.top=arguments[1];
      this.right=arguments[2];
      this.bottom=arguments[3];
    }
    else
    {
      this.left=arguments[0].left;
      this.top=arguments[0].top;
      this.right=arguments[0].right;
      this.bottom=arguments[0].bottom;
    }
  },

  ptInRect: function(arg) // (x,y) or (CPoint)
  {
    if (typeof arguments[1]=='undefined')
    {
      return (((arg.left>=this.left) && (arg.right<=this.right) && (arg.top>=this.top) && (arg.bottom<=this.bottom))?true:false);
    }
    else
    {
      var y=arguments[1];
      return (((arg>=this.left) && (arg<=this.right) && (y>=this.top) && (y<=this.bottom))?true:false);
    }
  },
  
  rectInRect: function(rect)
  {
    return (((rect.left>=this.left) && (rect.right<=this.right) && (rect.top>=this.top) && (rect.bottom<=this.bottom))?true:false);
  },

  rectRelation: function(rect)
  {
    return new CRect(this.left-rect.left,this.top-rect.top,rect.right-this.right,rect.bottom-this.bottom);
  }
});

// CScalar (physical width, maximum value)
var CScalar = Base.extend({
  constructor: function(width_max,value_max) {this._init(width_max,value_max);},
  
  // .scale() retuns current scaled width
  // .scale(value) sets new scaled width
  scale: function() {return ((arguments[0]=='undefined') ? this.width_scaled : this._set(arguments[0]));},

  // update the dimensions
  width: function(value) {this.width_max=value;this._set(0);},
  value: function(value) {this.value_max=value;this._set(0);},

  // private:
  _set: function(value) {return (((this.value_current=value) == 0) ? (this.width_scaled=0) : this._scale());},
  _scale: function() {return this.width_scaled=Math.floor((this.value_current*this.width_max)/this.value_max);},

  _init: function(width_max,value_max)
  {
    this.width_max = width_max;
    this.value_max = ((value_max == 0) ? 1 : value_max); // prevent div by zero
    this._set(0);
  }
});

// CScalarPoint (physial width, physical height, max x value, max y value)
var CScalarPoint = CPoint.extend({
  constructor: function(width_max,height_max,value_x_max,value_y_max)
  {
    this.base(); // init .x=0, .y=0
    this.xScalar = new CScalar(width_max,value_x_max);
    this.yScalar = new CScalar(height_max,value_y_max);
  },
  
  LPtoDP: function(pt)
  {
    this.x = this.xScalar.scale(pt.x);
    this.y = this.yScalar.scale(pt.y);
    return new CPoint(this.x,this.y);
  },
  
  // update the dimensions: for max in extent
  dimensions: function(pt) {this.xScalar.width(pt.x);this.yScalar.width(pt.y);},
  bounds: function(pt)     {this.xScalar.value(pt.x);this.yScalar.value(pt.y);}
});


var CScalarPoints = Base.extend({
  constructor: function()
  {
    this.array = new Array(); // type CScalarPoint
  },
  
  set: function(name,ptScalar) {this.array[name]=ptScalar;},
  get: function(name) {return this.array[name];}
});

