
package tmcsim.highwaymodel;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;

/**
 * PostmileCoords is a collection of Postmiles (id and LatLong Coordinates).
 * @author jdalbey
 */
public class PostmileCoords implements Iterable
{
    private List<Postmile> postmileList;
    public PostmileCoords()
    {
        postmileList = new ArrayList<Postmile>();
    }
    /** Accessor to value at given index */
    public Postmile get(int idx)
    {
        return postmileList.get(idx);
    }
    /** Return the size */
    public int size()
    {
        return postmileList.size();
    }
    /** Find the postmile with the given name */
    public Postmile find(String target)
    {
        int idx = 0;
        while (idx < postmileList.size() && !postmileList.get(idx).nameEquals(target))
        {
            idx++;
        }
        if (idx < postmileList.size())
        {
            return postmileList.get(idx);
        }
        else
        {
            return null;
        }
    }
    /** Load the postmile list from external file */
    public void load(Scanner scan)
    {
        try
        {
        String out = scan.next();
        //  split into an array 
        String[] results = out.split("\\n");
        for (String item : results)
        {
            String[] fields = item.split(",");
            String[] nameparts = fields[0].split(" ");
            String statepm = nameparts[2];
            // some postmiles come with a prefix, which we ignore
            if (Character.isLetter(statepm.charAt(0)))
            {
                statepm = statepm.substring(1);
            }  
            String revisedpm = nameparts[0] + " " + nameparts[1] + " " + statepm;
            Postmile pm;
            // If the file has 6 fields per line, include the perpx,y values
            if (fields.length == 6)
            {
                pm = new Postmile(revisedpm,fields[1],fields[2],fields[3],fields[4],fields[5]);
            }
            else // otherwise assume the file has just 4 fields
            {
                pm = new Postmile(revisedpm,fields[1],fields[2],fields[3]);
            }
            postmileList.add(pm);
        }
        }
        catch (Exception ex)  // probably badly formatted file
        {
            ex.printStackTrace();
        }
    }

    @Override
    public Iterator iterator()
    {
        return postmileList.iterator();
    }
    /**
     *  Postmile is a postmile id and its LatLong Coordinates.
     */
    final static class Postmile  
    {
        String name;  // the postmile name (Route,Direction,State postmile, e.g., 5 N 6.2)
        String latitude; // the latitude coordinate for this postmile
        String longitude; // the longitude coordinate for this postmile
        String street; // cross street name
        /* These fields are used by the map to adjust position of dot when zoomed */
        String perpx="0";  // perpendicular vector, x-component (default value)
        String perpy="0";  // perpendicular vector, y-component (default value)
        public Postmile(String name, String lat, String longitude, String street)
        {
            this.name = name.trim();
            this.latitude = lat.trim();
            this.longitude = longitude.trim();
            this.street = street.trim();
        }
        // This constructor is used if the file contains data for perpendicular vectors
        public Postmile(String name, String lat, String longitude, String street, String perpx, String perpy)
        {
            this.name = name.trim();
            this.latitude = lat.trim();
            this.longitude = longitude.trim();
            this.street = street.trim();
            this.perpx = perpx.trim();
            this.perpy = perpy.trim();
        }
        public boolean nameEquals(String target)
        {
            // remove .0 for comparing strings
            if (target.endsWith(".0"))
            {
                String truncTarget = target.substring(0,target.length()-2);
                return this.name.equals(truncTarget);
            }
            return this.name.equals(target);
        }
        @Override public boolean equals(Object aThat) 
        {
            if (this == aThat) return true;
            if (!(aThat instanceof Postmile)) return false;
            Postmile that = (Postmile) aThat;
            boolean r1 = this.name.equals(that.name);
            boolean r2 = this.latitude.equals(that.latitude);
            boolean r3 = this.longitude.equals(that.longitude);
            boolean r4 = this.street.equals(that.street);
            return r1 && r2 && r3 && r4;
        }
        @Override public String toString()
        {
            return name + ": " + latitude +","+ longitude +","+ street+","+ perpx +","+ perpy;
        }
        public String toJson()
        {
            String pattern =  "\n{\n   \"type\": \"Feature\",\n" +
                    "   \"id\": \"%s\",\n" +
                    "   \"geometry\":\n       {\n        \"type\": \"Point\",\n" +
                    "        \"coordinates\": [%s,%s]\n" +
                    "       },\n" +
                    "   \"properties\": \n" +         
                    "       {\"street\": \"%s\", " +
                    "\"color\": \"desiredcolor\", " +
                    "\"perpx\": \"%s\", " +
                    "\"perpy\": \"%s\"" +
                    "}\n},";

            return String.format(pattern, name, longitude, latitude, street, perpx, perpy);
        }
    }
}
