package name.abuchen.portfolio.ui.views.taxonomy;

import java.util.List;

import name.abuchen.portfolio.ui.util.Colors;

import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;

/* package */class TaxonomyNodeRenderer
{
    private final class Segment
    {
        private Color primary;
        private Color brighter;
        private Color darker;

        public Segment(String color)
        {
            RGB rgb = Colors.toRGB(color);
            createColors(rgb, rgb.getHSB());
        }

        public Segment(String color, int shade)
        {
            float[] hsb = Colors.toRGB(color).getHSB();
            hsb[2] = Math.max(0f, hsb[2] - (0.07f * (shade % 6)));
            RGB rgb = new RGB(hsb[0], hsb[1], hsb[2]);

            createColors(rgb, hsb);
        }

        private void createColors(RGB rgb, float[] hsb)
        {
            primary = resources.createColor(rgb);
            brighter = resources.createColor(new RGB(hsb[0], hsb[1], Math.min(1.0f, hsb[2] + 0.05f)));
            darker = resources.createColor(new RGB(hsb[0], hsb[1], Math.max(0f, hsb[2] - 0.05f)));
        }
    }

    private LocalResourceManager resources;

    public TaxonomyNodeRenderer(LocalResourceManager resources)
    {
        this.resources = resources;
    }

    public void drawRectangle(TaxonomyNode rootItem, TaxonomyNode item, GC gc, Rectangle r)
    {
        Segment segment = getSegment(rootItem, item);

        gc.setBackground(segment.primary);
        gc.fillRectangle(r.x, r.y, r.width, r.height);

        gc.setForeground(segment.darker);
        gc.drawLine(r.x, r.y + r.height - 1, r.x + r.width - 1, r.y + r.height - 1);
        gc.drawLine(r.x + r.width - 1, r.y, r.x + r.width - 1, r.y + r.height - 1);

        gc.setForeground(segment.brighter);
        gc.drawLine(r.x, r.y, r.x + r.width, r.y);
        gc.drawLine(r.x, r.y, r.x, r.y + r.height);
    }

    public Color getColorFor(TaxonomyNode node)
    {
        return getSegment(null, node).primary;
    }

    private Segment getSegment(TaxonomyNode rootItem, TaxonomyNode item)
    {
        if (rootItem == null || item.isRoot() || rootItem.equals(item))
            return new Segment(item.getColor());

        List<TaxonomyNode> path = item.getPath();
        int index = path.indexOf(rootItem);

        if (index < 0) // root not found!
            return new Segment(item.getColor());

        if (path.size() <= index + 2) // no grandchildren
            return new Segment(item.getColor());

        TaxonomyNode reference = path.get(index + 1);
        TaxonomyNode grandchild = path.get(index + 2);
        return new Segment(reference.getColor(), reference.getChildren().indexOf(grandchild));
    }

}

@@ -651,292 +651,8 @@
  %7D%0A%0A
-        public Segment(String color, int shade)%0A        %7B%0A            float%5B%5D hsb = Colors.toRGB(color).getHSB();%0A            hsb%5B2%5D = Math.max(0f, hsb%5B2%5D - (0.07f * (shade %25 6)));%0A            RGB rgb = new RGB(hsb%5B0%5D, hsb%5B1%5D, hsb%5B2%5D);%0A%0A            createColors(rgb, hsb);%0A        %7D%0A%0A
     
@@ -2293,30 +2293,10 @@
 x + 
-2) // no grandchildren
+1)
 %0A   
@@ -2400,63 +2400,8 @@
 1);%0A
-        TaxonomyNode grandchild = path.get(index + 2);%0A
     
@@ -2447,53 +2447,8 @@
 or()
-, reference.getChildren().indexOf(grandchild)
 );%0A 

Use identical colors for tree map tiles (used to use different shades)