import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.geom.MultiLineString;
import com.vividsolutions.jts.geom.impl.CoordinateArraySequence;

import fr.ocelet.runtime.List;

/**
 * Holds a list of list of Positions Every Polyline can contain more than one
 * Line. On Line is a list of Positions
 * 
 * @author pdegenne@teledetection.fr
 */
public class Polyline {

	private List<List<Position>> listOfLines;

	public Polyline(final List<List<Position>> llp) {
		super();
		this.listOfLines = llp;
	}

	public Polyline() {
		super();
		listOfLines = new List<List<Position>>();
	}

	
	/**
	 * Helper to translate this Polyline using one same
	 * service call
	 * 
	 * @param dx Distance to be applied to x
	 * @param dy Distance to be applied to y
	 * @since 4 jun 2012
	 */
	public void addTo_xy(double dx, double dy) {
		for (List<Position> line : listOfLines) {
			for (Position pos : line) pos.addTo_xy(dx, dy);
		}
	}
	
	/**
	 * Adds one line to a Polyline
	 * 
	 * @param line
	 */
	public void addLine(List<Position> line) {
		listOfLines.add(line);
	}

	/**
	 * Gives the number of Lines contained in this PolyLine
	 * 
	 * @return An int number
	 */
	public int nbLines() {
		return listOfLines.size();
	}

	/**
	 * Returns one Line from this PolyLine
	 * 
	 * @param index
	 *            Number of the required Line
	 * @return One Line in the form of a List<Position>
	 */
	public List<Position> getLine(int index) {
		return listOfLines.get(index);
	}

	/**
	 * Produces a JTS Geometry object from the content of this Polyline
	 * 
	 * @return Either a LineString or a MultiLineString depending on the number
	 *         of geometry elements contained in the Polyline
	 */
	public Geometry asGeometry() {
		int sz = listOfLines.size();
		Geometry geom = null;
		if (sz == 1) {
			// Position[] tpos = (Position[]) listOfLines.get(0).toArray();
			List<Position> pline = listOfLines.get(0);
			Coordinate[] coords = new Coordinate[pline.size()];
			int ci = 0;
			for (Position pos : pline) {
				coords[ci++] = new Coordinate(pos.x, pos.y);
			}
			geom = new LineString(new CoordinateArraySequence(coords),
					new GeometryFactory());
		} else if (sz > 1) {
			LineString[] lines = new LineString[sz];
			for (int lsi = 0; lsi < sz; lsi++) {
				List<Position> pline = listOfLines.get(lsi);
				Coordinate[] coords = new Coordinate[pline.size()];
				int ci = 0;
				for (Position pos : pline) {
					coords[ci++] = new Coordinate(pos.x, pos.y);
				}
				lines[lsi] = new LineString(
						new CoordinateArraySequence(coords),
						new GeometryFactory());
			}
			geom = new MultiLineString(lines, new GeometryFactory());
		}
		return geom;
	}

   /**
    * 
    * @return
    */
	public MPoints intersection(Polyline line) {
     Geometry thisg = this.asGeometry();
     Geometry lgeom = line.asGeometry();
     Geometry interpoints = thisg.intersection(lgeom);
	 return new MPoints(interpoints);
	}
	
}
