/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * 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.
 */

package com.android.camera.exif;

import com.android.camera.debug.Log;

import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * This class stores the EXIF header in IFDs according to the JPEG
 * specification. It is the result produced by {@link ExifReader}.
 *
 * @see ExifReader
 * @see IfdData
 */
class ExifData {
    private static final Log.Tag TAG = new Log.Tag("ExifData");
    private static final byte[] USER_COMMENT_ASCII = {
            0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00
    };
    private static final byte[] USER_COMMENT_JIS = {
            0x4A, 0x49, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    private static final byte[] USER_COMMENT_UNICODE = {
            0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0x00
    };

    private final IfdData[] mIfdDatas = new IfdData[IfdId.TYPE_IFD_COUNT];
    private byte[] mThumbnail;
    private ArrayList<byte[]> mStripBytes = new ArrayList<byte[]>();
    private final ByteOrder mByteOrder;

    ExifData(ByteOrder order) {
        mByteOrder = order;
    }

    /**
     * Gets the compressed thumbnail. Returns null if there is no compressed
     * thumbnail.
     *
     * @see #hasCompressedThumbnail()
     */
    protected byte[] getCompressedThumbnail() {
        return mThumbnail;
    }

    /**
     * Sets the compressed thumbnail.
     */
    protected void setCompressedThumbnail(byte[] thumbnail) {
        mThumbnail = thumbnail;
    }

    /**
     * Returns true it this header contains a compressed thumbnail.
     */
    protected boolean hasCompressedThumbnail() {
        return mThumbnail != null;
    }

    /**
     * Adds an uncompressed strip.
     */
    protected void setStripBytes(int index, byte[] strip) {
        if (index < mStripBytes.size()) {
            mStripBytes.set(index, strip);
        } else {
            for (int i = mStripBytes.size(); i < index; i++) {
                mStripBytes.add(null);
            }
            mStripBytes.add(strip);
        }
    }

    /**
     * Gets the strip count.
     */
    protected int getStripCount() {
        return mStripBytes.size();
    }

    /**
     * Gets the strip at the specified index.
     *
     * @exceptions #IndexOutOfBoundException
     */
    protected byte[] getStrip(int index) {
        return mStripBytes.get(index);
    }

    /**
     * Returns true if this header contains uncompressed strip.
     */
    protected boolean hasUncompressedStrip() {
        return mStripBytes.size() != 0;
    }

    /**
     * Gets the byte order.
     */
    protected ByteOrder getByteOrder() {
        return mByteOrder;
    }

    /**
     * Returns the {@link IfdData} object corresponding to a given IFD if it
     * exists or null.
     */
    protected IfdData getIfdData(int ifdId) {
        if (ExifTag.isValidIfd(ifdId)) {
            return mIfdDatas[ifdId];
        }
        return null;
    }

    /**
     * Adds IFD data. If IFD data of the same type already exists, it will be
     * replaced by the new data.
     */
    protected void addIfdData(IfdData data) {
        mIfdDatas[data.getId()] = data;
    }

    /**
     * Returns the {@link IfdData} object corresponding to a given IFD or
     * generates one if none exist.
     */
    protected IfdData getOrCreateIfdData(int ifdId) {
        IfdData ifdData = mIfdDatas[ifdId];
        if (ifdData == null) {
            ifdData = new IfdData(ifdId);
            mIfdDatas[ifdId] = ifdData;
        }
        return ifdData;
    }

    /**
     * Returns the tag with a given TID in the given IFD if the tag exists.
     * Otherwise returns null.
     */
    protected ExifTag getTag(short tag, int ifd) {
        IfdData ifdData = mIfdDatas[ifd];
        return (ifdData == null) ? null : ifdData.getTag(tag);
    }

    /**
     * Adds the given ExifTag to its default IFD and returns an existing ExifTag
     * with the same TID or null if none exist.
     */
    protected ExifTag addTag(ExifTag tag) {
        if (tag != null) {
            int ifd = tag.getIfd();
            return addTag(tag, ifd);
        }
        return null;
    }

    /**
     * Adds the given ExifTag to the given IFD and returns an existing ExifTag
     * with the same TID or null if none exist.
     */
    protected ExifTag addTag(ExifTag tag, int ifdId) {
        if (tag != null && ExifTag.isValidIfd(ifdId)) {
            IfdData ifdData = getOrCreateIfdData(ifdId);
            return ifdData.setTag(tag);
        }
        return null;
    }

    protected void clearThumbnailAndStrips() {
        mThumbnail = null;
        mStripBytes.clear();
    }

    /**
     * Removes the thumbnail and its related tags. IFD1 will be removed.
     */
    protected void removeThumbnailData() {
        clearThumbnailAndStrips();
        mIfdDatas[IfdId.TYPE_IFD_1] = null;
    }

    /**
     * Removes the tag with a given TID and IFD.
     */
    protected void removeTag(short tagId, int ifdId) {
        IfdData ifdData = mIfdDatas[ifdId];
        if (ifdData == null) {
            return;
        }
        ifdData.removeTag(tagId);
    }

    /**
     * Decodes the user comment tag into string as specified in the EXIF
     * standard. Returns null if decoding failed.
     */
    protected String getUserComment() {
        IfdData ifdData = mIfdDatas[IfdId.TYPE_IFD_0];
        if (ifdData == null) {
            return null;
        }
        ExifTag tag = ifdData.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_USER_COMMENT));
        if (tag == null) {
            return null;
        }
        if (tag.getComponentCount() < 8) {
            return null;
        }

        byte[] buf = new byte[tag.getComponentCount()];
        tag.getBytes(buf);

        byte[] code = new byte[8];
        System.arraycopy(buf, 0, code, 0, 8);

        try {
            if (Arrays.equals(code, USER_COMMENT_ASCII)) {
                return new String(buf, 8, buf.length - 8, "US-ASCII");
            } else if (Arrays.equals(code, USER_COMMENT_JIS)) {
                return new String(buf, 8, buf.length - 8, "EUC-JP");
            } else if (Arrays.equals(code, USER_COMMENT_UNICODE)) {
                return new String(buf, 8, buf.length - 8, "UTF-16");
            } else {
                return null;
            }
        } catch (UnsupportedEncodingException e) {
            Log.w(TAG, "Failed to decode the user comment");
            return null;
        }
    }

    /**
     * Returns a list of all {@link ExifTag}s in the ExifData or null if there
     * are none.
     */
    protected List<ExifTag> getAllTags() {
        ArrayList<ExifTag> ret = new ArrayList<ExifTag>();
        for (IfdData d : mIfdDatas) {
            if (d != null) {
                ExifTag[] tags = d.getAllTags();
                if (tags != null) {
                    for (ExifTag t : tags) {
                        ret.add(t);
                    }
                }
            }
        }
        if (ret.size() == 0) {
            return null;
        }
        return ret;
    }

    /**
     * Returns a list of all {@link ExifTag}s in a given IFD or null if there
     * are none.
     */
    protected List<ExifTag> getAllTagsForIfd(int ifd) {
        IfdData d = mIfdDatas[ifd];
        if (d == null) {
            return null;
        }
        ExifTag[] tags = d.getAllTags();
        if (tags == null) {
            return null;
        }
        ArrayList<ExifTag> ret = new ArrayList<ExifTag>(tags.length);
        for (ExifTag t : tags) {
            ret.add(t);
        }
        if (ret.size() == 0) {
            return null;
        }
        return ret;
    }

    /**
     * Returns a list of all {@link ExifTag}s with a given TID or null if there
     * are none.
     */
    protected List<ExifTag> getAllTagsForTagId(short tag) {
        ArrayList<ExifTag> ret = new ArrayList<ExifTag>();
        for (IfdData d : mIfdDatas) {
            if (d != null) {
                ExifTag t = d.getTag(tag);
                if (t != null) {
                    ret.add(t);
                }
            }
        }
        if (ret.size() == 0) {
            return null;
        }
        return ret;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (obj instanceof ExifData) {
            ExifData data = (ExifData) obj;
            if (data.mByteOrder != mByteOrder ||
                    data.mStripBytes.size() != mStripBytes.size() ||
                    !Arrays.equals(data.mThumbnail, mThumbnail)) {
                return false;
            }
            for (int i = 0; i < mStripBytes.size(); i++) {
                if (!Arrays.equals(data.mStripBytes.get(i), mStripBytes.get(i))) {
                    return false;
                }
            }
            for (int i = 0; i < IfdId.TYPE_IFD_COUNT; i++) {
                IfdData ifd1 = data.getIfdData(i);
                IfdData ifd2 = getIfdData(i);
                if (ifd1 != ifd2 && ifd1 != null && !ifd1.equals(ifd2)) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

}
