package org.sunflow.image.writers;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.sunflow.image.BitmapWriter;
import org.sunflow.image.Color;
import org.sunflow.image.ColorEncoder;

public class TGABitmapWriter implements BitmapWriter {
    private String filename;
    private int width, height;
    private byte[] data;

    public void configure(String option, String value) {
    }

    public void openFile(String filename) throws IOException {
        this.filename = filename;
    }

    public void writeHeader(int width, int height, int tileSize) throws IOException, UnsupportedOperationException {
        this.width = width;
        this.height = height;
        data = new byte[width * height * 4]; // RGBA8
    }

    public void writeTile(int x, int y, int w, int h, Color[] color, float[] alpha) throws IOException {
        color = ColorEncoder.unlinearize(color); // gamma correction
        byte[] tileData = ColorEncoder.quantizeRGBA8(color, alpha);
        for (int j = 0, index = 0; j < h; j++) {
            int imageIndex = 4 * (x + (height - 1 - (y + j)) * width);
            for (int i = 0; i < w; i++, index += 4, imageIndex += 4) {
                // swap bytes around so buffer is in native BGRA order
                data[imageIndex + 0] = tileData[index + 2];
                data[imageIndex + 1] = tileData[index + 1];
                data[imageIndex + 2] = tileData[index + 0];
                data[imageIndex + 3] = tileData[index + 3];
            }
        }
    }

    public void closeFile() throws IOException {
        // actually write the file from here
        OutputStream f = new BufferedOutputStream(new FileOutputStream(filename));
        // no id, no colormap, uncompressed 32bpp RGBA
        byte[] tgaHeader = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        f.write(tgaHeader);
        // then the size info
        f.write(width & 0xFF);
        f.write((width >> 8) & 0xFF);
        f.write(height & 0xFF);
        f.write((height >> 8) & 0xFF);
        // bitsperpixel and filler
        f.write(32);
        f.write(0);
        f.write(data); // write image data bytes (already in BGRA order)
        f.close();
    }
}