/*
 * Copyright (C) 2009 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.gallery;

import com.android.camera.BitmapManager;
import com.android.camera.Util;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Images.ImageColumns;
import android.util.Log;

import java.io.IOException;

/**
 * The class for normal images in gallery.
 */
public class Image extends BaseImage implements IImage {
    private static final String TAG = "BaseImage";

    private ExifInterface mExif;

    private int mRotation;

    public Image(BaseImageList container, ContentResolver cr,
            long id, int index, Uri uri, String dataPath,
            String mimeType, long dateTaken, String title,
            int rotation) {
        super(container, cr, id, index, uri, dataPath,
                mimeType, dateTaken, title);
        mRotation = rotation;
    }

    @Override
    public int getDegreesRotated() {
        return mRotation;
    }

    protected void setDegreesRotated(int degrees) {
        if (mRotation == degrees) return;
        mRotation = degrees;
        ContentValues values = new ContentValues();
        values.put(ImageColumns.ORIENTATION, mRotation);
        mContentResolver.update(mUri, values, null, null);

        //TODO: Consider invalidate the cursor in container
        // ((BaseImageList) getContainer()).invalidateCursor();
    }

    public boolean isReadonly() {
        String mimeType = getMimeType();
        return !"image/jpeg".equals(mimeType) && !"image/png".equals(mimeType);
    }

    public boolean isDrm() {
        return false;
    }

    /**
     * Replaces the tag if already there. Otherwise, adds to the exif tags.
     * @param tag
     * @param value
     */
    public void replaceExifTag(String tag, String value) {
        if (mExif == null) {
            loadExifData();
        }
        mExif.setAttribute(tag, value);
    }

    private void loadExifData() {
        try {
            mExif = new ExifInterface(mDataPath);
        } catch (IOException ex) {
            Log.e(TAG, "cannot read exif", ex);
        }
    }

    private void saveExifData() throws IOException {
        if (mExif != null) {
            mExif.saveAttributes();
        }
    }

    private void setExifRotation(int degrees) {
        try {
            degrees %= 360;
            if (degrees < 0) degrees += 360;

            int orientation = ExifInterface.ORIENTATION_NORMAL;
            switch (degrees) {
                case 0:
                    orientation = ExifInterface.ORIENTATION_NORMAL;
                    break;
                case 90:
                    orientation = ExifInterface.ORIENTATION_ROTATE_90;
                    break;
                case 180:
                    orientation = ExifInterface.ORIENTATION_ROTATE_180;
                    break;
                case 270:
                    orientation = ExifInterface.ORIENTATION_ROTATE_270;
                    break;
            }

            replaceExifTag(ExifInterface.TAG_ORIENTATION,
                    Integer.toString(orientation));
            saveExifData();
        } catch (Exception ex) {
            Log.e(TAG, "unable to save exif data with new orientation "
                    + fullSizeImageUri(), ex);
        }
    }

    /**
     * Save the rotated image by updating the Exif "Orientation" tag.
     * @param degrees
     */
    public boolean rotateImageBy(int degrees) {
        int newDegrees = (getDegreesRotated() + degrees) % 360;
        setExifRotation(newDegrees);
        setDegreesRotated(newDegrees);

        return true;
    }

    private static final String[] THUMB_PROJECTION = new String[] {
        BaseColumns._ID,
    };

    public Bitmap thumbBitmap(boolean rotateAsNeeded) {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inDither = false;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        bitmap = BitmapManager.instance().getThumbnail(mContentResolver, mId,
                Images.Thumbnails.MINI_KIND, options, false);

        if (bitmap != null && rotateAsNeeded) {
            bitmap = Util.rotate(bitmap, getDegreesRotated());
        }

        return bitmap;
    }
}
