
package GraphType;

import clustering.MyPair;
import edu.uci.ics.jung.graph.AbstractTypedGraph;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.graph.util.Pair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DirectedDenseGraph<V,E> extends AbstractTypedGraph<V, E> implements DirectedGraph<V, E> {

    protected Map<V,List<MyPair<V,E>>> adjacency_list;

    public DirectedDenseGraph() {
        super(EdgeType.DIRECTED);
        adjacency_list = new HashMap<V, List<MyPair<V,E>>>();

    }

    public Collection<E> getInEdges(V v) {
        List<E> edges = new ArrayList<E>();
        for(V key : adjacency_list.keySet()){
            List<MyPair<V,E>> edges_to_check = adjacency_list.get(key);
            for(MyPair<V,E> edge : edges_to_check){
                if(edge.getFirst().equals(v))
                    edges.add(edge.getSecond());
            }
        }
        return edges;
    }

    public Collection<E> getOutEdges(V v) {
        List<E> edges = new ArrayList<E>();
        if(adjacency_list.containsKey(v)){
            for(MyPair<V,E> edge : adjacency_list.get(v)){
                edges.add(edge.getSecond());
            }
        }
        return edges;
    }

    public Collection<V> getPredecessors(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Collection<V> getSuccessors(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int inDegree(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int outDegree(V v) {
        if(adjacency_list.containsKey(v)){
            return adjacency_list.get(v).size();
        }
        else
            return 0;
    }

    public boolean isPredecessor(V v, V v1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isSuccessor(V v, V v1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getPredecessorCount(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getSuccessorCount(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public V getSource(E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public V getDest(E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isSource(V v, E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isDest(V v, E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean addEdge(E e, V v, V v1) {
        List<MyPair<V,E>> edge_list;
        if(adjacency_list.containsKey(v)){
            edge_list = adjacency_list.get(v);
        }
        else{
            edge_list = new ArrayList<MyPair<V,E>>();
        }
        edge_list.add(new MyPair(v1,e));
        adjacency_list.put(v, edge_list);

        if(!adjacency_list.containsKey(v1))
            adjacency_list.put(v1, new ArrayList<MyPair<V,E>>());

        return true;
    }

    public boolean addEdge(E e, V v, V v1, EdgeType et) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Pair<V> getEndpoints(E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public V getOpposite(V v, E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Collection<E> getEdges() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Collection<V> getVertices() {
        return adjacency_list.keySet();
    }

    public boolean containsVertex(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean containsEdge(E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getEdgeCount() {
        int edge_count = 0;
        for(V key : adjacency_list.keySet()){
            edge_count+=adjacency_list.get(key).size();
        }
        return edge_count;
    }

    public int getVertexCount() {
        return adjacency_list.keySet().size();
    }

    public Collection<V> getNeighbors(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Collection<E> getIncidentEdges(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Collection<V> getIncidentVertices(E e) {
        List<V> incident_vertices = new ArrayList<V>();
        for(V key : adjacency_list.keySet()){
            for(MyPair<V,E> edge : adjacency_list.get(key)){
                if (edge.getSecond().equals(e)){
                        incident_vertices.add(edge.getFirst());
                }
            }
        }
        return incident_vertices;
    }

    public E findEdge(V v, V v1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Collection<E> findEdgeSet(V v, V v1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean addVertex(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean addEdge(E e, Collection<? extends V> clctn) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean addEdge(E e, Collection<? extends V> clctn, EdgeType et) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean removeVertex(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean removeEdge(E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isNeighbor(V v, V v1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isIncident(V v, E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int degree(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getNeighborCount(V v) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public int getIncidentCount(E e) {
        return 1;
    }

    public EdgeType getEdgeType(E e) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public EdgeType getDefaultEdgeType() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Collection<E> getEdges(EdgeType et) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public int getEdgeCount(EdgeType et) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean addEdge(E e, Pair<? extends V> pair, EdgeType et) {
        throw new UnsupportedOperationException("Not supported yet.");
    }



}
