// ===============================================================
// CBkort version 2.x, copyright Carl Bro GIS&IT, 2006
// ===============================================================
// $Archive: /Products/CBKort2/development/2.4/standard/wwwroot/js/standard/cbkortudstyr.js $ 
// $Date: 21-01-08 12:22 $
// $Revision: 6 $ 
// $Author: Nsm $
// =============================================================== 

var rltPoint = 0;
var rltLine = 1;
var rltPolygon = 2;

function CBKortUdstyr(scale,resolution,extent)
{
    // constants
    this.cbpNone = 0;
    this.cbpLine = 1;
    this.cbpPoint = 2;
    this.cbpCircle = 3;
    this.first = true;
    this.lineStr = "";
    this.lineColor = '#FF0000';
    this.pointHandler = null;
    this.scale = parseFloat(scale);
    this.points = new Array();
    this.npoints = 0;
    this.pxprcm = (96/resolution*96)/2.54;
    this.factor = (this.scale/this.pxprcm)/100;
    var strArr = extent.split(' ');
    this.left = parseFloat(strArr[0]);
    this.top = parseFloat(strArr[1]);
    this.right = parseFloat(strArr[2]);
    this.bottom = parseFloat(strArr[3]);
    this.drawMode = this.cbpLine;
    this.radius = 0;
    this.totalDist = 0;
    this.npSearchPoints = 0;
    this.pSearchPoints = new Array();
    this.polygonSearchHandler = null;
}

// Sets the color for drawing lines
CBKortUdstyr.prototype.setLineColor = function(c)
{
    this.lineColor = c;
}

CBKortUdstyr.prototype.setPointHandler = function(ph)
{
    this.pointHandler = ph;
}

CBKortUdstyr.prototype.setExtent = function(extent)
{
    var strArr = extent.split(' ');
    this.left = parseFloat(strArr[0]);
    this.top = parseFloat(strArr[1]);
    this.right = parseFloat(strArr[2]);
    this.bottom = parseFloat(strArr[3]);
}


CBKortUdstyr.prototype.deleteAll = function(name)
{
    writeHTML(getElement(name),"");
}

CBKortUdstyr.prototype.point = function(x, y)
{
    //Clip
    if (x<cbKort.mapX||y<cbKort.mapY||x>cbKort.mapWidth+cbKort.mapX||y>cbKort.mapHeight+cbKort.mapY)
        return;
    var cursorStr = "";
    var endStr = "></div>";
    if (this.first)
    {
        cursorStr="cursor : crosshair;";
        endStr = "onclick='cbKortUdstyr.closePolygon();'></div>";
        this.first = false;
    }

    this.lineStr+= "<div style='background-color:"+this.lineColor+";z-index:6;position:absolute;border:0px;margin:0px;padding:0px;font-size:1px;width:2px;height:2px;left:"+x+"px;top:"+y+"px;"+cursorStr+"'"+endStr;
}

CBKortUdstyr.prototype.drawLine = function(x1,y1,x2,y2)
{
    this.lineStr = "";
    var range = Math.abs(x2-x1);
    var axis = 0;
    if (Math.abs(y2-y1)>range)
    {
        range = Math.abs(y2-y1);
        axis = 1;
    }
    var dx = x2-x1;
    var dy = y2-y1;
    var errp = 2 * dy - dx;
    dxs = (dx<0) ? -1 : 1;
    dys = (dy<0) ? -1 : 1;
    xp = x1;
    yp = y1;
    if (axis==0)
    {
        for (i=1;i<=range;i++)
        {
             this.point(xp,yp);
             if (errp>0)
             {
                 yp = yp + dys;
                 errp = errp - (2*dx*dxs);
             }
             xp = xp + dxs;
             errp = errp + (2*dy*dys);
        }
    }
    else
    {
        for (i=1;i<=range;i++)
        {
             this.point(xp,yp);
             if (errp>0)
             {
                 xp = xp + dxs;
                 errp = errp - 2*dy*dys;
             }
             yp = yp + dys;
             errp = errp + 2*dx*dxs;
        }
    }
    appendHTML(getElement("points"),this.lineStr);
    this.lineStr = '';

}

CBKortUdstyr.prototype.drawCircle = function(x1,y1)
{
    this.deleteAll("points");
    this.lineStr = '';
    // Init
    var g = 3 - (2 * this.radius);
    var x = 0;
    var y = this.radius;
    var diagonalInc = 10 - 4*this.radius;
    var rightInc = 6;
    this.first = false;

    this.point(x1 + x, y1 + y);
    this.point(x1 + x, y1 - y);
    this.point(x1 + y, y1 + x);
    this.point(x1 + y, y1 - x);
    while (x <= y)
    {
        if (g >=  0)
        {
            g += diagonalInc;
            diagonalInc += 8;
            y -= 1;
        }
        else
        {
            g += rightInc;
            diagonalInc += 4;
        }
        rightInc += 4;
        x += 1;
        this.point(x1 + x, y1 + y);
        this.point(x1 + x, y1 - y);
        this.point(x1 - x, y1 + y);
        this.point(x1 - x, y1 - y);
        this.point(x1 + y, y1 + x);
        this.point(x1 + y, y1 - x);
        this.point(x1 - y, y1 + x);
        this.point(x1 - y, y1 - x);
    }
    appendHTML(getElement("points"),this.lineStr);
    this.lineStr = '';
}

CBKortUdstyr.prototype.drawMarker = function(x1,y1)
{
    this.point(x1,y1);
}

CBKortUdstyr.prototype.closePolygon = function()
{
    if (this.polygonIsClosed()) return;

    if (this.npoints<3) return;

    this.points[this.npoints++] = {x:this.points[0].x,y:this.points[0].y};
    this.showPoint();
    var p1 = this.getMapCoords(this.points[0].x,this.points[0].y);

    if (this.pointHandler)
    {
        this.pointHandler(p1.x,p1.y, 0, 0, this);
    }
}

CBKortUdstyr.prototype.polygonIsClosed = function()
{
    if (this.npoints<3) return false;
    return ((this.points[0].x == this.points[this.npoints-1].x) && (this.points[0].y == this.points[this.npoints-1].y));
}

CBKortUdstyr.prototype.polygonArea = function()
{
   var i,j;
   var area = 0;

   for (i=0;i<this.npoints;i++)
   {
      j = (i + 1) % this.npoints;
      var p1 = this.getMapCoords(this.points[i].x,this.points[i].y);
      var p2 = this.getMapCoords(this.points[j].x,this.points[j].y);
      area += p1.x * p2.y;
      area -= p1.y * p2.x;
   }

   area /= 2;
   return (area < 0) ? -area : area;

}

CBKortUdstyr.prototype.segmentLength = function(i1,i2)
{
    var p1 = this.getMapCoords(this.points[i1].x,this.points[i1].y);
    var p2 = this.getMapCoords(this.points[i2].x,this.points[i2].y);
    return Math.sqrt(Math.pow(Math.abs(p2.x)-Math.abs(p1.x),2)+Math.pow(Math.abs(p2.y)-Math.abs(p1.y),2));
}

CBKortUdstyr.prototype.showPoint = function()
{
    switch (this.drawMode)
    {
        case 0: break; //None
        case 1: // Line
            if (this.npoints > 1)
            {
                var x1 = this.points[this.npoints-2].x;
                var y1 = this.points[this.npoints-2].y;
                var x2 = this.points[this.npoints-1].x;
                var y2 = this.points[this.npoints-1].y;
                this.drawLine(x1+cbKort.mapX,y1+cbKort.mapY,x2+cbKort.mapX,y2+cbKort.mapY);
            }
            else if (this.npoints = 1)
            {
                var x1 = this.points[this.npoints-1].x;
                var y1 = this.points[this.npoints-1].y;
                this.drawLine(x1+cbKort.mapX,y1+cbKort.mapY,x1+cbKort.mapX+1,y1+cbKort.mapY+1);
            }
            break;
        case 2: // Point
            if (this.npoints = 1)
            {
                var x1 = this.points[this.npoints-1].x;
                var y1 = this.points[this.npoints-1].y;
                this.drawLine(x1+cbKort.mapX,y1+cbKort.mapY,x1+cbKort.mapX+1,y1+cbKort.mapY+1);
            }
            break;
        case 3: //Circle
            if (this.npoints > 0)
            {
                var x1 = this.points[this.npoints-1].x;
                var y1 = this.points[this.npoints-1].y;
                this.drawCircle(x1+cbKort.mapX,y1+cbKort.mapY);
            }
            break;
    }
}

CBKortUdstyr.prototype.doPoint = function()
{
    this.points[this.npoints++] = {x:cbKort.mouseX,y:cbKort.mouseY};
    // Draw
    this.showPoint();
    var p1 = this.getMapCoords(cbKort.mouseX,cbKort.mouseY);

    if (this.pointHandler)
    {
        this.pointHandler(p1.x,p1.y,cbKort.mouseX,cbKort.mouseY,this);
    }
}

CBKortUdstyr.prototype.getMapCoords = function (x1,y1)
{
    var x2 = ((x1/cbKort.mapWidth)*(this.right-this.left))+this.left;
    var y2 = (((cbKort.mapHeight-y1)/cbKort.mapHeight)*(this.bottom-this.top))+this.top;
    var precision = parseInt(cbInfo.getParam('cbinfo.mapcoordinate.precision',10));
    if(precision)
    {
        if(precision>=0)
        {
            x2 = x2.toFixed(precision);
            y2 = y2.toFixed(precision);
        }
        else if(precision<0)
        {
            x2 = parseInt(x2,10);
            y2 = parseInt(y2,10);
        }
    }
    return {x:x2,y:y2};
}

CBKortUdstyr.prototype.getPixelCoords = function (wx,wy)
{
    var dx = Math.round(cbKort.mapWidth*(wx-this.left)/(this.right-this.left));
    var dy = Math.round(cbKort.mapHeight*(this.bottom-wy)/(this.bottom-this.top));
    return {x:dx,y:dy};
}

CBKortUdstyr.prototype.reset = function()
{
    this.first = true;
    this.npoints=0;
    this.deleteAll("points");
}

CBKortUdstyr.prototype.validPolygon = function()
{

    if (this.npoints==2)
        return false;

    // Check all real points
    for ( var i = 0; i<this.npoints-1; i++)
    {
        var stop = this.npoints-1
        if (this.polygonIsClosed())
            stop--;
        for ( var j = i+2; j<stop; j++)
        {
            if (segmentsCross(this.points[i],this.points[i+1],this.points[j],this.points[j+1]))
                return false;
        }
    }

    // Check possible autogenerated segment
    p0 = this.points[0];
    p1 = this.points[this.npoints-1];

    if (!samePoint(p0,p1))
    {
        for ( var i = this.npoints-2; i > 1; i--)
        {
            if (segmentsCross(p0,p1,this.points[i],this.points[i-1]))
                return false;
        }
    }

    return true;
}

CBKortUdstyr.prototype.makeABox = function (id,title,closeEvent,posX,posY)
{
    var x = posX;
    var y = posY;
    if (!posX)
    {
        x = 100;
        y = 100;
    }
    var t = '<div id="'+id+'" class="movablebox" style="left:'+x+'px;top:'+y+'px;">';
    t+= '  <div class="titleBar" onmousedown="dragStart(event, \''+id+'\')"><span class="titleBarText">'+title+'</span><img class="titleBarButtons" src="/images/buttons/closebutt.gif" onclick="'+closeEvent+'"></div>';
    return t;
}

CBKortUdstyr.prototype.print = function ()
{
    var url = "/print.html?layers="+cbKort.layers+"&scale="+this.scale+"&extent="+cbKort.getExtentAsString();
    window.open(url, "Udskriv", "width=500,height=400");
}


CBKortUdstyr.prototype.setPolygonSearchHandler = function (handler)
{
    this.polygonSearchHandler = handler;
}


function samePoint(p1,p2)
{
    return ((p1.x==p2.x) && (p1.y==p2.y));
}

function roundToDecs(a,d)
{
    if (a.toFixed)
        return a.toFixed(d);

    var power = Math.pow(10,d);
    return Math.round(a*power)/power;
}

function formatDistance(d, numdecimals) 
{
    if (d<10000)
    {
        if (numdecimals || numdecimals == 0){
            return [roundToDecs(d, numdecimals),"m"];}
        else {
            return [d, cbInfo.getString("standard.units.length")]; }
    }
    else
        return [roundToDecs(d/1000,1),cbInfo.getString("standard.units.length_1000")];
}

function formatArea(a, numdecimals)
{
    if (a<10000)
    {
        if (a<5)
        {
            if (numdecimals)
                return [roundToDecs(a, numdecimals),cbInfo.getString("standard.units.area")];
	    	else
                return [roundToDecs(a, 0),cbInfo.getString("standard.units.area")];
        }
        else
        {
            return [roundToDecs(a, 0),cbInfo.getString("standard.units.area")];
        }
    }
    else
       if (a<1000000)
          return [roundToDecs(a/10000,1),cbInfo.getString("standard.units.area_10000")];
       else   
          return [roundToDecs(a/1000000,1),cbInfo.getString("standard.units.area_1000000")];
}

function isConcave(polygon,n)
{
    var positive = 0;
    var negative = 0;

    if (n<=3)
        return false;

    for ( var i = 0; i < n-1; i++)
    {
        var p0 = polygon[i];
        var p1 = polygon[i+1];
        var p2 = polygon[0];
        if (i+2<n)
            p2 = polygon[i+2]
        // Vectorizing
        var v0 = [p1.x - p0.x,p1.y - p0.y];
        var v1 = [p2.x - p1.x,p2.y - p1.y];
        // Cross product
        var cross = v0[0]*v1[1] - v0[1]*v1[0];
        if ( cross < 0 )
            negative++;
        else
            positive++;
    }
    return ( negative != 0 && positive != 0 );
}

function segmentsCross(v1a,v1b,v2a,v2b)
{
    var x1 = v1a.x;
    var y1 = v1a.y;
    var x2 = v1b.x;
    var y2 = v1b.y;
    var xp1 = v2a.x;
    var yp1 = v2a.y;
    var xp2 = v2b.x;
    var yp2 = v2b.y;
    var diffX = x2-x1;
    var diffY = y2-y1;
    var diffXp = xp2-xp1;
    var diffYp = yp2-yp1;

    if (((diffX*yp1-diffY*xp1)<(diffX*y1-diffY*x1) ^ (diffX*yp2-diffY*xp2)<(diffX*y1-diffY*x1)) & ((diffXp*y1-diffYp*x1)<(diffXp*yp1-diffYp*xp1) ^ (diffXp*y2-diffYp*x2)<(diffXp*yp1-diffYp*xp1)))
    {
        return true;
    }
    else
        return false;
}

var cbKortUdstyr;


