﻿// JScript File

Type.registerNamespace("Shapes"); 

// Initializes a new instance of the Polygon class
Shapes.Polygon= function()
{
    this.boundingBox = new CV.mBOSS.DAL.Rectangle();
    this.polyPoints = new Array();
    this.polyDistances = null;
    this.totalDistance = 0;
    this.coordSys = 'DEVICE'; //{ DEVICE, WORLD }
}
// Append a Point to the polygon
Shapes.Polygon.prototype.appendPoint = function ( i_point, i_distance)
{
    var nextPnt = this.polyPoints.length;
    this.polyPoints[nextPnt] = i_point;
    if ( i_distance != undefined){
        if ( this.polyDistances == null ){
            this.polyDistances = new Array();
        }
        this.polyDistances[nextPnt] = i_distance;
        this.totalDistance += i_distance;
    }
}
// Append an x,y coordinate pair to the polygon as a point
Shapes.Polygon.prototype.appendXY = function ( i_x, i_y, i_distance)
{
    var point = new CV.mBOSS.DAL.Point();
    point.x = i_x;
    point.y = i_y;
    this.appendPoint(point, i_distance);
}
// Append an x,y coordinate pair to the polygon as a point
Shapes.Polygon.prototype.updateLast = function ( i_x, i_y, i_distance)
{
    var lastPnt = this.getLastPoint();
    lastPnt.x = i_x;
    lastPnt.y = i_y;
    if ( i_distance != undefined){
        if ( this.polyDistances == null ){
            this.polyDistances = new Array();
        }
        var lastIdx = this.polyPoints.length -1;
        var lastDistance = this.polyDistances[lastIdx];
        this.polyDistances[lastIdx] = i_distance;
        this.totalDistance += (i_distance - lastDistance);
    }
}

//method to call when last vertice is added 
//Calc BB etc
Shapes.Polygon.prototype.finish= function ( )
{
    var nVetices = this.polyPoints.length;
    var pnt;
    var bDeviceCoord = this.coordSys == 'DEVICE' ? true : false;
    for(var i=0; i<nVetices; i++){
        var pnt = this.polyPoints[i];
        if ( i==0){
            this.boundingBox.LLX =  pnt.x;
            this.boundingBox.URX =  pnt.x;
            this.boundingBox.LLY =  pnt.y;
            this.boundingBox.URY =  pnt.y;
        } else if (bDeviceCoord == true){
            this.boundingBox.LLX = pnt.x < this.boundingBox.LLX ? pnt.x : this.boundingBox.LLX;
            this.boundingBox.URX = pnt.x > this.boundingBox.URX ? pnt.x : this.boundingBox.URX;
            //Y coordinates in device coordinates is oposite of world coordinates
            this.boundingBox.LLY = pnt.y > this.boundingBox.LLY ? pnt.y : this.boundingBox.LLY;
            this.boundingBox.URY = pnt.y < this.boundingBox.URY ? pnt.y : this.boundingBox.URY;
        } else {
            this.boundingBox.LLX = pnt.x < this.boundingBox.LLX ? pnt.x : this.boundingBox.LLX;
            this.boundingBox.URX = pnt.x > this.boundingBox.URX ? pnt.x : this.boundingBox.URX;
            //Y coordinates in world coordinates (oposite of device coordinates)
            this.boundingBox.LLY = pnt.y < this.boundingBox.LLY ? pnt.y : this.boundingBox.LLY;
            this.boundingBox.URY = pnt.y > this.boundingBox.URY ? pnt.y : this.boundingBox.URY;
        }
    }
}
//Return the lisrt of points in the polygon 
Shapes.Polygon.prototype.getPolyPoints = function ()
{
    return this.polyPoints;
}

Shapes.Polygon.prototype.getLastPoint = function ( )
{
    return this.polyPoints[this.polyPoints.length-1];
}
///
/// indexfromLast: positve index mean index from start 0=first, 1=second etc
///                negative numbers mean indesx from last: -1=last-1 etc
Shapes.Polygon.prototype.getPointByIndex = function ( i_indexFromLast )
{
    var idx = this.polyPoints.length-1 + i_indexFromLast;
    if ( idx >= 0 && idx <= this.polyPoints.length-1){
        return this.polyPoints[idx];
    } 
    return null;
}
//Get the soze of polygon, number of points
Shapes.Polygon.prototype.getNumVertices = function ()
{
    return this.polyPoints.length;
}
//return the polugon bounding rectangle
Shapes.Polygon.prototype.getBoundingBox = function ()
{
    return this.boundingBox;
}
//return the total distance along the vertices (if registered)
Shapes.Polygon.prototype.getTotalDistance = function ()
{
    return this.totalDistance;
}
Shapes.Polygon.prototype.getLastDistance = function ()
{
    if ( this.polyDistances != null && this.polyDistances.length > 0){
        return this.polyDistances[this.polyDistances.length-1];
    }
    return 0;
}
//return clear the polygon
Shapes.Polygon.prototype.clear = function ()
{
    this.polyPoints.length = 0;
    if ( this.polyDistances != null ){
        this.polyDistances.length = 0;
    }
    this.totalDistance = 0;
    this.boundingBox.LLX = this.boundingBox.LLY = this.boundingBox.URX = this.boundingBox.URY = 0;
}
//
//Check if the point is inside the polygon
//return value: true = Inside, false= outside
Shapes.Polygon.prototype.insidePolygon = function (i_point)
{
    var counter = 0;
    var i;
    var xinters;
    var p1,p2;
    var N = this.polyPoints.length;
    //First check that the input data is OK
     if ( i_point == null || N < 3)
     {
        return false;
     }
      p1 = this.polyPoints[0];
      for (i=1;i<=N;i++) {
        p2 = this.polyPoints[i % N];
        if (i_point.y > Math.min(p1.y, p2.y)) {
          if (i_point.y <= Math.max(p1.y, p2.y)) {
            if (i_point.x <= Math.max(p1.x, p2.x)) {
              if (p1.y != p2.y) {
                xinters = (i_point.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x;
                if (p1.x == p2.x || i_point.x <= xinters)
                  counter++;
              }
            }
          }
        }
        p1 = p2;
      }

      if (counter % 2 == 0){
        return false;
      } else {
        return true ;
      }
}

Shapes.Polygon.registerClass('Shapes.Polygon', null, Sys.IDisposable);

