/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package medusa.georgios.Layouts;

import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import javax.swing.JOptionPane;
import medusa.MedusaSimplerFrame;
import medusa.georgios.ClusteringAlgorithms.KMeans2;
import medusa.georgios.ClusteringAlgorithms.List2Graph;
import medusa.georgios.ClusteringAlgorithms.LoadClusters.LoadClusters;
import medusa.georgios.color_factory.ColorFactory;
import medusa.georgios.vecmathpackage.Point3d;
import medusa.georgios.enhanced_mcl.My_MarkovClustering;
import medusa.georgios.vecmathpackage.Color3f;
import medusa.graph.BasicGraph;
import medusa.graph.Edge;
import medusa.graph.Graph;
import medusa.graph.Node;

/**
 *
 * @author Pavlopoulos
 */
public class Layouts extends MedusaSimplerFrame {

    public static LoadClusters cl;
    private static ArrayList final_Order_of_Nodes = new ArrayList();
    private static ArrayList Used_Nodes = new ArrayList();
    public static medusa.georgios.ClusteringAlgorithms.Affinity_Propagation affinity_propagation_clustering;
    public static medusa.georgios.enhanced_mcl.My_MarkovClustering markov_clustering;
    public static medusa.georgios.ClusteringAlgorithms.KMeans2 kmeans;
    public static String affinity_propagation_report = null;
    public static String markov_clustering_report = null;
    //----------------------------------------------------------------------------------------------------------------------------
    static ArrayList tmp = new ArrayList();
    static int distance = 0;

    public Layouts() {
    }



    private static int yes_no(String message){
        int s = JOptionPane.showConfirmDialog
                (MedusaSimplerFrame.stringletPanel,
                message,
                "",
                JOptionPane.YES_NO_OPTION);

        return s;
    }

    private static int Calculate_distances_of_nodes(medusa.graph.Node node, Graph g ) {
        distance = 0;
        tmp.clear();
        //System.out.println(node.Connections_this_Node_is_source.size());
        GiveNode_take_distance(node, g);
        return distance;
    }

    private static void GiveNode_take_distance(medusa.graph.Node node, Graph g ) {
        if (!Used_Nodes.contains(node.getLabel())) {
            Used_Nodes.add(node.getLabel());
            final_Order_of_Nodes.add(node);
        }
        if (tmp.size() <= g.getNodeSize()) {
            if (node.getConnections() != 0) {

                int i = 0;
                for (Iterator it = g.edgesIterator(); it.hasNext();) {
                    Edge e = (Edge) it.next();
                    String source = e.getFromName();
                    String destination = e.getToName();
                    if (source.compareToIgnoreCase(node.getLabel()) == 0) {
                        if (!tmp.contains(g.getNode(destination))) {
                            distance++;
                            tmp.add(g.getNode(destination));
                            if (!Used_Nodes.contains(destination)) {
                                Used_Nodes.add(destination);
                                final_Order_of_Nodes.add(g.getNode(destination));
                            }
                            GiveNode_take_distance(g.getNode(destination),g);
                        }
                        i++;
                    }
                }



            }
        }
    }

//----------------------------------------------------------------------------------------------------------------------------
    public static void Apply_GO_like_Coordinates(Graph g, Component screen ) {
        if (g.getNodeSize() > 1) {
            double z = 0;
            ArrayList coor = new ArrayList();
            int counter = 0;
            final_Order_of_Nodes.clear();
            Used_Nodes.clear();

            int number_of_points = g.getNodeSize();

            ArrayList point_set = new ArrayList();

            ArrayList Order_of_Nodes = new ArrayList();
            ArrayList Children_of_Nodes = new ArrayList();
            Hashtable GiveInternalNameGetGeneOntologyLayoutNode = new Hashtable();
            int number_of_levels_for_GO = 0;

            int counteri = 0;
            for (Iterator it = g.nodesIterator(); it.hasNext();) {
                Node node = (Node) it.next();
                GeneOntologyLayoutNode nnn = new GeneOntologyLayoutNode(node, Calculate_distances_of_nodes(node,g),g);
                Order_of_Nodes.add(node.getLabel());
                Children_of_Nodes.add(nnn.distance);
                GiveInternalNameGetGeneOntologyLayoutNode.put(node.getLabel(), nnn);
                counteri++;
            }


            //  rank according to children
            boolean isSorted;
            int tempVariable;
            String tmp_vertice;
            int numberOfTimesLooped = 0;
            do {
                isSorted = true;
                for (int i = 1; i < Order_of_Nodes.size() - numberOfTimesLooped; i++) {
                    if (Children_of_Nodes.get(i) < Children_of_Nodes.get(i - 1)) {
                        tempVariable = Children_of_Nodes.get(i);
                        Children_of_Nodes.set(i, Children_of_Nodes.get(i - 1));
                        Children_of_Nodes.set(i - 1, tempVariable);

                        tmp_vertice = Order_of_Nodes.get(i);
                        Order_of_Nodes.set(i, Order_of_Nodes.get(i - 1));
                        Order_of_Nodes.set(i - 1, tmp_vertice);

                        isSorted = false;
                    }
                }
                numberOfTimesLooped++;
            } while (!isSorted);



//   System.out.println("Order_of_Nodes:"+Order_of_Nodes.size());
            for (int i = Order_of_Nodes.size() - 1; i >= 0; i--) {  //System.out.println("i:"+i);
                GeneOntologyLayoutNode n1 = GiveInternalNameGetGeneOntologyLayoutNode.get(Order_of_Nodes.get(i));
                if (n1 != null) {

                    int ccc = 0;
                    for (Iterator it = g.edgesIterator(); it.hasNext();) {
                        Edge e = (Edge) it.next();
                        String source = e.getFromName();
                        String destination = e.getToName();
                        if (source.compareToIgnoreCase(n1.node.getLabel()) == 0) {
                            ccc++;
                        }
                    }

                    if (ccc != 0) {

                        int j = 0;
                        for (Iterator it = g.edgesIterator(); it.hasNext();) {
                            Edge e = (Edge) it.next();
                            String source = e.getFromName();
                            String destination = e.getToName();
                            if (source.compareToIgnoreCase(n1.node.getLabel()) == 0) {
                                medusa.graph.Node mm = g.getNode(e.getFromName());
                                GeneOntologyLayoutNode n2 = GiveInternalNameGetGeneOntologyLayoutNode.get(mm.getLabel());
                                if (n2 != null) {
                                    n2.level = n1.level + 1;
                                    number_of_levels_for_GO = Math.max(number_of_levels_for_GO, n2.level);
                                }
                            }
                            j++;
                        }
                    }

                }
            }

            number_of_levels_for_GO++;

//   System.out.println("levels:"+number_of_levels_for_GO);
//    System.out.println("n.node.getInternalName()\tn.level\tn.distance\tn.parents+\tn.children");
//    for (int i = 0; i < Order_of_Nodes.size(); i++)
//    {
//        GeneOntologyLayoutNode ntmp = GiveInternalNameGetGeneOntologyLayoutNode.get(Order_of_Nodes.get(i));
////        System.out.println(ntmp.node.getInternalName()+"\t"+ntmp.level+"\t"+ntmp.distance+"\t"+ntmp.parents+"\t"+ntmp.children);
//    }

//             System.out.println("~~~~~~final_Order_of_Nodes~~~~~~~"+final_Order_of_Nodes.size());
//             System.out.println("~~~~~~Used_Nodes~~~~~~~"+Used_Nodes.size());

            double CurX, CurY, prosX, prosY;
            Point3d p;
            medusa.graph.Node Node = null;

            try {
                double start_y = screen.getHeight() - 15;
                double step_y = screen.getHeight() / (number_of_levels_for_GO + 1);
                double pos_tmp = 0;

                // System.out.println("~~~~~~~XXXXXXXXXXX~~~~~~~~~~~"+final_Order_of_Nodes.size());
                for (int n = 0; n < number_of_levels_for_GO; n++) {

                    double start_x = 15;
                    double pos_x = start_x;
                    double pos_y = start_y;
                    ArrayList semi_final_Order_of_Nodes = new ArrayList();


                    for (int j = 0; j < final_Order_of_Nodes.size(); j++) {
                        GeneOntologyLayoutNode m = GiveInternalNameGetGeneOntologyLayoutNode.get(final_Order_of_Nodes.get(j).getLabel());
                        if (m.level == n) {
                            semi_final_Order_of_Nodes.add(final_Order_of_Nodes.get(j));
                        }
                    }
                    //  System.out.println("~~~~~semi_final_Order_of_Nodes~~~~~~~~"+semi_final_Order_of_Nodes.size());


                    double step_x = screen.getWidth() / (semi_final_Order_of_Nodes.size() + 1);

                    //  System.out.println("level:"+n+"\t"+semi_final_Order_of_Nodes.size());
                    for (int i = 0; i < semi_final_Order_of_Nodes.size(); i++) {
                        Node = semi_final_Order_of_Nodes.get(i);
                        GeneOntologyLayoutNode nn = GiveInternalNameGetGeneOntologyLayoutNode.get(Node.getLabel());

                        pos_x = start_x + (i + 1) * step_x;
                        pos_y = start_y - (step_y) * (number_of_levels_for_GO / (n + 1));//Reinhard

                        pos_y = start_y - step_y * (n + 1); //------------mine

                        double zz = 0;
                        if (semi_final_Order_of_Nodes.size() >= 60) {
                            if (i % 2 == 0) {
                                zz += 1.5f;
                            }
                        }
                        p = new Point3d(pos_x, pos_y, zz);
                        nn.p = p;
                    }

                }




                for (int i = 0; i < final_Order_of_Nodes.size(); i++) {
                    GeneOntologyLayoutNode nn = GiveInternalNameGetGeneOntologyLayoutNode.get(final_Order_of_Nodes.get(i).getLabel());
                    point_set.add(nn.p);
                //System.out.println("point:"+"\t"+nn.p);
                }
//System.out.println("GiveInternalNameGetGeneOntologyLayoutNode:"+GiveInternalNameGetGeneOntologyLayoutNode.size());
//System.out.println("final_Order_of_Nodes:"+final_Order_of_Nodes.size());
//System.out.println("normalized_point_set:"+normalized_point_set.size());

                for (int i = 0; i < final_Order_of_Nodes.size(); i++) {
                    Node = final_Order_of_Nodes.get(i);
                    if (Node != null) {
                        Node.setX(point_set.get(i).x);
                        Node.setY(point_set.get(i).y);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

//----------------------------------------------------------------------------------------------------------------------------
    //----------------------------------------------------------------------------------------------------------------------------
    public static void Apply_Distance_Geomretry_Coordinates(Graph g, Component screen ) {

        if (g.getNodeSize() > 1) {
            try {
                ArrayList normalized_point_set = new ArrayList();
                ArrayList point_set = new ArrayList();
                int number_of_points = g.getNodeSize();
                int number_of_connections = g.getEdges().size();

                ArrayList clustering_connections = new ArrayList();

                for (Iterator it = g.edgesIterator(); it.hasNext();) {
                    Edge e = (Edge) it.next();
                    String source = e.getFromName();
                    String destination = e.getToName();
                    clustering_connections.add(source + "\t" + destination + "\t" + e.getConf());
                }



                List2Graph gg = new List2Graph(clustering_connections);
                int elements = gg.labels.size();

                medusa.georgios.Distance_Geometry.DistanceGeometry DG = new medusa.georgios.Distance_Geometry.DistanceGeometry();
                point_set = DG.distribute_nodes(gg.return_double_matrix());

                Point3d_VectorNormalization coordinates = new Point3d_VectorNormalization(point_set, 15f, (Math.min(screen.getWidth() - 1, screen.getHeight() - 1)) - 15);
                normalized_point_set = coordinates.Return_Normalized_Vector();

                int counteri = 0;
                for (Iterator it = g.nodesIterator(); it.hasNext();) {
                    Node node = (Node) it.next();
                    node.setX(normalized_point_set.get(counteri).x);
                    node.setY(normalized_point_set.get(counteri).y);
                    counteri++;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
//----------------------------------------------------------------------------------------------------------------------------

    public static ArrayList Apply_Circular_Coordinates(Graph g ,Component screen) {

        if (g.getNodeSize() > 1) {
            double CurX, CurY, prosX, prosY;
            ArrayList point_set = new ArrayList();
            Point3d p;
            try {
                if (g.getNodeSize() >= 2) {

                    double R = (Math.min(screen.getWidth() - 1, screen.getHeight() - 1)) / 2 - 10, R2;
                    double Xc = screen.getWidth() / 2, Yc = screen.getHeight() / 2, Zc = 0;
                    double x = screen.getWidth() / 2, y = screen.getHeight() / 2, z = 0;
                    double Du = 0, angle_step;
                    double[][] ctrlpoints = new double[g.getNodeSize()][3];
                    angle_step = 360f / (g.getNodeSize() + 1);

                    /***************************************************/
                    for (int i = 0; i < g.getNodeSize(); i++) {

                        //System.out.println("-------------"+Du);
                        x = Xc + R * (float) Math.cos(Math.toRadians(Du));
                        y = Yc + R * (float) Math.sin(Math.toRadians(Du));

                        z = 0;
                        ctrlpoints[i][0] = x;
                        ctrlpoints[i][1] = y;
                        ctrlpoints[i][2] = z;
                        Du = Du + angle_step;

                        CurX = ctrlpoints[i][0];
                        CurY = ctrlpoints[i][1];
                        p = new Point3d(CurX, CurY, 0);
                        point_set.add(p);
                    }

                    int counteri = 0;
                    for (Iterator it = g.nodesIterator(); it.hasNext();) {
                        Node node = (Node) it.next();
                        node.setX(point_set.get(counteri).x);
                        node.setY(point_set.get(counteri).y);
                        counteri++;
                    }
                }
                System.gc();

            } catch (Exception e) {
                e.printStackTrace();
            }
            return point_set;
        }
        return null;
    }
    //-----------------------------------------------------

    public static int spread_to_grid(int n) {
        int result = 0, i = 0;
        double x = n;
        while (i >= 0) {
            i++;
            if (i * i >= n) {
                result = i;
                break;
            }
        }

        return result;
    }
    //----------------------------------------------------------------------------------------------------------------------------

    public static void Apply_Grid_Coordinates(Graph g,Component screen ) {

        if (g.getNodeSize() > 1) {
            double z = 0;
            ArrayList coor = new ArrayList();
            float x, y;
            int counter = 0;
            float distance_between_points = 0f;
            int number_of_points = g.getNodeSize();
            float number_of_points_per_line = 0;
            if (number_of_points % 2 == 0) {
                number_of_points_per_line = spread_to_grid(number_of_points + 1);
            } else {
                number_of_points_per_line = spread_to_grid(number_of_points);
            }


            distance_between_points = number_of_points_per_line;


            float temp_width = Math.min(screen.getWidth() * 0.9f, screen.getWidth() * 0.9f);
            distance_between_points = temp_width / (number_of_points_per_line - 1);
            distance_between_points = distance_between_points;
            if (distance_between_points == 0) {
                distance_between_points = 0.001f;
            }

            System.out.println("distance_between_points:" + distance_between_points);

            float start_x = 15;
            float start_y = 15;
            double coorz = 0;
            if (number_of_points_per_line == 1) {
                double coorx = 0;
                double coory = 0;
                Point3d point = new Point3d(coorx, coory, coorz);
                coor.add(point);
            } else {
                for (y = 0; y < number_of_points_per_line; y++) {
                    start_x = 15;
                    for (x = 0; x < number_of_points_per_line; x++) {
                        if (coor.size() < number_of_points) {
//
                            double coorx = start_x + x * distance_between_points;
                            double coory = start_y + y * distance_between_points;
                            Point3d point = new Point3d(coorx, coory, coorz);
                            coor.add(point);
                        }

                    }
                }
            }

            int counteri = 0;
            for (Iterator it = g.nodesIterator(); it.hasNext();) {
                Node node = (Node) it.next();
                node.setX(coor.get(counteri).x);
                node.setY(coor.get(counteri).y);
                counteri++;
            }
        }
    }
    //----------------------------------------------------------------------------------------------------------------------------

    public static boolean Initialize_Kmeans(BasicGraph gg, int nclusters ) {
         try {

        cl=null;
        ArrayList clustering_connections = new ArrayList();
        boolean is_ready_to_run = true;

        int number_of_points = gg.getNodeSize();
        int number_of_connections = gg.getEdges().size();

        for (Iterator it = gg.edgesIterator(); it.hasNext();) {
            Edge e = (Edge) it.next();
            String source = gg.getNode(e.getFromName()).getLabel();
            String destination = gg.getNode(e.getToName()).getLabel();
            clustering_connections.add(source + "\t" + destination + "\t" + e.getConf());
        }


        String expr = Integer.toString(nclusters);
        if (nclusters<=0) 
            expr = JOptionPane.showInputDialog(MedusaSimplerFrame.stringletPanel,"Enter number of clusters");

        // System.out.println(expr);
 

        if (expr.matches("[0-9]+")) {
            int num_of_clusters = Integer.parseInt(expr);
            System.out.println("Running Kmeans");
            List2Graph g = new List2Graph(clustering_connections);
            //kmeans = new KMeans2_backup(num_of_clusters, g.A, g.labels);
            kmeans = new KMeans2(num_of_clusters, gg);
            
            if (num_of_clusters < g.labels.size()) {
                kmeans.runKMeans();
                System.out.println(kmeans.getReport());
//              kmeans.perform_and_get_results();
                kmeans.Save_To_File("Kmeans_clustering" + num_of_clusters + ".txt", kmeans.getReport());
                System.out.println("Kmeans results was saved in " + "Kmeans_clustering" + num_of_clusters + ".txt");
                is_ready_to_run = true;
            } else {
                JOptionPane.showMessageDialog(MedusaSimplerFrame.stringletPanel, "User must enter a number of clusters below " + g.labels.size());
                is_ready_to_run = false;
            }

        } else {
            JOptionPane.showMessageDialog(MedusaSimplerFrame.stringletPanel, "User must enter a number.");
            is_ready_to_run = false;
        }


        return is_ready_to_run;
           } catch (Exception e) {}
         return false;
    }


    //----------------------------------------------------------------------------------------------------------------------------
    public static void Initialize_MarkovClustering(Graph gg,Component screen) {
        ArrayList clustering_connections = new ArrayList();
        cl=null;
        int number_of_points = gg.getNodeSize();
        int number_of_connections = gg.getEdges().size();
        for (Iterator it = gg.edgesIterator(); it.hasNext();) {
            Edge e = (Edge) it.next();
            String source = gg.getNode(e.getFromName()).getLabel();
            String destination = gg.getNode(e.getToName()).getLabel();
            clustering_connections.add(source + "\t" + destination + "\t" + e.getConf());
        }

        System.out.println("Running Markov Clustering");
        markov_clustering = new My_MarkovClustering(clustering_connections);
        if(screen==stringletPanel){
        System.out.println(markov_clustering.Save_To_File("MCL.txt", true));
        System.out.println("Markov Clustering results were saved in " + " MCL.txt");
        }
        else
            System.out.println(markov_clustering.Save_To_File("MCL.txt", false));


    }



     /**
     * Run k-means clustering with a given number of clusters. It will ask a question about required clusters. 
     * @param g graph
     * @param screen component 
     */
     public static void Apply_Kmeans_Clustering(Graph g,Component screen) {
      Apply_Kmeans_Clustering(g,screen, 0);
     }
    


     /**
     * Run k-means clustering with a given number of clusters. No question will be asked. 
     * @param g graph
     * @param screen component 
     @ @param nclusters number of clusters
     */
    public static void Apply_Kmeans_Clustering(Graph g,Component screen, int nclusters) {


       // keep_current_colors=yes_no("Keep current node coloring?");
        cl=null;

        if (g.getNodeSize() > 1) {
            try {
                int number_of_points = g.getNodeSize();
                int number_of_connections = g.getEdges().size();
                boolean ik = Initialize_Kmeans(g, nclusters);
                if (Initialize_Kmeans(g,nclusters) == true) {
                    
                    /* could not resolve this... clean up the engine?
                    cl = new LoadClusters(kmeans.getReport());
                    distribute_clusters();
                    */
                    
                    // putting in a temporary solution
                    
                    // this is a map of nodes with their cluster numbers. 
                    // usually i would go through the nodes and assign a color depending on
                    // the cluter number.
                    // Have a look and see if Layout can be simplified
                   Map nodes_clusters=kmeans.getClusterMap();
                   cl = new LoadClusters(kmeans.getReport());
                   distribute_clusters(g, screen);
                   if(screen==stringletPanel){
                   System.out.println(kmeans.Save_To_File("kmeans"+kmeans.getK()+".txt"));
                   System.out.println("kmeans results was saved in " + "kmeans"+kmeans.getK()+".txt");
                   }
                   
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //----------------------------------------------------------------------------------------------------------------------------
    public static void Apply_MCL_Propagation_Clustering(Graph gg,Component screen) {
       // keep_current_colors=yes_no("Keep current node coloring?");

        if (gg.getNodeSize() > 1) {
            try {
                int number_of_points = gg.getNodeSize();
                int number_of_connections = gg.getEdges().size();
               // if (markov_clustering_report == null)
                {
                    Initialize_MarkovClustering(gg, screen);
                }

                markov_clustering_report = markov_clustering.getReport();
                cl = new LoadClusters(markov_clustering_report);

                distribute_clusters(gg,screen);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    //----------------------------------------------------------------------------------------------------------------------------
    public static void Initialize_AffinityPropagation(Graph g, Component screen) {

        ArrayList clustering_connections = new ArrayList();
        int number_of_points = g.getNodeSize();
        int number_of_connections = g.getEdges().size();

        for (Iterator it = g.edgesIterator(); it.hasNext();) {
            Edge e = (Edge) it.next();
            String source = g.getNode(e.getFromName()).getLabel();
            String destination = g.getNode(e.getToName()).getLabel();
            clustering_connections.add(source + "\t" + destination + "\t" + e.getConf());
        }

        System.out.println("Running Affinity Propagation");
        affinity_propagation_clustering = new medusa.georgios.ClusteringAlgorithms.Affinity_Propagation(clustering_connections);
        System.out.println("Number of clusters=" + affinity_propagation_clustering.getNumberOfClusters());
        
        if(screen==stringletPanel){
        System.out.println(affinity_propagation_clustering.Save_To_File("Affinity_Propagation.txt"));
        System.out.println("Affinity Propagation results was saved in " + " Affinity_Propagation.txt");
        }
    }

    public static void Apply_Random_Coordinates(Graph g, Component screen) {
        if (g.getNodeSize() > 1) {
            for (Iterator it = g.nodesIterator(); it.hasNext();) {
                Node node = (Node) it.next();
                node.setX(Math.random() * screen.getWidth());
                node.setY(Math.random() * screen.getHeight());
            }
        }
        //updateInfo();
        screen.repaint();
    }

    public static void Apply_Affinity_Propagation_Clustering(Graph g, Component screen) {
       // keep_current_colors=yes_no("Keep current node coloring?");
        if (g.getNodeSize() > 1) {
            try {
                int number_of_points = g.getNodeSize();
                int number_of_connections = g.getEdges().size();
               // if (affinity_propagation_report == null)
                {
                    Initialize_AffinityPropagation(g, screen);
                }

                affinity_propagation_report = affinity_propagation_clustering.getReport();
                cl = new LoadClusters(affinity_propagation_clustering.getReport());

                distribute_clusters(g,screen);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }
//------------------------------------------------------------------------------------------
        public static void Apply_Predefined_Clustering(Graph gg,Component screen) {

        if (gg.getNodeSize() > 1) {
            try {
                int number_of_points = gg.getNodeSize();
                int number_of_connections = gg.getEdges().size();
               
                    ArrayList Clusters = new ArrayList();
                         for (Iterator it = gg.nodesIterator(); it.hasNext();) {
                            Node node = (Node)it.next();
                            if(!Clusters.contains(node.getCLuster()))
                                Clusters.add(node.getCLuster());
                        }

                    System.out.println("Predefined clusters: "+Clusters.size());

                    StringBuffer str = new StringBuffer();
                    for (int i = 0; i < Clusters.size(); i++) {
                        str.append("----------------- Cluster: " + (i+1) + " -----------------\n");
                         for (Iterator it = gg.nodesIterator(); it.hasNext();) {
                                        Node node = (Node)it.next();
                                        if(Clusters.get(i)==(node.getCLuster()))
                                            str.append(node.getLabel() + "\n");
                                    }
                        System.out.println("~~~~~"+str.toString());
                     cl = new LoadClusters(str.toString());

                    distribute_clusters(gg,screen);
                    }

                


            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    //----------------------------------------------------------------------------------------------------------------------------
    public static void distribute_clusters(Graph g,Component screen) {

        if(screen==medusa.MedusaSimplerFrame.stringletPanel){
        MedusaSimplerFrame.setNodeColorSet(4);
        channel1MenuItem.setSelected(false);
        channel2MenuItem.setSelected(false);
        channel3MenuItem.setSelected(false);
        jRadioButtonMenuItem1.setSelected(true);}
        if (g.getNodeSize() > 1) {
            try {

                int number_of_points = g.getNodeSize();
                int number_of_connections = g.getEdges().size();
                ArrayList centers = new ArrayList();
                System.out.println("Number of clusters:" + cl.number_of_clusters());
                ArrayList point_set = new ArrayList();

                ArrayList colorscheme   = new ArrayList();

                
                ColorFactory cc = new ColorFactory();
                colorscheme.add(Color.RED);
                colorscheme.add(Color.GREEN);
                colorscheme.add(Color.BLUE);
                colorscheme.add(Color.PINK);
                colorscheme.add(Color.LIGHT_GRAY);
                colorscheme.add(Color.ORANGE);
                colorscheme.add(Color.CYAN);
                colorscheme.add(Color.MAGENTA);

                for (int i = 0; i <= cl.number_of_clusters(); i++) {
                        Object object = new Integer(i);
                        Color3f color = cc.computeColor(object,1.0f);
                        int red=(int)(color.x*255);
                        int green=(int)(color.y*255);
                        int blue=(int)(color.z*255);
                        if(red<=0)red=0;if(red>=255)red=255;
                        if(green<=0)green=0;if(green>=255)green=255;
                        if(blue<=0)blue=0;if(blue>=255)blue=255;
                        Color c = new Color(red,green,blue);
                        colorscheme.add(c);
                    }
                

                //find the centers on a grid

                float number_of_centers_per_line = 0;
                if (number_of_points % 2 == 0) {
                    number_of_centers_per_line = spread_to_grid(cl.number_of_clusters() + 1);
                } else {
                    number_of_centers_per_line = spread_to_grid(cl.number_of_clusters());
                }
                float distance_between_points = number_of_centers_per_line;
                float temp_width = (Math.min(screen.getWidth() - 1, screen.getHeight() - 1)) * 0.9f;
                distance_between_points = temp_width / (number_of_centers_per_line - 1);
               // distance_between_points = distance_between_points;
                if (distance_between_points == 0) {
                    distance_between_points = 0.001f;
                }

                float start_x = 15;
                float start_y = 15;
                double coorz = 0;
                if (number_of_centers_per_line == 1) {
                    double coorx = 0;
                    double coory = 0;
                    Point3d point = new Point3d(coorx, coory, coorz);
                    centers.add(point);
                } else {
                    for (int y = 0; y < number_of_centers_per_line; y++) {
                        start_x = 15;
                        for (int x = 0; x < number_of_centers_per_line; x++) {
                            if (centers.size() < number_of_points) {
                                double coorx = start_x + x * distance_between_points;
                                double coory = start_y + y * distance_between_points;
                                Point3d point = new Point3d(coorx, coory, coorz);
                                centers.add(point);
                            }
                        }
                    }
                }


                //place the nodes that belong to a cluster around a circle
                if (cl.number_of_clusters() == 1) {
                    Apply_Circular_Coordinates(g, screen);
                    for (int j = 0; j < cl.list_with_clusters.get(0).number_of_nodes(); j++) {
                                medusa.graph.Node Node = g.getNode(cl.list_with_clusters.get(0).node_names.get(j));
                                Node.setClusteringColor(colorscheme.get(0));
                            }
                } else {
                    for (int i = 0; i < cl.number_of_clusters(); i++) {
                        double CurX, CurY, prosX, prosY;
                        point_set.clear();
                        Point3d p;
                        if (cl.list_with_clusters.get(i).number_of_nodes() >= 2) {
                            double R = (distance_between_points - 1) / 2 - 10, R2;
                            if (cl.list_with_clusters.get(i).number_of_nodes() <= 10 && R >= 40 && cl.number_of_clusters() <= 15) {
                                R = 40;
                            }

                            double Xc = centers.get(i).x + R / 2, Yc = centers.get(i).y + R / 2, Zc = 0;
                            double x = Xc, y = Yc + R, z = 0;
                            double Du = 0, angle_step;
                            double[][] ctrlpoints = new double[cl.list_with_clusters.get(i).number_of_nodes()][3];
                            angle_step = 360f / (cl.list_with_clusters.get(i).number_of_nodes() + 1);

                            /***************************************************/
                            for (int ii = 0; ii < cl.list_with_clusters.get(i).number_of_nodes(); ii++) {

                                //System.out.println("-------------"+Du);
                                x = Xc + R * (float) Math.cos(Math.toRadians(Du));
                                y = Yc + R * (float) Math.sin(Math.toRadians(Du));

                                z = 0;
                                ctrlpoints[ii][0] = x;
                                ctrlpoints[ii][1] = y;
                                ctrlpoints[ii][2] = z;
                                Du = Du + angle_step;

                                CurX = ctrlpoints[ii][0];
                                CurY = ctrlpoints[ii][1];
                                if (CurY <= 0) {
                                    CurY = 10;
                                }
                                if (CurY >= screen.getHeight()) {
                                    CurY = screen.getHeight() - 10;
                                }
                                if (CurX <= 0) {
                                    CurX = 10;
                                }
                                if (CurX >= screen.getWidth()) {
                                    CurX = screen.getWidth() - 10;
                                }
                                if (Math.random() >= 0.5f) {
                                    CurX += Math.random();
                                } else {
                                    CurX -= Math.random();
                                }
                                if (Math.random() >= 0.5f) {
                                    CurY += Math.random();
                                } else {
                                    CurY -= Math.random();
                                }

                                p = new Point3d(CurX, CurY, 0);
                                point_set.add(p);
                            }

                            for (int j = 0; j < cl.list_with_clusters.get(i).number_of_nodes(); j++) {
                                medusa.graph.Node Node = g.getNode(cl.list_with_clusters.get(i).node_names.get(j));
                                Node.setX(point_set.get(j).x);
                                Node.setY(point_set.get(j).y);
                                Node.setClusteringColor(colorscheme.get(i));

                            }
                        } else
                        if (cl.list_with_clusters.get(i).number_of_nodes() > 0){
                            //System.out.println("~~~~~~~"+cl.list_with_clusters.size()+"\t"+colorscheme.size()+"~~~~~~~~~~~~~~");

                            medusa.graph.Node Node = g.getNode(cl.list_with_clusters.get(i).node_names.get(0));
                            Node.setX(centers.get(i).x);
                            Node.setY(centers.get(i).y);
                            Node.setClusteringColor(colorscheme.get(i));
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }


    }

//-------------------------------------------------------------------------------------------------------------------------
}

 

Ads help maintain this website.