package uwp.cs.edu.parkingtracker.navigation;

import android.content.Context;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;


/**
 * Created by Able on 4/27/2015.
 */

public class NodeParser {

     // Column index of the building column.
    private static final int BUILDING = 0;

     // Column index of the node type column.
    private static final int NODE_TYPE = 1;

     // Column index of the node longitude column.
    private static final int NODE_LONG = 2;

     // Column index of the node latitude column.
    private static final int NODE_LAT = 3;

     // Column index of the node id column.
    private static final int NODE_ID = 4;

     // Column index of the node neighbors column.
    private static final int NODE_NEIGHBORS = 5;

    // radius of earth in km
    private static final int RADIUS = 6371;

    //map used to contain all vertices. <Vertex Id, Vertex>
    public static HashMap<String, Vertex> nodeMap;

    //singleton instance
    private static NodeParser mInstance = null;

    //constructor
    public NodeParser(Context context) {
        nodeMap = new HashMap<>();
        int id = context.getResources().getIdentifier("nodemap", "raw", context.getPackageName());
        InputStream is = context.getResources().openRawResource(id);
        parseNodeFile(is);
    }

    //get single instance
    public static NodeParser getInstance(Context context) {
        if (mInstance == null) {
            synchronized (NodeParser.class) {
                if (mInstance == null) {
                    mInstance = new NodeParser(context);
                }
            }
        }
        return mInstance;
    }

    public static void parseNodeFile(InputStream inputStream) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                inputStream));
        try {
            reader.readLine();
            String line;
            while ((line = reader.readLine()) != null) {
                parseLine(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        setAdjacencies();

    }

    private static void parseLine(String line) {

        String[] cells = line.split(",");
        if (cells.length > 0) {

            String nodeLong = cells[NODE_LONG].toUpperCase(Locale.ENGLISH);
            String nodeLat = cells[NODE_LAT].toUpperCase(Locale.ENGLISH);
            String nodeId = cells[NODE_ID].toUpperCase(Locale.ENGLISH);
            //
            String nodeNeigh = cells[NODE_NEIGHBORS].toUpperCase(Locale.ENGLISH);

            String neighbors[] = nodeNeigh.split(" ");

            Vertex temp = new Vertex(nodeId);
            temp.neighbors = new ArrayList(Arrays.asList(neighbors));
            temp.lat = Double.parseDouble(nodeLong);
            temp.lon = Double.parseDouble(nodeLat);

            nodeMap.put(temp.name, temp);

        }
    }

    // updates the nodemap to set the adjacencies for each vertex
    private static void setAdjacencies() {

        ArrayList<String> keySet = new ArrayList(nodeMap.keySet());
        for (String key : keySet) {
            // current vertex
            Vertex temp = nodeMap.get(key);
            ArrayList<String> neighbors = new ArrayList(temp.neighbors);
            double weight;

            // for each neighbor
            for (int i = 0; i < neighbors.size(); i++) {
                // a neighbor to current vertex
                Vertex targetTemp = nodeMap.get(neighbors.get(i));
                weight = calculateEdge(temp, targetTemp);
                temp.adjacencies.add(new Edge(targetTemp, weight));
            }

        }
    }
    // returns the distance between two vertices
    public static double calculateEdge(Vertex current, Vertex neighbor) {

        double lat = current.lat;
        double lon = current.lon;
        double lat2 = neighbor.lat;
        double lon2 = neighbor.lon;

        Double latDistance = deg2rad(lat2 - lat);
        Double lonDistance = deg2rad(lon2 - lon);
        Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(deg2rad(lat)) * Math.cos(deg2rad(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double distance = RADIUS * c * 1000; // convert to meters
        return distance;

    }

    private static double deg2rad(double deg) {
        return (deg * Math.PI / 180.0);
    }

}

@@ -73,16 +73,66 @@
 ntext;%0A%0A
+import com.google.android.gms.maps.model.LatLng;%0A%0A
 import j
@@ -419,25 +419,24 @@
 rser %7B%0A%0A    
- 
 // Column in
@@ -507,17 +507,16 @@
 G = 0;%0A%0A
- 
     // C
@@ -597,17 +597,16 @@
 E = 1;%0A%0A
- 
     // C
@@ -692,25 +692,24 @@
 G = 2;%0A%0A    
- 
 // Column in
@@ -785,17 +785,16 @@
 T = 3;%0A%0A
- 
     // C
@@ -871,17 +871,16 @@
 D = 4;%0A%0A
- 
     // C
@@ -4694,10 +4694,631 @@
 %0A    %7D%0A%0A
+    // returns the nodeMap as %3Cvertex ID, Vertex%3E%0A    public HashMap %3CString, Vertex%3E getNodeMap()%7B%0A        return nodeMap;%0A    %7D%0A%0A    // returns the nodeMap as %3CVertex LatLng, Vertex%3E%0A    public HashMap %3CLatLng, Vertex%3E getLatLngNodeMap()%7B%0A%0A        ArrayList%3CString%3E keySet = new ArrayList(nodeMap.keySet());%0A        HashMap %3CLatLng, Vertex%3E latLngNodeMap = new HashMap();%0A%0A        for (String key : keySet) %7B%0A            Vertex temp = this.nodeMap.get(key);%0A            LatLng latLngTemp = new LatLng(temp.lat, temp.lon);%0A            latLngNodeMap.put(latLngTemp, temp);%0A        %7D%0A%0A        return latLngNodeMap;%0A    %7D%0A%0A
 %7D%0A

Add getLatLngNodeMap() method so we can lookup a vertex based on it's LatLng