/*
 *  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.
 *  under the License.
 */

package org.apache.commons.imaging.formats.xbm;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import org.apache.commons.imaging.ImageFormat;
import org.apache.commons.imaging.ImageInfo;
import org.apache.commons.imaging.ImageParser;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.apache.commons.imaging.common.BasicCParser;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.bytesource.ByteSource;

public class XbmImageParser extends ImageParser
{
    public XbmImageParser()
    {
    }

    @Override
    public String getName()
    {
        return "Xbm-Custom";
    }

    @Override
    public String getDefaultExtension()
    {
        return DEFAULT_EXTENSION;
    }
    private static final String DEFAULT_EXTENSION = ".xbm";
    private static final String ACCEPTED_EXTENSIONS[] =
    {
        ".xbm",
    };

    @Override
    protected String[] getAcceptedExtensions()
    {
        return ACCEPTED_EXTENSIONS;
    }

    @Override
    protected ImageFormat[] getAcceptedTypes()
    {
        return new ImageFormat[]
        {
            ImageFormat.IMAGE_FORMAT_XBM, //
        };
    }

    @Override
    public boolean embedICCProfile(File src, File dst, byte profile[])
    {
        return false;
    }

    @Override
    public IImageMetadata getMetadata(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    @Override
    public ImageInfo getImageInfo(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        XbmHeader xbmHeader = readXbmHeader(byteSource);
        return new ImageInfo("XBM", 1,
                new ArrayList<String>(), ImageFormat.IMAGE_FORMAT_XBM,
                "X BitMap",
                xbmHeader.height, "image/x-xbitmap", 1,
                0, 0, 0, 0,
                xbmHeader.width, false, false, false,
                ImageInfo.COLOR_TYPE_BW,
                ImageInfo.COMPRESSION_ALGORITHM_NONE);
    }

    @Override
    public Dimension getImageSize(ByteSource byteSource,
            Map params)
            throws ImageReadException, IOException
    {
        XbmHeader xbmHeader = readXbmHeader(byteSource);
        return new Dimension(xbmHeader.width, xbmHeader.height);
    }

    @Override
    public byte[] getICCProfileBytes(ByteSource byteSource,
            Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    private static class XbmHeader
    {
        int width;
        int height;
        int xHot = -1;
        int yHot = -1;

        public XbmHeader(int width, int height, int xHot, int yHot)
        {
            this.width = width;
            this.height = height;
            this.xHot = xHot;
            this.yHot = yHot;
        }

        public void dump(PrintWriter pw)
        {
            pw.println("XbmHeader");
            pw.println("Width: " + width);
            pw.println("Height: " + height);
            if (xHot != -1 && yHot != -1)
            {
                pw.println("X hot: " + xHot);
                pw.println("Y hot: " + yHot);
            }
        }
    }

    private static class XbmParseResult
    {
        XbmHeader xbmHeader;
        BasicCParser cParser;
    }

    private XbmHeader readXbmHeader(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        XbmParseResult result = parseXbmHeader(byteSource);
        return result.xbmHeader;
    }

    private XbmParseResult parseXbmHeader(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        InputStream is = null;
        try
        {
            is = byteSource.getInputStream();
            Map<String, String> defines = new HashMap<String, String>();
            ByteArrayOutputStream preprocessedFile = BasicCParser.preprocess(
                    is, null, defines);
            int width = -1;
            int height = -1;
            int xHot = -1;
            int yHot = -1;
            for (Iterator<Map.Entry<String,String>> it = defines.entrySet().iterator(); it.hasNext();)
            {
                Map.Entry<String, String> entry = it.next();
                String name = entry.getKey();
                if (name.endsWith("_width"))
                    width = Integer.parseInt(entry.getValue());
                else if (name.endsWith("_height"))
                    height = Integer.parseInt(entry.getValue());
                else if (name.endsWith("_x_hot"))
                    xHot = Integer.parseInt(entry.getValue());
                else if (name.endsWith("_y_hot"))
                    yHot = Integer.parseInt(entry.getValue());
            }
            if (width == -1)
                throw new ImageReadException("width not found");
            if (height == -1)
                throw new ImageReadException("height not found");

            XbmParseResult xbmParseResult = new XbmParseResult();
            xbmParseResult.cParser = new BasicCParser(
                    new ByteArrayInputStream(preprocessedFile.toByteArray()));
            xbmParseResult.xbmHeader = new XbmHeader(width, height, xHot, yHot);
            return xbmParseResult;
        }
        finally
        {
            try
            {
                if (is != null)
                    is.close();
            }
            catch (IOException ignored)
            {
            }
        }
    }

    private BufferedImage readXbmImage(XbmHeader xbmHeader, BasicCParser cParser)
            throws ImageReadException, IOException
    {
        String token;
        token = cParser.nextToken();
        if (token == null || !token.equals("static"))
            throw new ImageReadException("Parsing XBM file failed, no 'static' token");
        token = cParser.nextToken();
        if (token == null)
            throw new ImageReadException("Parsing XBM file failed, no 'unsigned' " +
                    "or 'char' token");
        if (token.equals("unsigned"))
            token = cParser.nextToken();
        if (token == null || !token.equals("char"))
            throw new ImageReadException("Parsing XBM file failed, no 'char' token");
        String name = cParser.nextToken();
        if (name == null)
            throw new ImageReadException("Parsing XBM file failed, no variable name");
        if (name.charAt(0) != '_' && !Character.isLetter(name.charAt(0)))
            throw new ImageReadException("Parsing XBM file failed, variable name " +
                    "doesn't start with letter or underscore");
        for (int i = 0; i < name.length(); i++)
        {
            char c = name.charAt(i);
            if (!Character.isLetterOrDigit(c) && c != '_')
                throw new ImageReadException("Parsing XBM file failed, variable name " +
                        "contains non-letter non-digit non-underscore");
        }
        token = cParser.nextToken();
        if (token == null || !token.equals("["))
            throw new ImageReadException("Parsing XBM file failed, no '[' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("]"))
            throw new ImageReadException("Parsing XBM file failed, no ']' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("="))
            throw new ImageReadException("Parsing XBM file failed, no '=' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("{"))
            throw new ImageReadException("Parsing XBM file failed, no '{' token");

        int rowLength = (xbmHeader.width + 7) / 8;
        byte[] imageData = new byte[rowLength * xbmHeader.height];
        for (int i = 0; i < imageData.length; i++)
        {
            token = cParser.nextToken();
            if (token == null || !token.startsWith("0x"))
                throw new ImageReadException("Parsing XBM file failed, " +
                        "hex value missing");
            if (token.length() > 4)
                throw new ImageReadException("Parsing XBM file failed, " +
                        "hex value too long");
            int value = Integer.parseInt(token.substring(2), 16);
            int flipped = 0;
            for (int j = 0; j < 8; j++)
            {
                if ((value & (1 << j)) != 0)
                    flipped |= (0x80 >>> j);
            }
            imageData[i] = (byte) flipped;

            token = cParser.nextToken();
            if (token == null)
                throw new ImageReadException("Parsing XBM file failed, " +
                        "premature end of file");
            if (!token.equals(",") && (i < (imageData.length - 1) || !token.equals("}")))
                throw new ImageReadException("Parsing XBM file failed, " +
                        "punctuation error");
        }

        int[] palette = {0xffffff, 0x000000};
        ColorModel colorModel = new IndexColorModel(1, 2,
                palette, 0, false, -1, DataBuffer.TYPE_BYTE);
        DataBufferByte dataBuffer = new DataBufferByte(imageData, imageData.length);
        WritableRaster raster = WritableRaster.createPackedRaster(dataBuffer,
                xbmHeader.width, xbmHeader.height, 1, null);
        BufferedImage image = new BufferedImage(colorModel, raster,
                colorModel.isAlphaPremultiplied(), new Properties());
        return image;
    }

    @Override
    public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
            throws ImageReadException, IOException
    {
        readXbmHeader(byteSource).dump(pw);
        return true;
    }

    @Override
    public final BufferedImage getBufferedImage(ByteSource byteSource,
            Map params) throws ImageReadException, IOException
    {
        XbmParseResult result = parseXbmHeader(byteSource);
        return readXbmImage(result.xbmHeader, result.cParser);
    }

    private String randomName()
    {
        UUID uuid = UUID.randomUUID();
        StringBuilder stringBuilder = new StringBuilder("a");
        long bits = uuid.getMostSignificantBits();
        // Long.toHexString() breaks for very big numbers
        for (int i = 64 - 8; i >= 0; i -= 8)
            stringBuilder.append(Integer.toHexString((int)((bits >> i) & 0xff)));
        bits = uuid.getLeastSignificantBits();
        for (int i = 64 - 8; i >= 0; i -= 8)
            stringBuilder.append(Integer.toHexString((int)((bits >> i) & 0xff)));
        return stringBuilder.toString();
    }

    private String toPrettyHex(int value)
    {
        String s = Integer.toHexString(0xff & value);
        if (s.length() == 2)
            return "0x" + s;
        return "0x0" + s;
    }

    @Override
    public void writeImage(BufferedImage src, OutputStream os, Map params)
            throws ImageWriteException, IOException
    {
        // make copy of params; we'll clear keys as we consume them.
        params = (params == null) ? new HashMap() : new HashMap(params);

        // clear format key.
        if (params.containsKey(PARAM_KEY_FORMAT))
            params.remove(PARAM_KEY_FORMAT);

        if (params.size() > 0)
        {
            Object firstKey = params.keySet().iterator().next();
            throw new ImageWriteException("Unknown parameter: " + firstKey);
        }

        String name = randomName();

        os.write(("#define " + name + "_width " + src.getWidth() + "\n").getBytes("US-ASCII"));
        os.write(("#define " + name + "_height " + src.getHeight() + "\n").getBytes("US-ASCII"));
        os.write(("static unsigned char " + name + "_bits[] = {").getBytes("US-ASCII"));

        int bitcache = 0;
        int bits_in_cache = 0;
        String separator = "\n  ";
        int written = 0;
        for (int y = 0; y < src.getHeight(); y++)
        {
            for (int x = 0; x < src.getWidth(); x++)
            {
                int argb = src.getRGB(x, y);
                int red = 0xff & (argb >> 16);
                int green = 0xff & (argb >> 8);
                int blue = 0xff & (argb >> 0);
                int sample = (red + green + blue) / 3;
                if (sample > 127)
                    sample = 0;
                else
                    sample = 1;
                bitcache |= (sample << bits_in_cache);
                ++bits_in_cache;
                if (bits_in_cache == 8)
                {
                    os.write(separator.getBytes("US-ASCII"));
                    separator = ",";
                    if (written == 12)
                    {
                        os.write("\n  ".getBytes("US-ASCII"));
                        written = 0;
                    }
                    os.write(toPrettyHex(bitcache).getBytes("US-ASCII"));
                    bitcache = 0;
                    bits_in_cache = 0;
                    ++written;
                }
            }
            if (bits_in_cache != 0)
            {
                os.write(separator.getBytes("US-ASCII"));
                separator = ",";
                if (written == 12)
                {
                    os.write("\n  ".getBytes("US-ASCII"));
                    written = 0;
                }
                os.write(toPrettyHex(bitcache).getBytes("US-ASCII"));
                bitcache = 0;
                bits_in_cache = 0;
                ++written;
            }
        }

        os.write("\n};\n".getBytes("US-ASCII"));
    }

    /**
     * Extracts embedded XML metadata as XML string.
     * <p>
     *
     * @param byteSource
     *            File containing image data.
     * @param params
     *            Map of optional parameters, defined in SanselanConstants.
     * @return Xmp Xml as String, if present.  Otherwise, returns null.
     */
    @Override
    public String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        return null;
    }
}
