package org.eclipse.stem.ui.grapheditor;

/* Copyright (c) 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     IBM Corporation - initial API and implementation
*******************************************************************************/

import java.awt.Polygon;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;



/**
* Helper Class for creating GML files
* 
*/
public class GmlPolygon {
	
	
	String name = "undefined";//$NON-NLS-1$
	
	List<Double> lat = new ArrayList<Double>();
	List<Double> lng = new ArrayList<Double>();
	

	/**
	 * 
	 * @param name
	 * 
	 */
	public GmlPolygon(String name) {
		this.name = name;
	}
	
	public GmlPolygon(String name, List<Double> lat, List<Double> lng) {
		this.name = name;
		this.lat = lat;
		this.lng = lng;
	}
	
	public GmlPolygon(String name, Polygon polygon) {
		this.name = name;
		for (int i=0; i<polygon.npoints; i++)
		{
			lat.add((double)polygon.xpoints[i]);
			lng.add((double)polygon.ypoints[i]);			
		}
	}
	/**
	 * 
	 * @param dlat
	 * @param dlng
	 */
	public void addPoint(double dlat, double dlng) {
		//Activator.logInformation("READ "+dlat+", "+dlng);
		double factor = GraphDefs.R;
		dlat *= factor;
		dlng *= factor;
		long ilat = Math.round(dlat);
		long ilng = Math.round(dlng);
		dlat = ilat;
		dlng = ilng;
		dlat /= factor;
		dlng /= factor;
		//Activator.logInformation("rounded to "+dlat+", "+dlng);
		lat.add(new Double(dlat));
		lng.add(new Double(dlng));
	}// addpoint
	
	/**
	 * 
	 * @param tokensKML
	 */
	public void addPoint(String tokensKML) {
		StringTokenizer st = new StringTokenizer(tokensKML);
		String delim = "\r\n";//$NON-NLS-1$
		if (tokensKML.indexOf(delim) <= -1)
			delim = "\n";//$NON-NLS-1$
		while (st.hasMoreTokens()) {
			String valxyz = st.nextToken(delim).trim();
			StringTokenizer st2 = new StringTokenizer(valxyz);
			while (st2.hasMoreTokens()) {
				String lat = st2.nextToken(",");//$NON-NLS-1$
				String lng = st2.nextToken(",");//$NON-NLS-1$
				@SuppressWarnings("unused")
				String z = st2.nextToken(",");//$NON-NLS-1$

				double lt = (new Double(lat)).doubleValue();
				double lg = (new Double(lng)).doubleValue();
				lt *= GraphDefs.R;
				lg *= GraphDefs.R;
				int ilt = (int)Math.round(lt);
				int ilg = (int)Math.round(lg);
				lt = (double) ilt;
				lg = (double) ilg;
				lt /= GraphDefs.R;
				lg /= GraphDefs.R;
				this.addPoint(lt, lg);
			}
		}
	}// addpoint

	
	/**
	 * all lat long data as a single string for file output
	 * @return all lat long data as a single string
	 */
	public String getData() {
		String retVal = "";//$NON-NLS-1$
		for (int i = 0; i < lat.size(); i ++) {
			double lt = lat.get(i).doubleValue();
			double lg = lng.get(i).doubleValue();
			// this FIXES the order to what STEM expects vs KML
			retVal += lg+" "+lt;//$NON-NLS-1$
			if (i < lat.size()-1) retVal += " ";//$NON-NLS-1$
		}
		return retVal;
	}
	
	
}// gmlPolygon
