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.awt.geom.PathIterator;
import java.util.HashMap;
import java.util.Map;

public class StarGlyphScenario 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 Scenario scenario;

    private Map<Indicator, Double> scenarioAngles;

    public StarGlyphScenario(Scenario scenario) {
        this.scenario = scenario;

        scenarioAngles = new HashMap<Indicator, Double>();

        x = 0;
        y = 0;
    }

    @Override
    public void paint(Graphics g) {
        if (!scenario.isVisible())
            return;

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

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

        drawSticks((Graphics2D) g);
    }

    private void drawSticks(Graphics2D g) {
        int indicatorNum = Indicator.numOfVisibleIndicators;
        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.getIndicatorNum(); ++i) {
            Indicator ithIndicator = Session.getIndicator(i);
            if (!ithIndicator.isVisible())
                continue;

            double min = ithIndicator.getMin();
            double max = ithIndicator.getMax();

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

            if (TradeoffsPanel.sortByIndicator != null && ithIndicator.equals(TradeoffsPanel.sortByIndicator)) {
                double arrowHeadRadius = 0.2 * stickLength;
                double angle1 = ownAngle - Math.PI/indicatorNum;
                double angle2 = ownAngle + Math.PI/indicatorNum;
                int xArrowHead1 = xCentre + (int) (arrowHeadRadius * Math.cos(angle1));
                int yArrowHead1 = yCentre + (int) (arrowHeadRadius * Math.sin(angle1));
                int xArrowHead2 = xCentre + (int) (arrowHeadRadius * Math.cos(angle2));
                int yArrowHead2 = yCentre + (int) (arrowHeadRadius * Math.sin(angle2));
                int xArrowTail1 = xArrowHead1 + (int) ((stickLength-arrowHeadRadius) * Math.cos(ownAngle));
                int yArrowTail1 = yArrowHead1 + (int) ((stickLength-arrowHeadRadius) * Math.sin(ownAngle));
                int xArrowTail2 = xArrowHead2 + (int) ((stickLength-arrowHeadRadius) * Math.cos(ownAngle));
                int yArrowTail2 = yArrowHead2 + (int) ((stickLength-arrowHeadRadius) * Math.sin(ownAngle));

                g.setColor(Constants.MAIN_COLOR);
                g.drawPolygon(new int[]{xCentre, xArrowHead1, xArrowTail1, xArrowTail2, xArrowHead2},
                              new int[]{yCentre, yArrowHead1, yArrowTail1, yArrowTail2, yArrowHead2},
                              5);

            }

            double scenarioValue = scenario.getAverageOrMedianValue(ithIndicator, OptionsPanel.contoursBasedOn);
            double proportion = (scenarioValue - min) / (max - min);
            int xStickCoord = xCentre + (int) (proportion * stickLength * Math.cos(ownAngle));
            int yStickCoord = yCentre + (int) (proportion * stickLength * Math.sin(ownAngle));
            g.setColor(scenario.getColor());
            g.drawLine(xCentre, yCentre, xStickCoord, yStickCoord);

            ++index;
        }
    }

    public void setScenario(Scenario scenario) {
        this.scenario = scenario;
    }

    public void showToolTip(int xMouse, int yMouse) {
        int stickNum = Indicator.numOfVisibleIndicators;
        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.getIndicatorNum(); ++i) {
            Indicator ithIndicator = Session.getIndicator(i);
            if (!ithIndicator.isVisible())
                continue;

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

            if (distanceToCentre > stickLength)
                break;

            if (ownAngle - angelDif <= mouseAngle && mouseAngle <= ownAngle + angelDif) {
                toolTipText += ithIndicator.getShortName();
                break;
            }

            ++index;
        }

        setToolTipText(toolTipText);
    }

}
