/*
 * 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.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.apache.commons.sanselan.ImageReadException;
import org.apache.commons.sanselan.common.bytesource.ByteSource;
import org.apache.commons.sanselan.formats.tiff.constants.ExifTagConstants;
import org.apache.commons.sanselan.formats.tiff.constants.GpsTagConstants;
import org.apache.commons.sanselan.formats.tiff.constants.TiffConstants;
import org.apache.commons.sanselan.formats.tiff.constants.TiffDirectoryType;
import org.apache.commons.sanselan.formats.tiff.constants.TiffTagConstants;
import org.apache.commons.sanselan.formats.tiff.fieldtypes.FieldType;
import org.apache.commons.sanselan.formats.tiff.taginfos.TagInfo;

public class TiffField implements TiffConstants
{
    public final TagInfo tagInfo;
    public final FieldType fieldType;

    public final int tag;
    public final int directoryType;
    public final int type;
    public final int length;
    public final int valueOffset;
    public final byte valueOffsetBytes[];

    public byte oversizeValue[] = null;
    public final int byteOrder;

    public TiffField(int tag, int directoryType, int type, int Length,
            int ValueOffset, byte ValueOffsetBytes[], int byteOrder)
    {

        this.tag = tag;
        this.directoryType = directoryType;
        this.type = type;
        this.length = Length;
        this.valueOffset = ValueOffset;
        this.valueOffsetBytes = ValueOffsetBytes;
        this.byteOrder = byteOrder;

        fieldType = getFieldType(type);
        tagInfo = getTag(directoryType, tag);
    }

    private int sortHint = -1;

    public boolean isLocalValue()
    {
        return fieldType.isLocalValue(this);
    }

    public int getBytesLength() throws ImageReadException
    {
        return fieldType.getBytesLength(this);
    }

    public final class OversizeValueElement extends TiffElement
    {
        public OversizeValueElement(int offset, int length)
        {
            super(offset, length);
        }

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

            return "OversizeValueElement, tag: " + tagInfo.name
                    + ", fieldType: " + fieldType.name;
        }
    }

    public TiffElement getOversizeValueElement()
    {
        if (fieldType.isLocalValue(this))
            return null;

        return new OversizeValueElement(valueOffset, oversizeValue.length);
    }

    public void setOversizeValue(byte bytes[])
    {
        this.oversizeValue = bytes;
    }

    private static FieldType getFieldType(int value)
    {
        for (int i = 0; i < FIELD_TYPES.size(); i++)
        {
            FieldType fieldType = FIELD_TYPES.get(i);
            if (fieldType.type == value)
                return fieldType;
        }

        return FIELD_TYPE_UNKNOWN;
    }

    private static TagInfo getTag(int directoryType, int tag,
            List<TagInfo> possibleMatches)
    {
        // Please keep this method in sync with TiffImageMetadata's findField()

        if (possibleMatches.size() < 1)
            return null;
        // else if (possibleMatches.size() == 1)
        // {
        // TagInfo tagInfo = (TagInfo) possibleMatches.get(0);
        // return tagInfo;
        // }

        // first search for exact match.
        for (int i = 0; i < possibleMatches.size(); i++)
        {
            TagInfo tagInfo = possibleMatches.get(i);
            if (tagInfo.directoryType == TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN)
                // pass
                continue;
            else if (directoryType == tagInfo.directoryType.directoryType)
                return tagInfo;
        }

        // accept an inexact match.
        for (int i = 0; i < possibleMatches.size(); i++)
        {
            TagInfo tagInfo = possibleMatches.get(i);

            if (tagInfo.directoryType == TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN)
                // pass
                continue;
            else if (directoryType >= 0
                    && tagInfo.directoryType.isImageDirectory())
                return tagInfo;
            else if (directoryType < 0
                    && !tagInfo.directoryType.isImageDirectory())
                return tagInfo;
        }

        // accept a wildcard match.
        for (int i = 0; i < possibleMatches.size(); i++)
        {
            TagInfo tagInfo = possibleMatches.get(i);

            if (tagInfo.directoryType == TiffDirectoryType.EXIF_DIRECTORY_UNKNOWN)
                return tagInfo;
        }

        // // accept a very rough match.
        // for (int i = 0; i < possibleMatches.size(); i++)
        // {
        // TagInfo tagInfo = (TagInfo) possibleMatches.get(i);
        // if (tagInfo.exifDirectory == EXIF_DIRECTORY_UNKNOWN)
        // return tagInfo;
        // else if (directoryType == DIRECTORY_TYPE_EXIF
        // && tagInfo.exifDirectory == EXIF_DIRECTORY_EXIF_IFD)
        // return tagInfo;
        // else if (directoryType == DIRECTORY_TYPE_INTEROPERABILITY
        // && tagInfo.exifDirectory == EXIF_DIRECTORY_INTEROP_IFD)
        // return tagInfo;
        // else if (directoryType == DIRECTORY_TYPE_GPS
        // && tagInfo.exifDirectory == EXIF_DIRECTORY_GPS)
        // return tagInfo;
        // else if (directoryType == DIRECTORY_TYPE_MAKER_NOTES
        // && tagInfo.exifDirectory == EXIF_DIRECTORY_MAKER_NOTES)
        // return tagInfo;
        // else if (directoryType >= 0
        // && tagInfo.exifDirectory.isImageDirectory())
        // return tagInfo;
        // else if (directoryType < 0
        // && !tagInfo.exifDirectory.isImageDirectory())
        // return tagInfo;
        // }

        return TiffTagConstants.TIFF_TAG_UNKNOWN;

        // if (true)
        // throw new Error("Why didn't this algorithm work?");
        //
        // {
        // TagInfo tagInfo = (TagInfo) possibleMatches.get(0);
        // return tagInfo;
        // }

        // Object key = new Integer(tag);
        //
        // if (directoryType == DIRECTORY_TYPE_EXIF
        // || directoryType == DIRECTORY_TYPE_INTEROPERABILITY)
        // {
        // if (EXIF_TAG_MAP.containsKey(key))
        // return (TagInfo) EXIF_TAG_MAP.get(key);
        // }
        // else if (directoryType == DIRECTORY_TYPE_GPS)
        // {
        // if (GPS_TAG_MAP.containsKey(key))
        // return (TagInfo) GPS_TAG_MAP.get(key);
        // }
        // else
        // {
        // if (TIFF_TAG_MAP.containsKey(key))
        // return (TagInfo) TIFF_TAG_MAP.get(key);
        // }
        //
        // if (ALL_TAG_MAP.containsKey(key))
        // return (TagInfo) ALL_TAG_MAP.get(key);

        // public static final int DIRECTORY_TYPE_EXIF = -2;
        // // public static final int DIRECTORY_TYPE_SUB = 5;
        // public static final int DIRECTORY_TYPE_GPS = -3;
        // public static final int DIRECTORY_TYPE_INTEROPERABILITY = -4;
        //
        // private static final Map GPS_TAG_MAP = makeTagMap(ALL_GPS_TAGS,
        // false);
        // private static final Map TIFF_TAG_MAP = makeTagMap(ALL_TIFF_TAGS,
        // false);
        // private static final Map EXIF_TAG_MAP = makeTagMap(ALL_EXIF_TAGS,
        // false);
        // private static final Map ALL_TAG_MAP = makeTagMap(ALL_TAGS, true);
        //
        // for (int i = 0; i < ALL_TAGS.length; i++)
        // {
        // TagInfo2 tag = ALL_TAGS[i];
        // if (tag.tag == value)
        // return tag;
        // }

        // return TIFF_TAG_UNKNOWN;
    }

    private static TagInfo getTag(int directoryType, int tag)
    {
        List<TagInfo> possibleMatches = ALL_TAG_MAP.get(tag);

        if (null == possibleMatches)
        {
            return TiffTagConstants.TIFF_TAG_UNKNOWN;
        }

        TagInfo result = getTag(directoryType, tag, possibleMatches);
        return result;
    }

    private int getValueLengthInBytes()
    {
        int unit_length = fieldType.length;
        int valueLength = unit_length * length;

        // Debug.debug("getValueLengthInBytes unit_length", unit_length);
        // Debug.debug("getValueLengthInBytes length", length);

        return valueLength;
    }

    public void fillInValue(ByteSource byteSource) throws IOException, TiffValueOutsideFileBoundsException
    {
        if (fieldType.isLocalValue(this))
            return;

        int valueLength = getValueLengthInBytes();
        long valueLengthLong = 0xffffffffL & valueLength;

        // Debug.debug("fillInValue tag", tag);
        // Debug.debug("fillInValue tagInfo", tagInfo);
        // Debug.debug("fillInValue valueOffset", valueOffset);
        // Debug.debug("fillInValue valueLength", valueLength);

        if (valueOffset < 0 ||
            valueOffset + valueLengthLong > byteSource.getLength()) {
            throw new TiffValueOutsideFileBoundsException(
                "Attempt to read byte range starting from " + valueOffset + " " +
                "of length " + valueLength + " " +
                "which is outside the file's size of " + byteSource.getLength());
        }
        byte bytes[] = byteSource.getBlock(valueOffset, valueLength);
        setOversizeValue(bytes);
    }

    public String getValueDescription()
    {
        try
        {
            return getValueDescription(getValue());
        } catch (ImageReadException e)
        {
            return "Invalid value: " + e.getMessage();
        }
    }

    private String getValueDescription(Object o)
    {
        if (o == null)
            return null;

        if (o instanceof Number)
        {
            return o.toString();
        } else if (o instanceof String)
        {
            return "'" + o.toString().trim() + "'";
        } else if (o instanceof Date)
        {
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
            return df.format((Date) o);
        } else if (o instanceof Object[])
        {
            Object objects[] = (Object[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < objects.length; i++)
            {
                Object object = objects[i];

                if (i > 50)
                {
                    result.append("... (" + objects.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + object);
            }
            return result.toString();
        }
        // else if (o instanceof Number[])
        // {
        // Number numbers[] = (Number[]) o;
        // StringBuffer result = new StringBuffer();
        //
        // for (int i = 0; i < numbers.length; i++)
        // {
        // Number number = numbers[i];
        //
        // if (i > 0)
        // result.append(", ");
        // result.append("" + number);
        // }
        // return result.toString();
        // }
        else if (o instanceof short[])
        {
            short values[] = (short[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                short value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        }
        else if (o instanceof int[])
        {
            int values[] = (int[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                int value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        } else if (o instanceof long[])
        {
            long values[] = (long[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                long value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        } else if (o instanceof double[])
        {
            double values[] = (double[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                double value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        } else if (o instanceof byte[])
        {
            byte values[] = (byte[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                byte value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        } else if (o instanceof char[])
        {
            char values[] = (char[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                char value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        } else if (o instanceof float[])
        {
            float values[] = (float[]) o;
            StringBuffer result = new StringBuffer();

            for (int i = 0; i < values.length; i++)
            {
                float value = values[i];

                if (i > 50)
                {
                    result.append("... (" + values.length + ")");
                    break;
                }
                if (i > 0)
                    result.append(", ");
                result.append("" + value);
            }
            return result.toString();
        }
        // else if (o instanceof short[])
        // {
        // short numbers[] = (short[]) o;
        // StringBuffer result = new StringBuffer();
        //
        // for (int i = 0; i < numbers.length; i++)
        // {
        // short number = numbers[i];
        //
        // if (i > 0)
        // result.append(", ");
        // result.append("" + number);
        // }
        // return result.toString();
        // }

        return "Unknown: " + o.getClass().getName();
    }

    public void dump()
    {
        PrintWriter pw = new PrintWriter(System.out);
        dump(pw);
        pw.flush();
    }

    public void dump(PrintWriter pw)
    {
        dump(pw, null);
    }

    public void dump(PrintWriter pw, String prefix)
    {
        if (prefix != null)
            pw.print(prefix + ": ");

        pw.println(toString());
        pw.flush();
    }

    // private void errorDump()
    // {
    // Debug.debug("tagInfo", tagInfo);
    // Debug.debug("fieldType", fieldType);
    // Debug.debug("tag", tag);
    // Debug.debug("type", type);
    // Debug.debug("length", length);
    // Debug.debug("valueOffset", valueOffset);
    // Debug.debug("valueOffsetBytes", valueOffsetBytes);
    // Debug.debug("oversizeValue", oversizeValue);
    // Debug.debug("byteOrder", byteOrder);
    // }

    public String getDescriptionWithoutValue()
    {
        return tag + " (0x" + Integer.toHexString(tag) + ": " + tagInfo.name
                + "): ";
    }

    @Override
    public String toString()
    {
        StringBuffer result = new StringBuffer();

        result.append(tag + " (0x" + Integer.toHexString(tag) + ": "
                + tagInfo.name + "): ");
        result.append(getValueDescription() + " (" + length + " "
                + fieldType.name + ")");

        return result.toString();
    }

    public String getTagName()
    {
        if (tagInfo == TiffTagConstants.TIFF_TAG_UNKNOWN)
            return tagInfo.name + " (0x" + Integer.toHexString(tag) + ")";
        return tagInfo.name;
    }

    public String getFieldTypeName()
    {
        return fieldType.name;
    }

    public static final String Attribute_Tag = "Tag";

    public Object getValue() throws ImageReadException
    {
        // System.out.print("getValue");
        return tagInfo.getValue(this);
    }

    public String getStringValue() throws ImageReadException
    {
        Object o = getValue();
        if (o == null)
            return null;
        if (!(o instanceof String))
            throw new ImageReadException("Expected String value("
                    + tagInfo.getDescription() + "): " + o);
        return (String) o;
    }

    private static final Map<Object, List<TagInfo>> makeTagMap(List<TagInfo> tags,
                                                               boolean ignoreDuplicates, String name)
    {
        // make sure to use the thread-safe version; this is shared state.
        Map<Object, List<TagInfo>> map = new Hashtable<Object, List<TagInfo>>();

        for (int i = 0; i < tags.size(); i++)
        {
            TagInfo tag = tags.get(i);

            List<TagInfo> tagList = map.get(tag.tag);
            if (tagList == null)
            {
                tagList = new ArrayList<TagInfo>();
                map.put(tag.tag, tagList);
            }
            tagList.add(tag);

            // if (map.get(key) == null)
            // map.put(key, tag);
            // else if (!ignoreDuplicates)
            // {
            // System.out.println("Duplicate tag in " + name + ": " + tag.tag
            // + " (0x" + Integer.toHexString(tag.tag) + ")");
            // System.out.println("\t" + "New name: " + tag.name);
            // System.out.println("\t" + "Old name: "
            // + ((TagInfo) map.get(key)).name);
            // }
        }

        return map;
    }

    private static final Map<Object, List<TagInfo>> GPS_TAG_MAP = makeTagMap(GpsTagConstants.ALL_GPS_TAGS, false,
            "GPS");
    private static final Map<Object, List<TagInfo>> TIFF_TAG_MAP = makeTagMap(TiffTagConstants.ALL_TIFF_TAGS, false,
            "TIFF");
    private static final Map<Object, List<TagInfo>> EXIF_TAG_MAP = makeTagMap(ExifTagConstants.ALL_EXIF_TAGS, true,
            "EXIF");
    private static final Map<Object, List<TagInfo>> ALL_TAG_MAP = makeTagMap(ALL_TAGS, true, "All");

    // static
    // {
    // Map map = new HashMap();
    //
    // for (int i = 0; i < ALL_TAGS.length; i++)
    // {
    // TagInfo2 tag = ALL_TAGS[i];
    // Object o = map.get("" + tag.tag);
    // if (o == null)
    // map.put("" + tag.tag, tag);
    // else
    // {
    // System.out.println("Duplicate tag: " + tag.tag);
    // System.out.println("\t" + "New name: " + tag.name);
    // System.out.println("\t" + "Old name: " + ((TagInfo2) o).name);
    // }
    // }
    //
    // }

    // public static final TagInfo2 ALL_TAGS[] = TagConstantsUtils
    // .mergeTagLists(new TagInfo2[][]{
    // ALL_EXIF_TAGS, ALL_TIFF_TAGS, ALL_GPS_TAGS,
    // });
    //
    //

    public int[] getIntArrayValue() throws ImageReadException
    {
        Object o = getValue();
        // if (o == null)
        // return null;

        if (o instanceof Number)
            return new int[] { ((Number) o).intValue() };
        else if (o instanceof Number[])
        {
            Number numbers[] = (Number[]) o;
            int result[] = new int[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i].intValue();
            return result;
        } else if (o instanceof short[]) {
            short numbers[] = (short[]) o;
            int result[] = new int[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = 0xffff & numbers[i];
            return result;
        } else if (o instanceof int[])
        {
            int numbers[] = (int[]) o;
            int result[] = new int[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i];
            return result;
        }

        throw new ImageReadException("Unknown value: " + o + " for: "
                + tagInfo.getDescription());
        // return null;
    }

    public double[] getDoubleArrayValue() throws ImageReadException
    {
        Object o = getValue();
        // if (o == null)
        // return null;

        if (o instanceof Number)
        {
            return new double[] { ((Number) o).doubleValue() };
        } else if (o instanceof Number[])
        {
            Number numbers[] = (Number[]) o;
            double result[] = new double[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i].doubleValue();
            return result;
        } else if (o instanceof short[]) {
            short numbers[] = (short[]) o;
            double result[] = new double[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i];
            return result;
        } else if (o instanceof int[])
        {
            int numbers[] = (int[]) o;
            double result[] = new double[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i];
            return result;
        } else if (o instanceof float[])
        {
            float numbers[] = (float[]) o;
            double result[] = new double[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i];
            return result;
        } else if (o instanceof double[])
        {
            double numbers[] = (double[]) o;
            double result[] = new double[numbers.length];
            for (int i = 0; i < numbers.length; i++)
                result[i] = numbers[i];
            return result;
        }

        throw new ImageReadException("Unknown value: " + o + " for: "
                + tagInfo.getDescription());
        // return null;
    }

    public int getIntValueOrArraySum() throws ImageReadException
    {
        Object o = getValue();
        // if (o == null)
        // return -1;

        if (o instanceof Number)
            return ((Number) o).intValue();
        else if (o instanceof Number[]) {
            Number numbers[] = (Number[]) o;
            int sum = 0;
            for (int i = 0; i < numbers.length; i++)
                sum += numbers[i].intValue();
            return sum;
        } else if (o instanceof short[]) {
            short[] numbers = (short[]) o;
            int sum = 0;
            for (int i = 0; i < numbers.length; i++)
                sum += numbers[i];
            return sum;
        } else if (o instanceof int[]) {
            int numbers[] = (int[]) o;
            int sum = 0;
            for (int i = 0; i < numbers.length; i++)
                sum += numbers[i];
            return sum;
        }

        throw new ImageReadException("Unknown value: " + o + " for: "
                + tagInfo.getDescription());
        // return -1;
    }

    public int getIntValue() throws ImageReadException
    {
        Object o = getValue();
        if (o == null)
            throw new ImageReadException("Missing value: "
                    + tagInfo.getDescription());

        return ((Number) o).intValue();
    }

    public double getDoubleValue() throws ImageReadException
    {
        Object o = getValue();
        if (o == null)
            throw new ImageReadException("Missing value: "
                    + tagInfo.getDescription());

        return ((Number) o).doubleValue();
    }

    public byte[] getByteArrayValue()
    {
        return fieldType.getRawBytes(this);
    }

    public int getSortHint()
    {
        return sortHint;
    }

    public void setSortHint(int sortHint)
    {
        this.sortHint = sortHint;
    }
}
