//$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/apps/igeoportal-standard/branches/2.5_testing/javascript/digitizer.js $
/*----------------------------------------------------------------------------
 This file is part of deegree, http://deegree.org/
 Copyright (C) 2001-2009 by:
 - Department of Geography, University of Bonn -
 and
 - lat/lon GmbH -

 This library is free software; you can redistribute it and/or modify it under
 the terms of the GNU Lesser General Public License as published by the Free
 Software Foundation; either version 2.1 of the License, or (at your option)
 any later version.
 This library is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
 details.
 You should have received a copy of the GNU Lesser General Public License
 along with this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 Contact information:

 lat/lon GmbH
 Aennchenstr. 19, 53177 Bonn
 Germany
 http://lat-lon.de/

 Department of Geography, University of Bonn
 Prof. Dr. Klaus Greve
 Postfach 1147, 53001 Bonn
 Germany
 http://www.geographie.uni-bonn.de/deegree/

 e-mail: info@deegree.org
----------------------------------------------------------------------------*/

function Digitizer (layWidth, layHeight, hspc, vspc, drawColor) {

	this.iWidth = layWidth;
	this.iHeight = layHeight;
	this.hspc = hspc;
	this.vspc = vspc;
	this.drawColor = drawColor;
	this.mouseX = 0;
    this.mouseY = 0;
	this.x = 0;
	this.y = 0;
	this.lineDrawing = false;
    this.closed = false;
    this.coords = new Array();
    this.layer_ = null;

	this.mode;
    this.stroke = 1;
    this.srf; 
    this.surface;
	
	// method declaration
	this.init = init;
	this.kill = kill;
	this.getMouse = getMouse;
	this.chkMouseUp = chkMouseUp;
	this.startDigitize = startDigitize;
	this.getCoordinates = getCoordinates;
	this.closeToPolygon = closeToPolygon;
	this.getAsLineString = getAsLineString;
	this.getCurrentAsLineString = getCurrentAsLineString;
	this.getAsPolygon = getAsPolygon;
	this.getCurrentAsPolygon = getCurrentAsPolygon;
    this.getAsBox = getAsBox;
    this.targetElement = "digitizerCanvas";
    
	this.setMode = setMode;
    this.setStroke = setStroke;
	this.getAsPoint = getAsPoint;
	this.setDigitizingComplete = setDigitizingComplete;

	// method implementation

	function init() {
		this.kill();		
		this.surface = dojox.gfx.createSurface( getElement( this.targetElement ), 1900, 1500);
		this.srf = this.surface.createGroup();		
    }
	
	function kill() {
		if ( this.srf != null ) {			
			this.srf.clear();
			removeChildren( getElement( this.targetElement ) );
		}
		this.closed = true;
		this.lineDrawing = false;		
	}
	
    function getMouse( xx, yy ) {    
        if ( (xx <= this.iWidth) && (yy <= this.iHeight) && xx > 0 && yy > 0 &&
             this.mouseX >= 0 && this.mouseY >= 0 && xx > 5 && yy > 5 ) {
             
        	 this.srf.clear();
             if( this.mode == "point" ) {
    	        this.x = xx;
 				this.y = yy;
	         } else if( this.mode == "box" ) {
	         	this.x = xx;
 				this.y = yy;
 				var rx = this.coords[0].x;
                var ry = this.coords[0].y;
                var w = xx - this.coords[0].x;
                var h = yy - this.coords[0].y;
                if ( w < 0 ) {
                    rx = xx;
                    w = -1 * w;
                }
                if ( h < 0 ) {
                    ry = yy;
                    h = -1 * h;
                }                
                this.srf.createShape({type: "rect", x: rx, y: ry, width: w, height: h})
                .setFill([255, 255, 255, 0.5])
                .setStroke({color: "red", width: this.stroke});
                this.srf.moveToFront();
	         } else if( this.mode == "linestring" ) {    
				this.x = xx;
				this.y = yy;
				if ( this.lineDrawing ) {
					var p1 = this.srf.createPath().setStroke( {color: "red", width: this.stroke} );
					p1.moveTo( this.coords[0].x, this.coords[0].y );
					for ( var i = 1; i < this.coords.length; i++) {
						p1.lineTo( this.coords[i].x, this.coords[i].y )
					}
					p1.lineTo( xx, yy )
					this.srf.moveToFront();

				} 
			} else {    
				this.x = xx;
				this.y = yy;	
				if ( this.lineDrawing ) {
					var p1 = this.srf.createShape({type: "path"});
					p1.setStroke( {color: "red", width: this.stroke} );
					p1.setFill([255, 255, 255, 0.5]);						
					p1.moveTo( this.coords[0].x, this.coords[0].y );
					for ( var i = 1; i < this.coords.length; i++) {
						p1.lineTo( this.coords[i].x, this.coords[i].y )
					}
					p1.lineTo( xx, yy )
					p1.lineTo( this.coords[0].x, this.coords[0].y )
					this.srf.moveToFront();
				} 
			}
		} 
	}

    function chkMouseUp() {
		var k = this.coords.length-1;
    	if ( this.coords[k].x != this.x && this.coords[k].y != this.y ) {
			this.coords.push( new Point( this.x, this.y ) ); 
			this.mouseX = this.x;
			this.mouseY = this.y;
		}
    }

    function startDigitize(x,y) {
    	if ( this.closed ) {
			this.coords = new Array();    		
    		this.closed = false;
    	}
        if ( !this.lineDrawing ) {
            this.mouseX= x;
            this.mouseY= y;
            this.x = this.mouseX;
            this.y = this.mouseY;
        	this.coords.push( new Point( x, y ) );        	
        }
        this.lineDrawing = true;	
    }

    function getCoordinates() {
    	return this.coords;
    }
    
    function getAsLineString(gt) {
    	var points = Array();
    	for ( var i = 0; i < this.coords.length; i++) {
    		var xx = gt.getSourceX( this.coords[i].x + this.hspc );
    		var yy = gt.getSourceY( this.coords[i].y + this.vspc );
			points.push( new Point( xx, yy ) );
    	}
    	this.lineDrawing = false;
    	return new LineString( points );
    }
    
    /**
     * 
     * @param x
     * @param y
     * @param gt
     * @return current geometry as line string (without finalizing digitizing)
     */
    function getCurrentAsLineString(x, y, gt) {
    	var points = Array();
    	for ( var i = 0; i < this.coords.length; i++) {
    		var xx = gt.getSourceX( this.coords[i].x + this.hspc );
    		var yy = gt.getSourceY( this.coords[i].y + this.vspc );
			points.push( new Point( xx, yy ) );
    	}
    	var xx = gt.getSourceX( x + this.hspc );
		var yy = gt.getSourceY( y + this.vspc );
		points.push( new Point( xx, yy ) );
    	return new LineString( points );
    }
    
    function closeToPolygon() {
    	this.coords.push( new Point( this.coords[0].x, this.coords[0].y ) ); 		
		this.closed = true;
        this.lineDrawing = false;
    }
    
    function getAsPolygon(gt) {
		if ( !this.closed ) {
			this.closeToPolygon();
		}
		var points = Array();
    	for ( var i = 0; i < this.coords.length; i++) {
    		var xx = gt.getSourceX( this.coords[i].x + this.hspc );
    		var yy = gt.getSourceY( this.coords[i].y + this.vspc );
			points.push( new Point( xx, yy ) );
    	}
    	return new Polygon( points );
	}
    
    /**
     * 
     * @param x
     * @param y
     * @param gt
     * @return current geometry as polygon (without finalizing digitizing)
     */
    function getCurrentAsPolygon( x, y, gt) {		
		var points = Array();
    	for ( var i = 0; i < this.coords.length; i++) {
    		var xx = gt.getSourceX( this.coords[i].x + this.hspc );
    		var yy = gt.getSourceY( this.coords[i].y + this.vspc );
			points.push( new Point( xx, yy ) );
    	}
    	var xx = gt.getSourceX( x + this.hspc );
		var yy = gt.getSourceY( y + this.vspc );
		points.push( new Point( xx, yy ) );
		var xx = gt.getSourceX( this.coords[0].x + this.hspc );
		var yy = gt.getSourceY( this.coords[0].y + this.vspc );
		points.push( new Point( xx, yy ) );
    	return new Polygon( points );
	}

	function setStroke( s ){
		this.stroke = s;
	}

	function setMode( mode ){
		this.mode = mode;
	}
	
    function getAsPoint(gt) {
   		var xx = gt.getSourceX( this.coords[0].x + this.hspc );
   		var yy = gt.getSourceY( this.coords[0].y + this.vspc );
    	return new Point( xx, yy );
	}
	
	function getAsBox(gt) {
   		var x1 = gt.getSourceX( this.coords[0].x + this.hspc );
   		var y1 = gt.getSourceY( this.coords[0].y + this.vspc );
   		var x2 = gt.getSourceX( this.coords[1].x + this.hspc );
   		var y2 = gt.getSourceY( this.coords[1].y + this.vspc );
   		if ( x1 > x2 ) {
   			var t = x1 ;
   			x1 = x2;
   			x2 = t;
   		}
   		if ( y1 > y2 ) {
   			var t = y1 ;
   			y1 = y2;
   			y2 = t;
   		}
    	return new Envelope( x1, y1, x2, y2 );
	}
	
	function setDigitizingComplete( isComplete ){
		this.closed = isComplete;
	}
}
