package ru.yandex.webmaster3.core.statistic;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.BitSet;

import javax.imageio.ImageIO;

import com.google.common.math.IntMath;

/**
 * @author aherman
 */
public class HostGraphUtils {
    private static final int WIDTH_BITS = 8; // 256
    private static final int HEIGHT_BITS = 7; // 128
    private static final int RECT_SIZE = 4;

    private static final Color EMPTY = Color.white;
    private static final Color SMALL = new Color(0xC04D3B);
//    private static final Color MEDIUM = new Color(0x687EAB);
    private static final Color MEDIUM = new Color(0xAA5FC7);
    private static final Color BIG = new Color(0x6BAA3F);

    public static void writeToImage(ApproximateHostCounter hostCounter, OutputStream os) throws IOException {
        writeToImage(hostCounter.getBits(), hostCounter.getBitSet(), os);
    }

    public static void writeToImage(int bits, BitSet bitSet, OutputStream os) throws IOException {
        int width = IntMath.pow(2, WIDTH_BITS) * RECT_SIZE;
        int height = IntMath.pow(2, HEIGHT_BITS) * RECT_SIZE;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        graphics.setColor(Color.white);
        graphics.fillRect(0, 0, width, height);

        int groupBits = bits - WIDTH_BITS - HEIGHT_BITS;
        int groupPoints = IntMath.pow(2, groupBits);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int count = 0;
                for (int i = 0; i < groupPoints; i++) {
                    int id = (((x << HEIGHT_BITS) + y) << groupBits) + i;
                    if (bitSet.get(id)) {
                        count++;
                    }
                }
                graphics.setColor(toColor(count, groupPoints));
                graphics.fillRect(x * RECT_SIZE, y * RECT_SIZE, RECT_SIZE, RECT_SIZE);
            }
        }
        ImageIO.write(image, "PNG", os);
    }

    private static Color toColor(int count, int max) {
        if (count < 1) {
            return EMPTY;
        }
        if (count == max) {
            return BIG;
        }
        if (count < max / 2) {
            return SMALL;
        }
        return MEDIUM;
    }
}
