package com.sysu.admin.utils.shape;

import com.alibaba.fastjson.JSON;
import com.sysu.admin.utils.shape.vo.LineStringVo;
import com.sysu.admin.utils.shape.vo.MultiLineStringVo;
import com.sysu.admin.utils.shape.vo.MultiPolygonVo;
import com.sysu.admin.utils.shape.vo.PolygonVo;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;

/**
 * 调换 Geometry中的X 和 Y
 */
public class GeoSwapXYUtil {

    public static Geometry swap(GeometryJSON fjson, Geometry geometry) throws IOException {
        String str = cast(fjson, geometry);
        if(str == null){
            return null;
        }
        Reader reader = new StringReader(str);
        switch(geometry.getGeometryType()){
            case "GeometryCollection":
                return fjson.readGeometryCollection(reader);
            case "MultiLineString":
                return fjson.readMultiLine(reader);
            case "Point":
                break;
            case "LineString":
                return fjson.readLine(reader);
            case "Polygon":
                return fjson.readPolygon(reader);
            case "MultiPolygon":
                return fjson.readMultiPolygon(str);
        }
        return null;

    }

    private static String cast(GeometryJSON fjson, Geometry geometry){
        switch(geometry.getGeometryType()){
            case "GeometryCollection":
                return castGeometryCollection(fjson, (GeometryCollection)geometry);
            case "MultiLineString":
                return castMultiLineString(fjson.toString(geometry));
            case "Point":
                break;
            case "LineString":
                return castLineString(fjson.toString(geometry));
            case "Polygon":
                return castPolygon(fjson.toString(geometry));
            case "MultiPolygon":
                return castMultiPolygon(fjson.toString(geometry));
        }
        return null;
    }

    private static String castGeometryCollection(GeometryJSON fjson, GeometryCollection geometryCollection){
        String[] geometriesJsonArray = new String[geometryCollection.getNumGeometries()];
        int length = 0;
        for(int i=0;  i< geometryCollection.getNumGeometries();i++){
            Geometry geometry = geometryCollection.getGeometryN(i);
            switch (geometry.getGeometryType()){
                case "Point":
                    break;
                case "LineString":
                    geometriesJsonArray[i] = castLineString(fjson.toString(geometry));
                    break;
                case "Polygon":
                    geometriesJsonArray[i] = castPolygon(fjson.toString(geometry));
                    break;
            }
            length += geometriesJsonArray[i].length();
        }
        StringBuffer result = new StringBuffer(length + 100);
        result.append("{\"type\": \"GeometryCollection\",\"geometries\": [");
        result.append(geometriesJsonArray[0]);
        for(int i=1;i< geometriesJsonArray.length;i++){
            result.append(",").append(geometriesJsonArray[i]);
        }
        result.append("]}");
        return result.toString();
    }


    private static String castMultiPolygon(String str){
        MultiPolygonVo multiPolygonVo = JSON.parseObject(str, MultiPolygonVo.class);
        for(double[][][] a1 : multiPolygonVo.getCoordinates()){
            for(double[][] a2 : a1){
                for(double[] a3 : a2){
                    double temp = a3[0];
                    a3[0] = a3[1];
                    a3[1] = temp;
                }
            }
        }
        return JSON.toJSONString(multiPolygonVo);
    }

    private static String castMultiLineString(String str){
        MultiLineStringVo vo = JSON.parseObject(str, MultiLineStringVo.class);
        for(double[][] a1 : vo.getCoordinates()){
            for(double[] a2 : a1){
                double temp = a2[0];
                a2[0] = a2[1];
                a2[1] = temp;
            }
        }
        return JSON.toJSONString(vo);
    }

    private static String castPolygon(String str){
        PolygonVo vo = JSON.parseObject(str, PolygonVo.class);
        for(double[][] a1 : vo.getCoordinates()){
            for(double[] a2 : a1){
                double temp = a2[0];
                a2[0] = a2[1];
                a2[1] = temp;
            }
        }
        return JSON.toJSONString(vo);
    }

    private static String castLineString(String str){
        LineStringVo vo = JSON.parseObject(str, LineStringVo.class);
        for(double[] a1 : vo.getCoordinates()){
            double temp = a1[0];
            a1[0] = a1[1];
            a1[1] = temp;
        }
        return JSON.toJSONString(vo);
    }


}
