package com.persagy.bdtp.adm.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.CaseInsensitiveMap;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.LinearRing;
import org.locationtech.jts.geom.Polygon;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class GeomUtil {

	private static GeometryFactory geometryFactory = new GeometryFactory();

	public static Polygon[] getPolygon(ArrayNode arrayNode){
		Polygon[] ps = new Polygon[arrayNode.size()];
		for (int i = 0; i < ps.length; i++) {
			ArrayNode arr = (ArrayNode) arrayNode.get(i);
			ArrayNode shellArrNode = (ArrayNode) arr.get(0);
			LinearRing shell = geometryFactory.createLinearRing(buildCoords(shellArrNode));
			LinearRing[] holes = null;
			if(arr.size() > 1) {
				holes = new LinearRing[arr.size() - 1];
				for (int n = 1; n < arr.size(); n++) {
					holes[n - 1] = geometryFactory.createLinearRing(buildCoords((ArrayNode) arr.get(n)));
				}
			}
			ps[i] = geometryFactory.createPolygon(shell, holes);
		}
		return ps;
	}

	private static Coordinate[] buildCoords(ArrayNode arrayNode){
		Coordinate[] coords = new Coordinate[arrayNode.size()];
		for (int i = 0; i < arrayNode.size(); i++) {
			JsonNode pointNode = arrayNode.get(i);
			coords[i] = new Coordinate(pointNode.get("x").asDouble(), pointNode.get("y").asDouble());
		}
		return coords;
	}

	public static boolean checkPolygon(ArrayList<ArrayList<ArrayList<CaseInsensitiveMap>>> outline){
		if(CollUtil.isEmpty(outline))
			return false;

		try {
			Polygon[] ps = new Polygon[outline.size()];
			for (int i = 0; i < ps.length; i++) {
				List space = (List) outline.get(i);
				if(CollUtil.isEmpty(space))
					return false;

				List<Map> shellList = (List) space.get(0);
				LinearRing shell = geometryFactory.createLinearRing(buildCoords(shellList));
				LinearRing[] holes = null;
				if(space.size() > 1) {
					holes = new LinearRing[space.size() - 1];
					for (int n = 1; n < space.size(); n++) {
						holes[n - 1] = geometryFactory.createLinearRing(buildCoords((List<Map>) space.get(n)));
					}
				}
				ps[i] = geometryFactory.createPolygon(shell, holes);
			}
		} catch (Exception e) {
			return false;
		}
		return true;
	}

	private static Coordinate[] buildCoords(List<Map> list){
		Coordinate[] coords = new Coordinate[list.size()];
		for (int i = 0; i < list.size(); i++) {
			Map point = list.get(i);
			coords[i] = new Coordinate((Double) point.get("x"), (Double)point.get("y"));
		}
		return coords;
	}

	public static boolean checkPolygon(ArrayNode outline){
		if(outline == null || outline.size() == 0)
			return false;

		try {
			Polygon[] ps = new Polygon[outline.size()];
			for (int i = 0; i < ps.length; i++) {
				ArrayNode space = (ArrayNode) outline.get(i);
				if(space == null || space.size() == 0)
					return false;

				ArrayNode shellList = (ArrayNode) space.get(0);
				LinearRing shell = geometryFactory.createLinearRing(buildCoords(shellList));
				LinearRing[] holes = null;
				if(space.size() > 1) {
					holes = new LinearRing[space.size() - 1];
					for (int n = 1; n < space.size(); n++) {
						holes[n - 1] = geometryFactory.createLinearRing(buildCoords((ArrayNode) space.get(n)));
					}
				}
				ps[i] = geometryFactory.createPolygon(shell, holes);
			}
		} catch (Exception e) {
			return false;
		}
		return true;
	}

}
