package vismon.plot;

import vismon.data.Indicator;
import vismon.data.Scenario;
import vismon.data.Session;
import vismon.gui.OptionsPanel;
import vismon.gui.TradeoffsPanel;
import vismon.util.Constants;
import vismon.util.Util;

import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;

public class StarGlyphIndicator extends JPanel {

    private final double outerRadiusProportion = 0.5;
    private final double angelDif = Math.PI/30;

    private int x;
    private int y;
    private int w;
    private int h;
    private int plotLength;
    private double stickLength;

    private int xCentre;
    private int yCentre;

    private Indicator indicator;

    private double min;
    private double max;

    public StarGlyphIndicator(Indicator indicator) {
        this.indicator = indicator;

        min = indicator.getMin();
        max = indicator.getMax();

        x = 0;
        y = 0;
    }

    @Override
    public void paint(Graphics g) {
        if (Session.getScenarios().size() == 0)
            return;

        w = this.getWidth();
        h = this.getHeight();

        plotLength = w;
        if (w > h)
            plotLength = h;

        drawSticks((Graphics2D) g);
        drawBorder((Graphics2D) g);
    }

    private void drawSticks(Graphics2D g) {
        int scenarioNum = Scenario.numOfVisibleScenarios;//Session.getScenarios().size();
        stickLength = outerRadiusProportion * plotLength;

        xCentre = x + (int) (0.5 * w);
        yCentre = y + (int) (0.5 * h);

        g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));

        int index = 0;
        for (int i = 0; i < Session.getScenarios().size(); ++i) {
            Scenario ithScenario = Session.getSortedScenarios(TradeoffsPanel.sortByIndicator).get(i);
            if (!ithScenario.isVisible())
                continue;

            double ownAngle = index * 2 * Math.PI / scenarioNum;

            double scenarioValue = ithScenario.getAverageOrMedianValue(indicator, OptionsPanel.contoursBasedOn);
            double proportion = (scenarioValue - min) / (max - min);
            int xStick = xCentre + (int) (proportion * stickLength * Math.cos(ownAngle));
            int yStick = yCentre + (int) (proportion * stickLength * Math.sin(ownAngle));
            g.setColor(ithScenario.getColor());
            g.drawLine(xCentre, yCentre, xStick, yStick);
            ++index;
        }
    }

    private void drawBorder(Graphics2D g) {
        if (TradeoffsPanel.sortByIndicator == null)
            return;

        if (indicator.equals(TradeoffsPanel.sortByIndicator)) {
            g.setColor(Constants.MAIN_COLOR);
            g.setStroke(new BasicStroke(2.0f));
            g.drawRect(x+(int) (0.5*(w-plotLength)), y+(int) (0.5*(h-plotLength)), plotLength, plotLength);
            g.setStroke(new BasicStroke(1.0f));
        }
    }

    public void showToolTip(int xMouse, int yMouse) {
        int stickNum = Scenario.numOfVisibleScenarios;//Session.getScenarios().size();
        double distanceToCentre = Math.sqrt((xMouse-xCentre)*(xMouse-xCentre) +
                                            (yMouse-yCentre)*(yMouse-yCentre));
        double mouseAngle = Util.calculateAngle(xMouse, yMouse, xCentre, yCentre);

        String toolTipText = "";
        int index = 0;
        for (int i = 0; i < Session.getScenarios().size(); ++i) {
            Scenario ithScenario = Session.getSortedScenarios(TradeoffsPanel.sortByIndicator).get(i);
            if (!ithScenario.isVisible())
                continue;

            double ownAngle = index * 2 * Math.PI / stickNum;

            if (distanceToCentre > stickLength)
                break;

            if (ownAngle - angelDif <= mouseAngle && mouseAngle <= ownAngle + angelDif) {
                toolTipText += ithScenario.getName() + ": " + Util.format(ithScenario.getAverageValue(indicator), 2);
                break;
            }
            ++index;
        }

        setToolTipText(toolTipText);
    }

    /*private double getAngle(Scenario scenario) {
        int scenarioNum = Session.getScenarios().size();
        int scenarioRank = Session.getScenarioRank(scenario);
        double ownAngle = scenarioRank * 2*Math.PI / scenarioNum;

        return ownAngle;
    }*/

}
