package kr.gmtc.tss.area;

import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import kr.gmtc.tss.util.XmlParseUtil;
import kr.gmtc.tss.util.vo.NodeValue;

public class MarineAreaLoader {

	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
//	@Value("${marine-area.file-path:./data/marine-area.xml}")
	private String marineAreaFilePath;
	
	Map<String,String> marinAreaMap = new ConcurrentHashMap<String, String>(); 

	Integer[] lonArr=null;
	Integer[] latArr=null;
	
	public MarineAreaLoader(String marineAreaFilePath) {
		this.marineAreaFilePath= marineAreaFilePath;
		loadXMLData() ;
	}
	
	public String getMarineAreaId(double lon, double lat) {
		String marineAreaId="";
		String key="";
		int lonIdx = Arrays.binarySearch(lonArr, (int) (lon * 100000));
		int latIdx = Arrays.binarySearch(latArr, (int) (lat * 100000));
		try {

			if (lonIdx >= 0) {
				key += lonArr[lonIdx];
			} else {
				lonIdx = Math.abs(lonIdx) - 2;// idx가 - 값이면 현재 -현재값+1 위치로 절대값 -2해야 실제 IDX 확인 가능
				if (lonArr.length <= lonIdx||lonIdx<0) { // 최대 값 이상인 혹은 0 이하인경우 return
					return "";
				}
				key += lonArr[lonIdx];
			}

			key += "_";

			if (latIdx >= 0) {
				key += latArr[latIdx];
			} else {
				latIdx = Math.abs(latIdx) - 2;// idx가 - 값이면 현재 -현재값+1 위치로 절대값 -2해야 실제 IDX 확인 가능
				if (latArr.length <= latIdx||latIdx<0) { // 최대 값 이상인 혹은 0 이하인경우 return
					return "";
				}
				key += latArr[latIdx];
			}
		} catch (Exception e) {
			logger.info("getMarineAreaId error = ",e);
			
			key="";
		}
		marineAreaId=marinAreaMap.get(key);
		if(marineAreaId==null) {
			marineAreaId="";
		}
		return marineAreaId; 
	}
	


	public void loadXMLData() {
		File file = new File(marineAreaFilePath);
		
		if(!file.exists()) {
			logger.error(marineAreaFilePath+" 위치에 해구도 파일이 없습니다.");
			return;
		}
		

		Set<Integer> lonList = new HashSet<Integer>();
		Set<Integer> latList = new HashSet<Integer>();
		

		Map<String,Object> rootXml=XmlParseUtil.parseXml("./data/marine_area.xml");
		List<NodeValue> list=XmlParseUtil.getNodeValueList(rootXml, "/kml/Document/Folder/Placemark");

		
		
		for (int i = 0; i < list.size(); i++) {
			NodeValue placemark=list.get(i);
			List<NodeValue> simpleDataList = XmlParseUtil.getNodeValueList(placemark.getChildMap(), "/ExtendedData/SchemaData/SimpleData");
			String no1="";
			String no2="";
//			String no3="";
			
			
			for (int j = 0; j < simpleDataList.size(); j++) {
				NodeValue simpleData=simpleDataList.get(j);
				String name=simpleData.getAttrMapValue("name");
				if("대해구도번호".equals(name)) {
					no1=simpleData.getText();
				}else if("소해구도 부번".equals(name)) {
					no2=simpleData.getText();
				}
//				else if("소해구도번호".equals(name)) {
//					no3=simpleData.getText();
//				}
			}
			String boundary=""+XmlParseUtil.getNodeData(placemark.getChildMap(), "/Polygon/outerBoundaryIs/LinearRing/coordinates", 1);
			
			String key=parseBoundary(boundary, lonList, latList);
			
			if(!key.isEmpty()) {
				//key : minLon_maxLat
				//value : 해구도번호
				marinAreaMap.put(key, no1+"_"+no2);//+"_"+no3);
			}else {
//				logger.error("키 생성 오류 : ["+no1+"_"+no2+"_"+no3+"] "+boundary);
				logger.error("키 생성 오류 : ["+no1+"_"+no2+"] "+boundary);
			}
			
		}
		

		lonArr =  lonList.toArray(new Integer[lonList.size()]);
		latArr =  latList.toArray(new Integer[latList.size()]);
		Arrays.sort(lonArr);
		Arrays.sort(latArr);
		
	}
	
	
	
	public String parseBoundary(String boundaryStr,Set<Integer> lonList,Set<Integer> latList) {
		String key="";
		String [] arr = boundaryStr.split(" ");
		double [] lonArr = new double[arr.length];
		double [] latArr = new double[arr.length];
		
		for (int i = 0; i < arr.length; i++) {
			String[] temp = arr[i].split(",");
			lonArr[i]=Double.parseDouble(temp[0]);
			latArr[i]=Double.parseDouble(temp[1]);
		}
		Arrays.sort(lonArr);
		Arrays.sort(latArr);

		double lon=lonArr[0]*100000;
		lon = Math.round(lon);

		double lat=latArr[0]*100000;
		lat = Math.round(lat);
		
		int lonInt = (int)lon;
		int latInt = (int)lat;
		
		lonList.add(lonInt);
		latList.add(latInt);
		
		
		key=lonInt+"_"+latInt;
		
		return key;
	}
	
	
	

	public String getMarineAreaFilePath() {
		return marineAreaFilePath;
	}


	public void setMarineAreaFilePath(String marineAreaFilePath) {
		this.marineAreaFilePath = marineAreaFilePath;
	}
	

	
}
