/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package it.cnr.iasi.giant.thread;

import it.cnr.iasi.giant.Main;
import it.cnr.iasi.giant.io.IOWriter;
import it.cnr.iasi.giant.util.Helper;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.ProgressMonitorInputStream;

/**
 *
 * @author Fabio Cumbo
 * @info GIANT
 * @version v1.0
 * @organization IASI-CNR : Istituto di Analisi dei Sistemi ed Informatica 
 *                  "Antonio Ruberti" - Consiglio Nazionale delle Ricerche
 * 
 */
public class ClusterLoaderThread extends Thread {
    
    private static File file;
    private static String filepath;
    private static String filename;
    private static HashMap<Integer, ArrayList<String>> clusters = new HashMap<Integer, ArrayList<String>>();
    private static HashMap<Integer, HashMap<Integer, ArrayList<String>>> clustersKRange = new HashMap<Integer, HashMap<Integer, ArrayList<String>>>();
    
    public ClusterLoaderThread(File clusterFile) {
        super(clusterFile.getName());
        file = clusterFile;
        filepath = clusterFile.getAbsolutePath();
        filename = clusterFile.getName();
    }
    
    @Override
    public void run() {
        try {
            JFrame frame = new JFrame();
            frame.setVisible(true);
            frame.setAlwaysOnTop(true);
            try {
                InputStream fstream = new FileInputStream(file.getAbsolutePath());
                    InputStream fstreamMonitor = new ProgressMonitorInputStream(frame, "Loading...", fstream);
                    DataInputStream in = new DataInputStream(fstreamMonitor); 
                    BufferedReader br = new BufferedReader(new InputStreamReader(in));
                frame.setVisible(false);
                
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    Logger.getLogger(ClusterLoaderThread.class.getName()).log(Level.SEVERE, null, ex);
                }
                
                String strLine;
                
                try {
                    //int count = 0;
                    
                    while ((strLine = br.readLine()) != null) {
                        Helper helper = new Helper();
                        ArrayList<String> line = helper.tabPattern(strLine);
                        
                        //INTERNAL CLUSTER FILE FORMAT:
                        /*
                         *  node1   cluster1
                         *  node2   cluster1
                         *  node3   cluster1
                         *  node4   cluster2
                         *  node5   cluster2
                         *  node6   cluster3
                         *  ...
                         */
                        try {
                            int clusterNum = Integer.valueOf(line.get(1));
                            if (clusters.get(clusterNum) != null) {
                                ArrayList<String> tmp =  clusters.get(clusterNum);
                                tmp.add(line.get(0));
                                clusters.put(clusterNum, tmp);
                            }
                            else {
                                ArrayList<String> tmp = new ArrayList<String>();
                                tmp.add(line.get(0));
                                clusters.put(clusterNum, tmp);
                            }
                        } catch (ClassCastException e) {
                            JOptionPane.showMessageDialog(Main.getApp().getFrameOverride(), "INTERNAL ERROR: Invalid internal cluster file format!", "ERROR!", JOptionPane.ERROR_MESSAGE);
                            return;
                        }
                        
                        
                        //EACH ROW IS A CLUSTER
                        //clusters.put(count, line);
                        //count++;
                    }
                    
                    System.err.println("CLUSTERS: " + clusters.size());
                    for (int c: clusters.keySet())
                        System.out.println("Cluster: " + c + " - " + (clusters.get(c)).size() + " nodes");
                                        
                    br.close();
                    in.close();
                    fstreamMonitor.close();
                    fstream.close();
                    
                    if (Main.getGiantAdapter().getCyApplicationManager().getCurrentNetwork()!=null || !Main.getGiantAdapter().getCyApplicationManager().getCurrentNetwork().getNodeList().isEmpty()) {
                        if (!ClusterLoaderThread.getClustersData().isEmpty()) {
                            Main.getApp().getComputePZ_button().setEnabled(true);
                        }
                    }
                    
                    IOWriter writer = new IOWriter();
                    setFilePath(writer.writeTmpClusterFile(clusters));
                    
                }
                catch (NullPointerException e) {                                
                    br.close();
                    in.close();
                    fstreamMonitor.close();
                    fstream.close();
                }
            }
            catch (FileNotFoundException e) {}
        } catch (IOException e) { }
    }
    
    public static HashMap<Integer, ArrayList<String>> getClustersData() {
        return clusters;
    }
    
    public static void setClusters(HashMap<Integer, ArrayList<String>> data) {
        clusters = data;
    }
    
    public static File getClusterFdile() {
        return file;
    }
    
    public static void setClusterFilePath(String path) {
        filepath = path;
    }
    
    public static String getFilePath() {
        return filepath;
    }
    
    public static void setClusterFileName(String name) {
        filename = name;
    }
    
    public static String getFileName() {
        return filename;
    }
    
    public static void setClustersKRange(HashMap<Integer, HashMap<Integer, ArrayList<String>>> clusters) {
        clustersKRange = clusters;
    }
    
    public static HashMap<Integer, HashMap<Integer, ArrayList<String>>> getClustersKRange() {
        return clustersKRange;
    }
    
    public static Integer getClusterForNode(String node) {
        for (Integer clus: clusters.keySet()) {
            if (clusters.get(clus).contains(node))
                return clus;
        }
        return 0;
    }
    
    public static void setFilePath(String path) {
        filepath = path;
    }
    
}
