package _VisualDVM.ProjectData.SapforData.Functions.UI.Graph;
import Common.Utils.Pair;

import java.util.LinkedHashMap;
import java.util.Vector;
public class FunctionsGraphUIGreed extends FunctionsGraphUI {
    //веса вершин.
    protected LinkedHashMap<String, Integer> weights = new LinkedHashMap<>();
    //группы вершин по весам.в порядке убывания весов.
    protected LinkedHashMap<Integer, Vector<String>> groups = new LinkedHashMap<>();
    public FunctionsGraphUIGreed(GraphInfo graph_in) {
        super(graph_in);
    }
    @Override
    public void SetCoordinates() {
        //получить веса вершин.
        for (String name : graph.vertexMap.keySet()) {
            Vector<String> edges = graph.vertexMap.get(name);
            //как минимум, вес вершины - это все исходящие из нее ребра.
            if (!weights.containsKey(name)) weights.put(name, edges.size());
            else weights.replace(name, weights.get(name) + edges.size());
            for (String dst : edges) {
                //есть ребро, значит уже вес 1
                if (!weights.containsKey(dst)) weights.put(dst, 1);
                else weights.replace(dst, weights.get(dst) + 1);
            }
        }
        //сортировка по весу вершин.
        //1 определить максимальный вес.
        int max = 0;
        for (String name : weights.keySet())
            if (weights.get(name) > max) max = weights.get(name);
        for (int i = max; i >= 0; --i) {
            Vector<String> current_group = new Vector<>();
            for (String name : weights.keySet()) {
                if (weights.get(name) == i) current_group.add(name);
            }
            if (current_group.size() > 0) {
                groups.put(i, current_group);
            }
        }
        //linked hash map -  сохраняет порядок. поэтому они уже по убыванию.
        //теперь координаты. берем самую тыжелую группу, правильный многоугольник по центру
        //поток следующая, вокруг первого, и т д.
        int R = 150;
        int i = 0;
        double x_offet = 0;
        double y_ofset = 0;
        double rot = 0.0; //чтобы не было линеечки с каждой группой вращаем многоугольники.
        for (int w : groups.keySet()) {
            //первая вершина - особый случай. если она одна - ее в центр и надо
            if ((i == 0) && (groups.get(w).size() == 1)) {
                graph.vertexCoordinates.put(groups.get(w).get(0), new Pair<>(0.0, 0.0));
            } else {
                double phi0 = rot;
                double phi = 2 * Math.PI / groups.get(w).size();
                for (String name : groups.get(w)) {
                    double x = R * Math.cos(phi0);
                    double y = R * Math.sin(phi0);
                    if (x < x_offet) x_offet = x;
                    if (y < y_ofset) y_ofset = y;
                    //todo добавить в рассчет прямоугольник и самой вершины.
                    graph.vertexCoordinates.put(name, new Pair<>(x, y));
                    phi0 += phi;
                }
                R += 100;
            }
            ++i;
            rot += 10;
            if (rot > 360.0) rot = 0.0;
        }
        x_offet *= -1;
        y_ofset *= -1;
        //теперь надо применить смещение. смещение. чтобы не было отрицательных координат.
        for (String name : graph.vertexCoordinates.keySet()) {
            Pair<Double, Double> old = graph.vertexCoordinates.get(name);
            graph.vertexCoordinates.replace(name, new Pair<>(old.getKey() + x_offet + 50, old.getValue() + y_ofset + 50));
        }
    }
}
