/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.commons.imaging.formats.rgbe;

import java.io.IOException;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.BinaryConstants;
import org.apache.commons.imaging.common.BinaryFileFunctions;
import org.apache.commons.imaging.common.BinaryInputStream;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.ImageMetadata;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.util.Debug;

class RgbeInfo extends BinaryFileFunctions {
    private static final Pattern RESOLUTION_STRING = Pattern.compile( "-Y (\\d+) \\+X (\\d+)" );

    private final BinaryInputStream in;
    private ImageMetadata metadata;
    private int width = -1;
    private int height = -1;
    private static final byte[] TWO_TWO = new byte[]{ 0x2, 0x2 };

    RgbeInfo( ByteSource byteSource ) throws IOException {
        this.in = new BinaryInputStream( byteSource.getInputStream(), BinaryConstants.BYTE_ORDER_BIG_ENDIAN );
    }

    IImageMetadata getMetadata() throws IOException, ImageReadException {
        if ( null == metadata ) {
            readMetadata();
        }

        return metadata;
    }

    int getWidth() throws IOException, ImageReadException {
        if ( -1 == width ) {
            readDimensions();
        }

        return width;
    }

    int getHeight() throws IOException, ImageReadException {
        if ( -1 == height ) {
            readDimensions();
        }

        return height;
    }

    void close() {
        try {
            in.close();
        } catch( IOException e ) {
            Debug.debug( e );
        }
    }

    private void readDimensions() throws IOException, ImageReadException {
        getMetadata(); // Ensure we've read past this

        InfoHeaderReader reader = new InfoHeaderReader( in );
        String resolution = reader.readLine();
        Matcher matcher = RESOLUTION_STRING.matcher( resolution );

        if ( !matcher.matches() ) {
            throw new ImageReadException(
                "Invalid HDR resolution string. Only \"-Y N +X M\" is supported. Found \"" + resolution + "\"" );
        }

        height = Integer.parseInt( matcher.group( 1 ) );
        width = Integer.parseInt( matcher.group( 2 ) );
    }

    private void readMetadata() throws IOException, ImageReadException {
        in.readAndVerifyBytes( RgbeConstants.HEADER, "Not a valid HDR: Incorrect Header" );

        InfoHeaderReader reader = new InfoHeaderReader( in );

        if ( reader.readLine().length() != 0 ) {
            throw new ImageReadException( "Not a valid HDR: Incorrect Header" );
        }

        metadata = new ImageMetadata();

        String info = reader.readLine();

        while ( info.length() != 0 ) {
            int equals = info.indexOf( "=" );

            if ( equals > 0 ) {
                String variable = info.substring( 0, equals );
                String value = info.substring( equals + 1 );

                if ( "FORMAT".equals( value ) ) {
                    if ( !"32-bit_rle_rgbe".equals( value ) ) {
                        throw new ImageReadException(
                            "Only 32-bit_rle_rgbe images are supported, trying to read " + value );
                    }
                }

                metadata.add( variable, value );
            } else {
                metadata.add( "<command>", info );
            }

            info = reader.readLine();
        }
    }

    public float[][] getPixelData() throws IOException, ImageReadException {
        // Read into local variables to ensure that we have seeked into the file far enough
        int height = getHeight();
        int width = getWidth();

        if ( width >= 32768 ) {
            throw new ImageReadException( "Scan lines must be less than 32768 bytes long" );
        }

        byte[] scanLineBytes = convertShortToByteArray( width, BinaryConstants.BYTE_ORDER_BIG_ENDIAN );
        byte[] rgbe = new byte[width * 4];
        float[][] out = new float[3][width * height];

        for ( int i = 0; i < height; i++ ) {
            in.readAndVerifyBytes( TWO_TWO, "Scan line " + i + " expected to start with 0x2 0x2" );
            in.readAndVerifyBytes( scanLineBytes, "Scan line " + i + " length expected" );

            decompress( in, rgbe );

            for ( int channel = 0; channel < 3; channel++ ) {
                int channelOffset = channel * width;
                int eOffset = 3 * width;

                for ( int p = 0; p < width; p++ ) {
                    int mantissa = rgbe[p + eOffset] & 0xff;
                    int pos = p + i * width;

                    if ( 0 == mantissa ) {
                        out[channel][pos] = 0;
                    } else {
                        float mult = (float) Math.pow( 2, mantissa - ( 128 + 8 ) );
                        out[channel][pos] = ( ( rgbe[p + channelOffset] & 0xff ) + 0.5f ) * mult;
                    }
                }
            }
        }

        return out;
    }

    private static void decompress( InputStream in, byte[] out ) throws IOException {
        int position = 0;
        int total = out.length;

        while ( position < total ) {
            int n = in.read();

            if ( n > 128 ) {
                int value = in.read();

                for ( int i = 0; i < ( n & 0x7f ); i++ ) {
                    out[position++] = (byte) value;
                }
            } else {
                for ( int i = 0; i < n; i++ ) {
                    out[position++] = (byte) in.read();
                }
            }
        }
    }
}