/*
 * 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.sanselan.formats.tiff;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.sanselan.ImageReadException;
import org.apache.commons.sanselan.common.RationalNumber;
import org.apache.commons.sanselan.formats.tiff.constants.TiffConstants;
import org.apache.commons.sanselan.formats.tiff.constants.TiffTagConstants;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfo;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoAscii;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoByte;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoDouble;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoFloat;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoGpsText;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoLong;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoRational;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoSByte;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoSLong;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoSRational;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoSShort;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoShort;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfoXpString;

public class TiffDirectory extends TiffElement implements TiffConstants
//extends BinaryFileFunctions
{

    public String description()
    {
        return TiffDirectory.description(type);
    }

    @Override
    public String getElementDescription(boolean verbose)
    {
        if (!verbose)
            return "TIFF Directory (" + description() + ")";

        int entryOffset = offset + TIFF_DIRECTORY_HEADER_LENGTH;

        StringBuffer result = new StringBuffer();
        for (int i = 0; i < entries.size(); i++)
        {
            TiffField entry = entries.get(i);

            result.append("\t");
            result.append("[" + entryOffset + "]: ");
            result.append(entry.tagInfo.name);
            result.append(" (" + entry.tag + ", 0x"
                    + Integer.toHexString(entry.tag) + ")");
            result.append(", " + entry.fieldType.name);
            result.append(", " + entry.fieldType.getRawBytes(entry).length);
            result.append(": " + entry.getValueDescription());

            result.append("\n");

            entryOffset += TIFF_ENTRY_LENGTH;
            //            entry.fillInValue(byteSource);
        }
        return result.toString();
    }

    public static final String description(int type)
    {
        switch (type)
        {
            case DIRECTORY_TYPE_UNKNOWN :
                return "Unknown";
            case DIRECTORY_TYPE_ROOT :
                return "Root";
            case DIRECTORY_TYPE_SUB :
                return "Sub";
            case DIRECTORY_TYPE_THUMBNAIL :
                return "Thumbnail";
            case DIRECTORY_TYPE_EXIF :
                return "Exif";
            case DIRECTORY_TYPE_GPS :
                return "Gps";
            case DIRECTORY_TYPE_INTEROPERABILITY :
                return "Interoperability";
            default :
                return "Bad Type";
        }
    }

    public final int type;
    public final List<TiffField> entries;
    //    public final int offset;
    public final int nextDirectoryOffset;

    public TiffDirectory(int type, List<TiffField> entries, final int offset,
            int nextDirectoryOffset)
    {
        super(offset, TIFF_DIRECTORY_HEADER_LENGTH + entries.size()
                * TIFF_ENTRY_LENGTH + TIFF_DIRECTORY_FOOTER_LENGTH);

        this.type = type;
        this.entries = entries;
        this.nextDirectoryOffset = nextDirectoryOffset;
    }

    public List<TiffField> getDirectoryEntrys()
    {
        return new ArrayList<TiffField>(entries);
    }

    public void dump()
    {
        for (int i = 0; i < entries.size(); i++)
        {
            TiffField entry = entries.get(i);
            entry.dump();
        }

    }

    public boolean hasJpegImageData() throws ImageReadException
    {
        if (null != findField(TiffTagConstants.TIFF_TAG_JPEG_INTERCHANGE_FORMAT))
            return true;

        return false;
    }

    public boolean hasTiffImageData() throws ImageReadException
    {
        if (null != findField(TiffTagConstants.TIFF_TAG_TILE_OFFSETS))
            return true;

        if (null != findField(TiffTagConstants.TIFF_TAG_STRIP_OFFSETS))
            return true;

        return false;
    }

    public BufferedImage getTiffImage(int byteOrder) throws ImageReadException, IOException
    {
        Map params = null;
        return getTiffImage(byteOrder, params);
    }

    public BufferedImage getTiffImage(int byteOrder, Map params) throws ImageReadException,
            IOException
    {
        if (null == tiffImageData)
            return null;

        return new TiffImageParser().getBufferedImage(this, byteOrder, params);
    }

    public TiffField findField(TagInfo tag) throws ImageReadException
    {
        boolean failIfMissing = false;
        return findField(tag, failIfMissing);
    }

    public TiffField findField(TagInfo tag, boolean failIfMissing)
            throws ImageReadException
    {
        if (entries == null)
            return null;

        for (int i = 0; i < entries.size(); i++)
        {
            TiffField field = entries.get(i);
            if (field.tag == tag.tag)
                return field;
        }

        if (failIfMissing)
            throw new ImageReadException("Missing expected field: "
                    + tag.getDescription());

        return null;
    }
    
    public Object getFieldValue(TagInfo tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        return field.getValue();
    }
    
    public byte[] getFieldValue(TagInfoByte tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        return field.fieldType.getRawBytes(field);
    }
    
    public String[] getFieldValue(TagInfoAscii tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public short[] getFieldValue(TagInfoShort tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public int[] getFieldValue(TagInfoLong tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public RationalNumber[] getFieldValue(TagInfoRational tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public byte[] getFieldValue(TagInfoSByte tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        return field.fieldType.getRawBytes(field);
    }
    
    public short[] getFieldValue(TagInfoSShort tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public int[] getFieldValue(TagInfoSLong tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public RationalNumber[] getFieldValue(TagInfoSRational tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public float[] getFieldValue(TagInfoFloat tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public double[] getFieldValue(TagInfoDouble tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        if (!tag.dataTypes.contains(field.fieldType)) {
            return null;
        }
        byte[] bytes = field.fieldType.getRawBytes(field);
        return tag.getValue(field.byteOrder, bytes);
    }
    
    public String getFieldValue(TagInfoGpsText tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        return tag.getValue(field);
    }
    
    public String getFieldValue(TagInfoXpString tag) throws ImageReadException {
        TiffField field = findField(tag);
        if (field == null) {
            return null;
        }
        return tag.getValue(field);
    }
    
    public static final class ImageDataElement extends TiffElement
    {
        public ImageDataElement(int offset, int length)
        {
            super(offset, length);
        }

        @Override
        public String getElementDescription(boolean verbose)
        {
            if (verbose)
                return null;
            return "ImageDataElement";
        }
    }

    private List<ImageDataElement> getRawImageDataElements(TiffField offsetsField,
            TiffField byteCountsField) throws ImageReadException
    {
        int offsets[] = offsetsField.getIntArrayValue();
        int byteCounts[] = byteCountsField.getIntArrayValue();

        if (offsets.length != byteCounts.length)
            throw new ImageReadException("offsets.length(" + offsets.length
                    + ") != byteCounts.length(" + byteCounts.length + ")");

        List<ImageDataElement> result = new ArrayList<ImageDataElement>();
        for (int i = 0; i < offsets.length; i++)
        {
            result.add(new ImageDataElement(offsets[i], byteCounts[i]));
        }
        return result;
    }

    public List<ImageDataElement> getTiffRawImageDataElements() throws ImageReadException
    {
        TiffField tileOffsets = findField(TiffTagConstants.TIFF_TAG_TILE_OFFSETS);
        TiffField tileByteCounts = findField(TiffTagConstants.TIFF_TAG_TILE_BYTE_COUNTS);
        TiffField stripOffsets = findField(TiffTagConstants.TIFF_TAG_STRIP_OFFSETS);
        TiffField stripByteCounts = findField(TiffTagConstants.TIFF_TAG_STRIP_BYTE_COUNTS);

        if ((tileOffsets != null) && (tileByteCounts != null))
        {
            return getRawImageDataElements(tileOffsets, tileByteCounts);
        }
        else if ((stripOffsets != null) && (stripByteCounts != null))
        {
            return getRawImageDataElements(stripOffsets, stripByteCounts);
        }
        else
            throw new ImageReadException("Couldn't find image data.");
    }

    public boolean imageDataInStrips() throws ImageReadException
    {
        TiffField tileOffsets = findField(TiffTagConstants.TIFF_TAG_TILE_OFFSETS);
        TiffField tileByteCounts = findField(TiffTagConstants.TIFF_TAG_TILE_BYTE_COUNTS);
        TiffField stripOffsets = findField(TiffTagConstants.TIFF_TAG_STRIP_OFFSETS);
        TiffField stripByteCounts = findField(TiffTagConstants.TIFF_TAG_STRIP_BYTE_COUNTS);

        if ((tileOffsets != null) && (tileByteCounts != null))
            return false;
        else if ((stripOffsets != null) && (stripByteCounts != null))
            return true;
        else if ((stripOffsets != null) && (stripByteCounts != null))
            return true;
        else
            throw new ImageReadException("Couldn't find image data.");
    }

    public ImageDataElement getJpegRawImageDataElement()
            throws ImageReadException
    {
        TiffField jpegInterchangeFormat = findField(TiffTagConstants.TIFF_TAG_JPEG_INTERCHANGE_FORMAT);
        TiffField jpegInterchangeFormatLength = findField(TiffTagConstants.TIFF_TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);

        if ((jpegInterchangeFormat != null)
                && (jpegInterchangeFormatLength != null))
        {
            int offset = jpegInterchangeFormat.getIntArrayValue()[0];
            int byteCount = jpegInterchangeFormatLength.getIntArrayValue()[0];

            return new ImageDataElement(offset, byteCount);
        }
        else
            throw new ImageReadException("Couldn't find image data.");
    }

    private TiffImageData tiffImageData = null;

    public void setTiffImageData(TiffImageData rawImageData)
    {
        this.tiffImageData = rawImageData;
    }

    public TiffImageData getTiffImageData()
    {
        return tiffImageData;
    }

    private JpegImageData jpegImageData = null;

    public void setJpegImageData(JpegImageData value)
    {
        this.jpegImageData = value;
    }

    public JpegImageData getJpegImageData()
    {
        return jpegImageData;
    }

}
