/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.tools.chartlib;

import com.android.annotations.NonNull;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Arc2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.swing.tree.TreeNode;

/**
 * Component which renders a
 * <a href="https://en.wikipedia.org/wiki/Pie_chart#Ring_chart_.2F_Sunburst_chart_.2F_Multilevel_pie_chart">
 * sunburst chart</a> that can be unrolled by setting its angle.
 */
public final class SunburstComponent extends AnimatedComponent {

    private static final Color[] COLORS = {
            new Color(0x6baed6),
            new Color(0xc6dbef),
            new Color(0xfd8d3c),
            new Color(0xfdd0a2),
            new Color(0x74c476),
            new Color(0xc7e9c0),
            new Color(0x9e9ac8),
            new Color(0xdadaeb),
            new Color(0x969696),
            new Color(0xd9d9d9),
    };

    private static final Color[] HIGHLIGHTS = {
            new Color(0x3182bd),
            new Color(0x9ecae1),
            new Color(0xe6550d),
            new Color(0xfdae6b),
            new Color(0x31a354),
            new Color(0xa1d99b),
            new Color(0x756bb1),
            new Color(0xbcbddc),
            new Color(0x636363),
            new Color(0xbdbdbd),
    };

    private ValuedTreeNode mData;

    private Slice mSlice;

    private float mGap;

    private float mStart;

    private float mFixed;

    private float mAngle;

    private float mCurrentAngle;

    private float mSeparator;

    private boolean mAutoSize;

    private float mSliceWidth;

    private boolean myUseCount;

    private int mySelectionLevel;

    private int myZoomLevel;

    private Slice mySelection;

    private Slice myZoom;

    private boolean myLockSelection;

    private final List<SliceSelectionListener> mListeners;

    // Calculated values
    private float mX;

    private float mY;

    private float mMaxDepth;

    private float mMaxSide;

    private float mCenterX;

    private float mCenterY;

    private float mDelta;

    private Point2D.Float mDirection;

    private Map<Color, Path2D.Float> mPaths;

    public SunburstComponent(@NonNull ValuedTreeNode data) {
        super(30);
        mData = data;
        mSlice = new Slice(0.0f);
        mSliceWidth = 50;
        mGap = 50;
        mX = -1;
        mY = -1;
        mCurrentAngle = mAngle = 360.0f;
        mDelta = 0.0f;
        mFixed = 60.0f;
        mStart = 180.0f;
        mSeparator = 1.0f;
        mySelectionLevel = -1;
        myLockSelection = false;
        mPaths = new HashMap<Color, Path2D.Float>();
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    myZoom = mySelection;
                    myZoomLevel = mySelectionLevel;
                    myLockSelection = false;
                } else {
                    myLockSelection = !myLockSelection && mySelection != null;
                }
            }
        });
        mListeners = new LinkedList<SliceSelectionListener>();
    }

    @Override
    protected void draw(Graphics2D g) {
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        Dimension dim = getSize();

        g.setColor(getBackground());
        g.fillRect(0, 0, dim.width, dim.height);

        mPaths.clear();
        drawSlice(g, mSlice, 0.0f, 0.0f, 1.0f);
        for (Map.Entry<Color, Path2D.Float> entry : mPaths.entrySet()) {
            g.setColor(entry.getKey());
            g.fill(entry.getValue());
        }
    }

    @Override
    protected void updateData() {

        Dimension dim = getSize();
        mX = dim.width * 0.5f;
        mY = dim.height * 0.5f;

        updateArea();
        updateStructure(mSlice, mData, false);

        mCurrentAngle = Math.abs(mCurrentAngle - mAngle) < 0.1f ? mAngle
                : lerp(mCurrentAngle, mAngle, 0.999f);
        if (mAutoSize) {
            float full = Math.min(mMaxDepth, mMaxSide) - mGap - 20;
            float none = mMaxDepth * 2 - mGap - 20;
            float factor = mCurrentAngle / 360.0f;
            float depth = full * factor + none * (1 - factor);
            mFixed = lerp(mFixed, (float) ((mMaxSide - 20) / Math.PI), 0.999f);
            float width = depth / getMaxDepth(mSlice);
            mSliceWidth = lerp(mSliceWidth, width, 0.999f);
        }

        // mDelta is the extra radius needed to keep the same length at the fixes radius
        // (mDelta + mFixed * Rad(mCurrentAngle) == 2PI * mFixed =>
        // mDelta + mFixed == 2PI * mFixed / Rad(mCurrentAngle) =>
        mDelta = 360.0f * mFixed / mCurrentAngle - mFixed;
        mDirection = new Point2D.Float((float) Math.cos(mStart * Math.PI / 180.0f),
                -(float) Math.sin(mStart * Math.PI / 180.0f));

        mCenterX = mX + (mDelta + mMaxDepth * (360.0f - mCurrentAngle) / 360.0f) * mDirection.x;
        mCenterY = mY + (mDelta + mMaxDepth * (360.0f - mCurrentAngle) / 360.0f) * mDirection.y;

        updateSelection();
        updateSlice(mSlice, 0, myZoom == null);
    }

    private void updateSelection() {
        Point mouse = getMousePosition();
        if (!myLockSelection) {
            boolean selection = false;
            if (mouse != null) {
                float value = 0;
                float depth = 0;
                if (mCurrentAngle > 0) {
                    float distance = (float) mouse.distance(mCenterX, mCenterY);
                    depth = (distance - mGap - mDelta) / mSliceWidth;
                    float angle = -(float) Math
                            .toDegrees(Math.atan2(mouse.y - mCenterY, mouse.x - mCenterX));
                    angle = (angle - mStart - 180.0f + mCurrentAngle * 0.5f) % 360.0f;
                    angle = angle < 0 ? angle + 360.0f : angle;
                    value = angle / mCurrentAngle;
                } else {
                    float length = (float) (Math.PI * 2.0f * mFixed);
                    // Do the dot product of the vector to the mouse with the unit vector to project to:
                    depth = (mouse.x - mX) * mDirection.x + (mouse.y - mY) * mDirection.y - (mMaxDepth - mGap);
                    value = (mouse.x - mX) * mDirection.y + (mouse.y - mY) * -mDirection.x;
                    // Normalize:
                    depth = -depth / mSliceWidth;
                    value = -value / length + 0.5f;
                }
                selection = updateSelectedSlice(mSlice, depth, value, 0);
            }
            if (!selection) {
                mySelectionLevel = -1;
                if (mySelection != null) {
                    mySelection = null;
                    fireSliceSelected(new SliceSelectionEvent(null));
                }
            }
        } else {
            if (mySelection != null && mySelection.node == null) {
                myLockSelection = false;
                mySelectionLevel = -1;
                mySelection = null;
                fireSliceSelected(new SliceSelectionEvent(null));
            }
        }
        if (myZoom != null && myZoom.node == null) {
            resetZoom();
        }
    }

    public void resetZoom() {
        myZoom = null;
        myZoomLevel = -1;
    }

    private boolean updateSlice(Slice slice, int level, boolean zoom) {
        zoom = zoom || slice == myZoom;
        boolean children = false;
        for (int i = 0; i < slice.getChildrenCount(); i++) {
            Slice child = slice.getChild(i);
            children = updateSlice(child, level + 1, zoom) || children;
        }
        zoom = zoom || children;

        slice.selected = lerp(slice.selected, slice == mySelection ? 1.0f : 0.0f, 0.99f);
        slice.visible = lerp(slice.visible, zoom ? 1.0f : 0.0f, 0.99f);
        slice.zoom = lerp(slice.zoom,
                level < myZoomLevel ? (level == myZoomLevel - 1) ? 0.5f : 0.0f : 1.0f, 0.99f);

        return zoom;
    }

    private boolean updateSelectedSlice(Slice slice, float depth, float value, int level) {
        if (depth < 0.0f || value < 0.0f || value > 1.0f) {
            return false;
        } else if (depth < slice.getDepth()) {
            mySelectionLevel = level;
            if (mySelection != slice) {
                mySelection = slice;
                fireSliceSelected(new SliceSelectionEvent(slice.node));
            }
            return true;
        } else {
            depth -= slice.getDepth();
            float total = 0.0f;
            for (Slice child : slice.getChildren()) {
                total += child.getValue();
            }
            float current = 0.0f;
            for (int i = 0; i < slice.getChildrenCount(); i++) {
                Slice child = slice.getChild(i);
                float val = child.getValue() / total;
                if (value < current + val || i == slice.getChildrenCount() - 1) {
                    value = (value - current) / val;
                    return updateSelectedSlice(child, depth, value, level + 1);
                }
                current += val;

            }
        }
        return false;
    }

    private void fireSliceSelected(SliceSelectionEvent event) {
        for (SliceSelectionListener listener : mListeners) {
            listener.valueChanged(event);
        }
    }

    @Override
    protected void debugDraw(Graphics2D g2d) {
        addDebugInfo("Total slices: %d", mData.getCount());
        addDebugInfo("Paths %d", mPaths.size());
        g2d.setColor(Color.GREEN);
        drawArrow(g2d, mX, mY, mDirection.x, mDirection.y, mMaxDepth, Color.MAGENTA);
        drawArrow(g2d, mX, mY, mDirection.y, -mDirection.x, mMaxSide, Color.MAGENTA);
        if (mCurrentAngle == 0) {
            Path2D.Float fixed = new Path2D.Float();
            float length = (float) (Math.PI * 2.0f * mFixed) * 0.5f;
            fixed.moveTo(
                    mX + (mMaxDepth * (360.0f - mCurrentAngle) / 360.0f - mFixed) * mDirection.x
                            - mDirection.y * length,
                    mY + (mMaxDepth * (360.0f - mCurrentAngle) / 360.0f - mFixed) * mDirection.y
                            + mDirection.x * length);
            fixed.lineTo(
                    mX + (mMaxDepth * (360.0f - mCurrentAngle) / 360.0f - mFixed) * mDirection.x
                            + mDirection.y * length,
                    mY + (mMaxDepth * (360.0f - mCurrentAngle) / 360.0f - mFixed) * mDirection.y
                            - mDirection.x * length);

            g2d.draw(fixed);
        } else {
            drawMarker(g2d, mCenterX, mCenterY, Color.BLUE);
            Arc2D.Float fixed = new Arc2D.Float();
            fixed.setArcByCenter(mCenterX, mCenterY, mDelta + mFixed,
                    mStart + (360.0f - mCurrentAngle) * 0.5f, mCurrentAngle, Arc2D.OPEN);
            g2d.draw(fixed);
        }
    }

    private void updateArea() {
        float angle = (float) Math.toRadians(mStart);
        float a = (float) Math.cos(angle) * mY;
        float b = (float) Math.sin(angle) * mX;
        mMaxDepth = mX * mY / (float) Math.sqrt((a * a) + (b * b));
        a = (float) Math.cos(angle + Math.PI * 0.5) * mY;
        b = (float) Math.sin(angle + Math.PI * 0.5) * mX;
        mMaxSide = mX * mY / (float) Math.sqrt((a * a) + (b * b));
    }

    float getFraction(ValuedTreeNode node) {
        TreeNode parent = node.getParent();
        assert parent == null || parent instanceof ValuedTreeNode;
        if (myUseCount) {
            return parent == null ? 1.0f
                    : (float) node.getCount() / ((ValuedTreeNode) parent).getCount();
        } else {
            return parent == null ? 1.0f
                    : (float) node.getValue() / ((ValuedTreeNode) parent).getValue();
        }
    }

    static ValuedTreeNode getChildAt(ValuedTreeNode node, int i) {
        TreeNode child = node.getChildAt(i);
        assert child instanceof ValuedTreeNode;
        return (ValuedTreeNode) child;
    }

    private float getMaxDepth(Slice slice) {
        float depth = 0.0f;
        for (Slice child : slice.getChildren()) {
            depth = Math.max(depth, getMaxDepth(child));
        }
        return depth + slice.depth;
    }

    private boolean updateStructure(Slice slice, ValuedTreeNode node, boolean hasSiblings) {
        if (node == null) {
            slice.depth = lerp(slice.depth, hasSiblings ? slice.depth : 0.0f, 0.99f);
            slice.value = lerp(slice.value, hasSiblings ? 0.0f : slice.value, 0.99f);
        } else {
            slice.depth = lerp(slice.depth, node.getParent() == null ? 0.0f : 1.0f, 0.99f);
            slice.value = lerp(slice.value, getFraction(node), 0.99f);
        }
        slice.node = node;

        int last = -1;
        int slices = slice.getChildrenCount();
        int nodes = node == null ? 0 : node.getChildCount();
        for (int i = 0; i < slices; i++) {
            Slice childSlice = slice.getChild(i);
            ValuedTreeNode childNode = i < nodes ? getChildAt(node, i) : null;
            if (updateStructure(childSlice, childNode, nodes > 0)) {
                last = i;
            }
        }
        // Test neighbours with the same color:
        int c = slices > 0 ? slice.getChild(0).color
                : ((slice.color + (int) (Math.random() * COLORS.length - 1) + 1) % COLORS.length);
        for (int i = slices; i < nodes; i++) {
            ValuedTreeNode childNode = getChildAt(node, i);
            Slice childSlice = new Slice(slices > 0 ? 0.0f : getFraction(childNode));
            childSlice.color = c;
            childSlice.depth = slices > 0 ? 1.0f : 0.0f;
            slice.addChild(childSlice);
            if (updateStructure(childSlice, childNode, nodes > 0)) {
                last = i;
            }
        }

        if (last + 1 < slice.getChildrenCount()) {
            slice.clearSublist(last + 1, slice.getChildrenCount());
        }

        return node != null || (slice.depth > 0.00001f && slice.value > 0.00001f) || last >= 0;
    }

    Path2D.Float getPath(Color color) {
        Path2D.Float path = mPaths.get(color);
        if (path == null) {
            path = new Path2D.Float();
            mPaths.put(color, path);
        }
        return path;
    }

    private void drawSlice(Graphics2D g, Slice slice, float depth, float from, float to) {
        if (slice.getDepth() > 0.0f) { // Optimization for zero width slices
            Color c = COLORS[slice.color];
            float s = slice.selected;
            Color b = HIGHLIGHTS[slice.color];
            c = new Color((int) (b.getRed() * s + c.getRed() * (1 - s)),
                    (int) (b.getGreen() * s + c.getGreen() * (1 - s)),
                    (int) (b.getBlue() * s + c.getBlue() * (1 - s)));
            Path2D.Float path = getPath(c);
            if (mCurrentAngle == 0) {
                float length = (float) (Math.PI * 2.0f * mFixed);
                float delta = mGap + depth * mSliceWidth - mMaxDepth + mSeparator * 0.5f
                        + slice.getBorder() * mSliceWidth;
                float up = length * (0.5f - from) - mSeparator * 0.5f;
                float down = length * (0.5f - to) + mSeparator * 0.5f;
                float size = mSliceWidth * slice.getDepth() - mSeparator
                        - slice.getBorder() * mSliceWidth * 2.0f;

                float deltaX = mDirection.x * delta;
                float deltaY = mDirection.y * delta;
                float upX = mDirection.y * up;
                float upY = -mDirection.x * up;
                float downX = mDirection.y * down;
                float downY = -mDirection.x * down;
                float sizeX = mDirection.x * size;
                float sizeY = mDirection.y * size;

                if (up > down) {
                    path.moveTo(mX - deltaX + upX, mY - deltaY + upY);
                    path.lineTo(mX - deltaX + upX - sizeX, mY - deltaY + upY - sizeY);
                    path.lineTo(mX - deltaX + downX - sizeX, mY - deltaY + downY - sizeY);
                    path.lineTo(mX - deltaX + downX, mY - deltaY + downY);
                    path.closePath();
                }
            } else {
                float angle = (360.0f - mCurrentAngle) * 0.5f + mCurrentAngle * from + mStart;
                float arc = mCurrentAngle * (to - from);

                float radius = mSliceWidth * depth + mGap + mDelta;

                float outerLen = (radius + mSliceWidth * slice.getDepth()) * (float) Math.toRadians(
                        arc);
                if (outerLen < 1) {
                    path = getPath(Color.RED);
                }
                float outerRadius = radius + mSliceWidth * slice.getDepth() - mSeparator * 0.5f
                        - slice.getBorder() * mSliceWidth;
                float innerRadius = radius + mSeparator * 0.5f + slice.getBorder() * mSliceWidth;
                float outerAngle = (float) Math.toDegrees(Math.asin(mSeparator / outerRadius));
                if (outerAngle < arc && outerRadius > innerRadius) {
                    Arc2D.Float outer = new Arc2D.Float();
                    outer.setArcByCenter(mCenterX, mCenterY, outerRadius,
                            angle + outerAngle * 0.5f, arc - outerAngle, Arc2D.OPEN);
                    path.append(outer, false);

                    float innerAngle = (float) Math.toDegrees(Math.asin(mSeparator / innerRadius));
                    if (innerAngle < arc) {
                        Arc2D.Float inner = new Arc2D.Float();
                        inner.setArcByCenter(mCenterX, mCenterY, innerRadius,
                                angle + innerAngle * 0.5f + arc - innerAngle, -(arc - innerAngle),
                                Arc2D.OPEN);
                        path.append(inner, true);
                    } else {
                        float r = (float) (mSeparator * 0.5f / Math
                                .sin(Math.toRadians(arc * 0.5f)));
                        float dx = (float) (Math.cos(Math.toRadians(angle + arc * 0.5f)) * r);
                        float dy = (float) (Math.sin(Math.toRadians(angle + arc * 0.5f)) * r);
                        path.lineTo(mCenterX + dx, mCenterY - dy);
                    }
                    path.lineTo(outer.getStartPoint().getX(), outer.getStartPoint().getY());
                }
            }
        }

        float total = 0.0f;
        for (Slice child : slice.getChildren()) {
            total += child.getValue();
        }
        float value = 0.0f;
        for (Slice child : slice.getChildren()) {
            float childFrom = from + (value / total) * (to - from);
            float childTo = from + ((value + child.getValue()) / total) * (to - from);

            drawSlice(g, child, depth + slice.getDepth(), childFrom, childTo);

            value += child.getValue();
        }
    }

    public void setGap(float gap) {
        mGap = gap;
    }

    public void setSliceWidth(float sliceWidth) {
        mSliceWidth = sliceWidth;
    }

    public void setAngle(float angle) {
        mAngle = angle;
    }

    public void setStart(float start) {
        mStart = start;
        updateArea();
    }

    public void setFixed(int fixed) {
        mFixed = fixed;
    }

    public float getGap() {
        return mGap;
    }

    public float getSliceWidth() {
        return mSliceWidth;
    }

    public float getStart() {
        return mStart;
    }

    public float getFixed() {
        return mFixed;
    }

    public float getAngle() {
        return mAngle;
    }

    public float getSeparator() {
        return mSeparator;
    }

    public void setSeparator(float separator) {
        mSeparator = separator;
    }

    public void setData(ValuedTreeNode data) {
        mData = data;
    }

    public ValuedTreeNode getData() {
        return mData;
    }

    public void setAutoSize(boolean autoSize) {
        mAutoSize = autoSize;
    }

    public void setUseCount(boolean useCount) {
        myUseCount = useCount;
    }

    public void addSelectionListener(SliceSelectionListener listener) {
        mListeners.add(listener);
    }

    public void removeSelectionListener(SliceSelectionListener listener) {
        mListeners.remove(listener);
    }

    static class Slice {

        private ArrayList<Slice> children = new ArrayList<Slice>();

        Slice parent;

        float value;

        float depth;

        int color;

        float hover;

        float zoom;

        float selected;

        float visible;

        ValuedTreeNode node;

        public float getValue() {
            return value * visible;
        }

        public float getBorder() {
            return selected * depth * 0.05f;
        }

        public float getDepth() {
            return zoom * depth + getBorder() * 2.0f;
        }

        public Slice(float value) {
            this.value = value;
            this.depth = 1.0f;
            this.hover = 0.0f;
            this.selected = 0.0f;
            this.zoom = 1.0f;
            this.visible = 1.0f;
        }

        public int getChildrenCount() {
            return children.size();
        }

        public void addChild(Slice child) {
            children.add(child);
            child.parent = this;
        }

        public Slice getChild(int i) {
            return children.get(i);
        }

        public void clearSublist(int from, int to) {
            for (int i = from; i < to; i++) {
                children.get(i).parent = null;
            }
            children.subList(from, to).clear();
        }

        public ArrayList<Slice> getChildren() {
            return children;
        }
    }

    public static class SliceSelectionEvent {

        private final ValuedTreeNode mNode;

        public SliceSelectionEvent(ValuedTreeNode node) {
            mNode = node;
        }

        public ValuedTreeNode getNode() {
            return mNode;
        }
    }

    public interface SliceSelectionListener {
        void valueChanged(SliceSelectionEvent e);
    }
}
