/*----------------    FILE HEADER ---------------------------------------
 This file is part of Geoide.
 Copyright (C) 2005-2006 by:
 IDgis B.V.
 http://www.idgis.nl

 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:

 Herman Assink
 IDgis bv
 P.O. Box 15
 7450 AA Holten
 The Netherlands
 E-Mail: herman.assink@idgis.nl

 * @version 1.4.0
 * @author IDgis team
 * 
 ------------------------------------------------------------------------*/
import nl.idgis.giclient.geoma.Envelope;
import nl.idgis.giclient.geoma.Geometry;
import nl.idgis.giclient.geoma.Point;

class nl.idgis.giclient.geoma.GeometryCollection extends Geometry {

    private var geometries:Array = null;

    function GeometryCollection(srsName:String, geometries:Array) {
    	  super(srsName);
    	  
        if ((geometries == null) || (geometries.length == 0)) {
            // EXCEPTION
            return;
        }

        this.geometries = geometries;

        for (var i:String in geometries) {
            Geometry(geometries[i]).setSuperGeometry(this);
        }
    }

    function addGeometry(geometry:Geometry):Void {
        geometry.setSuperGeometry(this);
        geometries.push(geometry);
        this.getMostSuperGeometry().geometryEventDispatcher.changeGeometry(this, false); // TODO EVENT MODEL
    }

    function addGeometryMember(point:Point):Void { }

    function removeGeometry(geometry:Geometry):Void {
        if (geometries.length == 1) {
            // EXCEPTION
            return;
        }

        for (var i:Number = 0; i < geometries.length; i++) {
            if (geometries[i] == geometry) {
                geometry.setSuperGeometry(null);
                geometries.splice(i, 1);
                break;
            }
        }
    }

    function getGeometries():Array {
        return geometries;
    }

    function getNumGeometries():Number {
        return geometries.length;
    }

    function getGeometry(num:Number):Geometry {
        return Geometry(geometries[num]);
    }

    function addPoint(point:Point):Void {
        Geometry(geometries[geometries.length - 1]).addPoint(point);
    }

    function removePoint(point:Point):Void {
        Geometry(geometries[geometries.length - 1]).removePoint(point);
    }

    function setPointXY(x:Number, y:Number):Void {
        Geometry(geometries[0]).setPointXY(x, y);
    }

    function move(dx:Number, dy:Number):Void {
        for (var i:String in geometries) {
            Geometry(geometries[i]).move(dx, dy);
        }
    }

    function getCoords():Array {
        var coords:Array = new Array();
        for (var i:Number = 0; i < geometries.length; i++) {
            coords = coords.concat(Geometry(geometries[i]).getCoords());
        }
        return coords;
    }

    function getCenterPoint():Point {
        var points:Array = getCoords();

        var point:Point = null;
        var sumX:Number = 0;
        var sumY:Number = 0;
        var numUniquePoints:Number = 0;

        for (var i:Number = 0; i < points.length; i++) {
            point = Point(points[i]);
            sumX += point.getX();
            sumY += point.getY();
            numUniquePoints++;
        }
        var centerPoint:Point = new Point(getSRS(), sumX / numUniquePoints, sumY / numUniquePoints);
        return centerPoint;
    }

    function getNearestPoint(point:Point):Point {
        var points:Array = getCoords();

        var currentPoint:Point = Point(points[0]);
        var distance:Number = currentPoint.getDistance(point);
        var nearestDistance:Number = distance;
        var nearestPoint:Point = currentPoint;

        for (var i:Number = 1; i < points.length; i++) {
            currentPoint = Point(points[i]);
            distance = currentPoint.getDistance(point);
            if (nearestDistance > distance) {
                nearestDistance = distance;
                nearestPoint = currentPoint;
            }
        }
        return nearestPoint;
    }

    function getEnvelope():Envelope {
        var coords:Array = getCoords();

        var point:Point = coords[0];
        var minX:Number = point.getX();
        var minY:Number = point.getY();
        var maxX:Number = point.getX();
        var maxY:Number = point.getY();

        for (var i:Number = 1; i < coords.length; i++) {
            point = Point(coords[i]);
            if (minX > point.getX()) {
                minX = point.getX();
            }
            if (minY > point.getY()) {
                minY = point.getY();
            }
            if (maxX < point.getX()) {
                maxX = point.getX();
            }
            if (maxY < point.getY()) {
                maxY = point.getY();
            }
        }
        return new Envelope(getSRS(), minX, minY, maxX, maxY);
    }

    function clone():GeometryCollection {
        if ((geometries == null) || (geometries.length == 0)) {
            return null;
        }
        var geoms:Array = new Array();
        for (var i:String in geometries) {
            geoms.push(Geometry(geometries[i]).clone());
        }
        return new GeometryCollection(getSRS(), geoms);
    }

}