using System;
using System.Collections.Generic;
using System.Linq;
using BAMCIS.GeoJSON;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using Newtonsoft.Json;

namespace SouthSmart.GISService.Infrastructure.Module
{
    public static class GeoJsonHelper
    {
        public static BAMCIS.GeoJSON.Polygon GeometryConvert2Polygon ( this IGeometry geometry )
        {

            //图形转为点集
            IPointCollection pPointColl = geometry as IPointCollection;
            if ( pPointColl.PointCount == 0 )
            {
                return null;
            }
            var listPosition = new List<BAMCIS.GeoJSON.Position> ();
            //遍历点集
            for ( int j = 0; j < pPointColl.PointCount; j++ )
            {
                var point = pPointColl.get_Point ( j );
                //输出点坐标
                listPosition.Add ( new BAMCIS.GeoJSON.Position ( point.X, point.Y ) );
            }
            if ( listPosition.Count >= 4 )
            {
                if ( listPosition[0].Latitude == listPosition[listPosition.Count - 1].Latitude&& listPosition[0].Longitude == listPosition[listPosition.Count - 1].Longitude )
                {
                    var polygon = new BAMCIS.GeoJSON.Polygon ( new List<LinearRing> ()
                {
                    new LinearRing ( listPosition )
                } );
                    return polygon;
                }

            }
            else
            {
                return null;
            }
            return null;

        }
        public static BAMCIS.GeoJSON.LineString GeometryConvert2LineString ( this IGeometry geometry )
        {
            //图形转为点集
            IPointCollection pPointColl = geometry as IPointCollection;
            var listPosition = new List<BAMCIS.GeoJSON.Position> ( pPointColl.PointCount );
            //遍历点集
            for ( int j = 0; j < pPointColl.PointCount; j++ )
            {
                var point = pPointColl.get_Point ( j );
                //输出点坐标
                listPosition.Add ( new BAMCIS.GeoJSON.Position ( point.X, point.Y ) );
            }
            var lineString = new BAMCIS.GeoJSON.LineString ( listPosition );
            return lineString;
        }
        public static BAMCIS.GeoJSON.Point GeometryConvert2Point ( this IGeometry geometry )
        {
            var pPoint = ( IPoint ) geometry;
            var geoPoint = new BAMCIS.GeoJSON.Point ( new Position ( pPoint.X, pPoint.Y ) );
            return geoPoint;
        }

        public static BAMCIS.GeoJSON.GeometryCollection FeaturesConvert ( this List<IFeature> features )
        {
            var listGeometry = new List<Geometry> ();
            for ( int i = 0; i < features.Count; i++ )
            {
                var thisFeature = features[i];
                switch ( features[i].Shape.GeometryType )
                {
                    case esriGeometryType.esriGeometryNull:
                        break;
                    case esriGeometryType.esriGeometryPoint:
                        listGeometry.Add ( thisFeature.Shape.GeometryConvert2Point () );
                        break;
                    case esriGeometryType.esriGeometryMultipoint:
                        break;
                    case esriGeometryType.esriGeometryLine:
                        listGeometry.Add ( thisFeature.Shape.GeometryConvert2LineString () );
                        break;
                    case esriGeometryType.esriGeometryCircularArc:
                        break;
                    case esriGeometryType.esriGeometryEllipticArc:
                        break;
                    case esriGeometryType.esriGeometryBezier3Curve:
                        break;
                    case esriGeometryType.esriGeometryPath:
                        break;
                    case esriGeometryType.esriGeometryPolyline:
                        listGeometry.Add ( thisFeature.Shape.GeometryConvert2LineString () );
                        break;
                    case esriGeometryType.esriGeometryRing:
                        break;
                    case esriGeometryType.esriGeometryPolygon:
                        var geometryConvert = thisFeature.Shape.GeometryConvert2Polygon ();
                        if ( geometryConvert != null )
                            listGeometry.Add ( geometryConvert );
                        break;
                    case esriGeometryType.esriGeometryEnvelope:
                        break;
                    case esriGeometryType.esriGeometryAny:
                        break;
                    case esriGeometryType.esriGeometryBag:
                        break;
                    case esriGeometryType.esriGeometryMultiPatch:
                        break;
                    case esriGeometryType.esriGeometryTriangleStrip:
                        break;
                    case esriGeometryType.esriGeometryTriangleFan:
                        break;
                    case esriGeometryType.esriGeometryRay:
                        break;
                    case esriGeometryType.esriGeometrySphere:
                        break;
                    case esriGeometryType.esriGeometryTriangles:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException ();
                }
            }
            BAMCIS.GeoJSON.GeometryCollection geometryCollection = new GeometryCollection ( listGeometry );
            return geometryCollection;
        }
        public static BAMCIS.GeoJSON.GeometryCollection GeometryConvert ( this List<IGeometry> geometrys )
        {
            var listGeometry = new List<Geometry> ();
            for ( int i = 0; i < geometrys.Count; i++ )
            {
                var geometry = geometrys[i];
                switch ( geometrys[i].GeometryType )
                {
                    case esriGeometryType.esriGeometryNull:
                        break;
                    case esriGeometryType.esriGeometryPoint:
                        listGeometry.Add ( geometry.GeometryConvert2Point () );
                        break;
                    case esriGeometryType.esriGeometryMultipoint:
                        break;
                    case esriGeometryType.esriGeometryLine:
                        listGeometry.Add ( geometry.GeometryConvert2LineString () );
                        break;
                    case esriGeometryType.esriGeometryCircularArc:
                        break;
                    case esriGeometryType.esriGeometryEllipticArc:
                        break;
                    case esriGeometryType.esriGeometryBezier3Curve:
                        break;
                    case esriGeometryType.esriGeometryPath:
                        break;
                    case esriGeometryType.esriGeometryPolyline:
                        listGeometry.Add ( geometry.GeometryConvert2LineString () );
                        break;
                    case esriGeometryType.esriGeometryRing:
                        break;
                    case esriGeometryType.esriGeometryPolygon:
                        var geometryConvert = geometry.GeometryConvert2Polygon ();
                        if ( geometryConvert != null )
                            listGeometry.Add ( geometryConvert );
                        break;
                    case esriGeometryType.esriGeometryEnvelope:
                        break;
                    case esriGeometryType.esriGeometryAny:
                        break;
                    case esriGeometryType.esriGeometryBag:
                        break;
                    case esriGeometryType.esriGeometryMultiPatch:
                        break;
                    case esriGeometryType.esriGeometryTriangleStrip:
                        break;
                    case esriGeometryType.esriGeometryTriangleFan:
                        break;
                    case esriGeometryType.esriGeometryRay:
                        break;
                    case esriGeometryType.esriGeometrySphere:
                        break;
                    case esriGeometryType.esriGeometryTriangles:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException ();
                }
            }
            BAMCIS.GeoJSON.GeometryCollection geometryCollection = new GeometryCollection ( listGeometry );
            return geometryCollection;
        }
        public static List<IGeometry> GeoJsonConvert ( BAMCIS.GeoJSON.GeometryCollection geometryCollection )
        {
            var listGeometry = new List<IGeometry> ();
            //遍历所有的几何图层Geometries
            foreach ( var geometry in geometryCollection.Geometries )
            {
                IGeometry geoOutput = null;
                switch ( geometry.Type )
                {
                    case GeoJsonType.Point:
                        BAMCIS.GeoJSON.Point point = geometry as BAMCIS.GeoJSON.Point;
                        IPoint pt = new PointClass ();
                        pt.PutCoords ( point.Coordinates.Longitude, point.Coordinates.Latitude );
                        geoOutput = ( IGeometry ) point;
                        break;
                    case GeoJsonType.MultiPoint:
                        break;
                    case GeoJsonType.LineString:
                        break;
                    case GeoJsonType.MultiLineString:
                        break;
                    case GeoJsonType.Polygon:
                        BAMCIS.GeoJSON.Polygon polygon = geometry as BAMCIS.GeoJSON.Polygon;
                        Ring ring1 = new RingClass ();
                        object missing = Type.Missing;
                        foreach ( var lineRing in polygon.Coordinates )
                        {
                            foreach ( var lineString in lineRing.Coordinates )
                            {
                                IPoint position = new PointClass ();
                                position.PutCoords ( lineString.Longitude, lineString.Latitude );
                                ring1.AddPoint ( position, ref missing, ref missing );
                            }
                        }
                        IGeometryCollection pointPolygon = new PolygonClass ();
                        pointPolygon.AddGeometry ( ring1 as IGeometry, ref missing, ref missing );
                        IPolygon polyGonGeo = pointPolygon as IPolygon;
                        polyGonGeo.SimplifyPreserveFromTo ();
                        geoOutput = ( IGeometry ) polyGonGeo;
                        break;
                    case GeoJsonType.MultiPolygon:
                        break;
                    case GeoJsonType.GeometryCollection:
                        break;
                    case GeoJsonType.Feature:
                        break;
                    case GeoJsonType.FeatureCollection:
                        break;
                    default:
                        throw new ArgumentOutOfRangeException ();
                }
                listGeometry.Add ( geoOutput );
            }
            return listGeometry;
        }
    }
}