
package clustering;

import data.GraphBuilder;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseGraph;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.List;
import view.Viewer;

public class GraphClusterer implements ActionListener{

    private List<VertexScore<String>> global_ranking;
    private int currentElement;
    private Viewer viewGraph;
    private Graph<String, Edge<String>> graph;
    private boolean graph_output;
    private boolean isGraphDirected;
    private int minvolume;
    LocalSpectral<String,Edge<String>> clusterer;

    public GraphClusterer(String path, boolean isGraphDirected,int min_volume) {
        global_ranking = null;
        this.currentElement = 0;
        GraphBuilder builder = new GraphBuilder(isGraphDirected);
        builder.buildGraphFromARFF(path, 1000000);
        graph = builder.getGraph();
        viewGraph = new Viewer(graph, this);
        graph_output = true;
        this.isGraphDirected = isGraphDirected;
        this.minvolume = min_volume;
        this.clusterer = new LocalSpectral(graph);
    }

    public void actionPerformed(ActionEvent ae) {
        System.out.println("Clicked!");
        this.visualNextCluster();
    }

    public void clusterize(boolean graph_output){

       global_ranking = clusterer.getGlobalRank();
       this.graph_output = graph_output;

       System.out.println("GLOBAL RANKING");
       for(VertexScore<String> v : global_ranking)
           System.out.println(v.toString());
       
       if (graph_output)
            viewGraph.viewGraphRank(global_ranking,null);
    }

    public void visualNextCluster(){
       if(this.currentElement > global_ranking.size()-1)
           return;
       
       List<String> cut = clusterer.clusterPageRankPriors(global_ranking.get(currentElement).getVertex(),this.minvolume);
       Graph cut_graph;
       if (isGraphDirected)
            cut_graph = new DirectedSparseGraph<String, Edge<String>>();
        else
            cut_graph = new SparseGraph<String, Edge<String>>();
       for(String vertex : cut){
           Collection<Edge<String>> out_edges = graph.getOutEdges(vertex);
           for(Edge<String> edge : out_edges){
               String out_node = graph.getOpposite(vertex, edge);
               if (cut.contains(out_node)){
                   cut_graph.addEdge(edge, edge.getVertex1(),edge.getVertex2());
               }
           }
       }
       viewGraph.setGraph(cut_graph);
       float vertex_rank = (float) global_ranking.get(this.currentElement).getScore();
       viewGraph.setText("Page Rank Value: "+vertex_rank);
       if (graph_output)
            viewGraph.viewGraphRank(global_ranking, global_ranking.get(this.currentElement).getVertex());

       this.currentElement++;

     }
}
