function Point2D(x,y,z)
{
  this.x = x;
  this.y = y;
}

function Segment(A,B)
{
  this.setVertices(A,B);
}

// resets the origin of this segment.  Assumes
// end point B is shifted by the same amount.
Segment.prototype.setOrigin = function(A) {
  this.A = A;
}

Segment.prototype.setVertices = function(A,B)
{
  this.setOrigin(A);

  // create a coordinate transformation matrix
  var dx = B.x-A.x;
  var dy = B.y-A.y;
  this.dAB = Math.sqrt(dx*dx+dy*dy);
  if (this.dAB>0) {
    // create orthogonal matrix with |AB| as X axis
    var ma = dx/this.dAB;
    var mb = dy/this.dAB;
    var mc = -mb;
    var md =  ma;
    // revisit - not certain of order

    // create inverse matrix
    // divisor 1/ad-bc = 1/(ma*ma-mb*mb) = 1/1 (I think?)
    this.ia = md;
    this.ib = -mb;
    this.ic = -mc;
    this.id = ma;
  }
}

Segment.prototype.getDistance = function(C) {
  var D = new Point(0,0);
  if (this.dAB>0) {
    var x = C.x-this.A.x;
    var y = C.y-this.A.y;
    D.x = x * this.ia + y * this.ic;
    D.y = x * this.ib + y * this.id;
    D.z = this.dAB;
  } else {
    // degenerate case - AB is point, return simple dx,dy
    D.x = C.x-this.A.x;
    D.y = C.y-this.A.y;
    D.z = 0;
  }
  // D.x = distance along line from A towards B in original units (ie not normalized by line length)
  // D.y = distance from line (also not normalized by line length)
  // D.z = length of line
  return D;
}

Segment.prototype.getSimpleDistance = function(C) {
  var D = this.getDistance(C);
  //log(D.x+","+D.y+","+D.z);
  var d = Math.abs(D.y);
  // off the end
  if (D.x<0 && -D.x>d) d=-D.x;
  if (D.x>D.z && (D.x-D.z)>d) d=(D.x-D.z);
  return d;
}

// HACK - testing code
/*

var A = new Point2D(0,0,0);
var B = new Point2D(100,100);
var C = new Point2D(10,10);

var S = new Segment(A,B);
var D = S.getDistance(C);
alert(D.x+","+D.y+","+D.z);
*/
