package daruma.geometry;

import com.vividsolutions.jts.geom.* ;
import com.vividsolutions.jts.geom.impl.* ;
import daruma.geometry.OgcGeometryFactory ;
import daruma.geometry.CoordinateSystemTransformation;

//======================================================================
/**
 * DaRuMa 用 Geometry スーパークラス
 */

public abstract class DrmGeometry
{
    private String srsName;
    private Geometry geometry ;

    private static OgcGeometryFactory defaultGeometryFactory =
	new OgcGeometryFactory() ;

    //--------------------------------------------------
    /**
     * constructor
     */
    public DrmGeometry() 
    {
	this.srsName = null;
	this.geometry = null ;
    }

    //--------------------------------------------------
    /**
     * srsName 設定
     */
    public void setSrsName( String  srsName ) 
    {
	this.srsName = srsName;
    }

    //--------------------------------------------------
    /**
     * srsName 取得
     */
    public String getSrsName()
    {
	return( this.srsName );
    }

    //--------------------------------------------------
    /**
     * OGC model の geometry を設定
     */
    public void setGeometry( Geometry geometry ) 
    {
	this.geometry = geometry ;
    }

    //--------------------------------------------------
    /**
     * OGC model の geometry を生成
     */
    public Geometry genGeometry()
    {
	return this.genGeometry(defaultGeometryFactory) ;
    }

    //--------------------------------------------------
    /**
     * OGC model の geometry を生成
     */
    abstract public Geometry genGeometry(OgcGeometryFactory geoFactory) ;

    //--------------------------------------------------
    /**
     * OGC model の geometry を取得。
     * もし未設定の場合、生成した後、取得。
     */
    public Geometry getGeometry()
    {
	return this.getGeometry(defaultGeometryFactory) ;
    }

    //--------------------------------------------------
    /**
     * OGC model の geometry を取得。
     * もし未設定の場合、生成した後、取得。
     */
    public Geometry getGeometry(OgcGeometryFactory geoFactory) 
    {
	if(this.geometry == null) {
	    this.setGeometry(this.genGeometry(geoFactory)) ;
	}

	return this.geometry ;
    }

    //--------------------------------------------------
    /**
     * check the object contains a given geometry
     */
    public boolean contains(DrmGeometry geometry) {
	return contains(geometry.getGeometry()) ;
    }

    public boolean contains(Geometry geometry) {
	return getGeometry().contains(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object is covered by a given geometry
     */
    public boolean coveredBy(DrmGeometry geometry) {
	return coveredBy(geometry.getGeometry()) ;
    }

    public boolean coveredBy(Geometry geometry) {
	return getGeometry().coveredBy(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object covers a given geometry
     */
    public boolean covers(DrmGeometry geometry) {
	return covers(geometry.getGeometry()) ;
    }

    public boolean covers(Geometry geometry) {
	return getGeometry().covers(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object crosses a given geometry
     */
    public boolean crosses(DrmGeometry geometry) {
	return crosses(geometry.getGeometry()) ;
    }

    public boolean crosses(Geometry geometry) {
	return getGeometry().crosses(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object disjoints a given geometry
     */
    public boolean disjoint(DrmGeometry geometry) {
	return disjoint(geometry.getGeometry()) ;
    }

    public boolean disjoint(Geometry geometry) {
	return getGeometry().disjoint(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object intersects a given geometry
     */
    public boolean intersects(DrmGeometry geometry) {
	return intersects(geometry.getGeometry()) ;
    }

    public boolean intersects(Geometry geometry) {
	return getGeometry().intersects(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object overlaps a given geometry
     */
    public boolean overlaps(DrmGeometry geometry) {
	return overlaps(geometry.getGeometry()) ;
    }

    public boolean overlaps(Geometry geometry) {
	return getGeometry().overlaps(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object touches a given geometry
     */
    public boolean touches(DrmGeometry geometry) {
	return overlaps(geometry.getGeometry()) ;
    }

    public boolean touches(Geometry geometry) {
	return getGeometry().touches(geometry) ;
    }

    //--------------------------------------------------
    /**
     * check the object is within a given geometry
     */
    public boolean within(DrmGeometry geometry) {
	return within(geometry.getGeometry()) ;
    }

    public boolean within(Geometry geometry) {
	return getGeometry().within(geometry) ;
    }

    //--------------------------------------------------
    /**
     * return coordinate transformed geometry
     */
    public abstract DrmGeometry transform
				( CoordinateSystemTransformation trans )
	throws TransformationException;
}
