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

import android.app.DialogFragment;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.RectF;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

import com.adobe.xmp.XMPException;
import com.adobe.xmp.XMPMeta;
import com.android.camera.CameraActivity;
import com.android.camera.app.MediaSaver.OnMediaSavedListener;
import com.android.camera.app.MediaSaver;
import com.android.camera.exif.ExifInterface;
import com.android.camera.tinyplanet.TinyPlanetPreview.PreviewSizeListener;
import com.android.camera.util.XmpUtil;
import com.android.camera2.R;

import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.TimeZone;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * An activity that provides an editor UI to create a TinyPlanet image from a
 * 360 degree stereographically mapped panoramic image.
 */
public class TinyPlanetFragment extends DialogFragment implements PreviewSizeListener {
    /** Argument to tell the fragment the URI of the original panoramic image. */
    public static final String ARGUMENT_URI = "uri";
    /** Argument to tell the fragment the title of the original panoramic image. */
    public static final String ARGUMENT_TITLE = "title";

    public static final String CROPPED_AREA_IMAGE_WIDTH_PIXELS =
            "CroppedAreaImageWidthPixels";
    public static final String CROPPED_AREA_IMAGE_HEIGHT_PIXELS =
            "CroppedAreaImageHeightPixels";
    public static final String CROPPED_AREA_FULL_PANO_WIDTH_PIXELS =
            "FullPanoWidthPixels";
    public static final String CROPPED_AREA_FULL_PANO_HEIGHT_PIXELS =
            "FullPanoHeightPixels";
    public static final String CROPPED_AREA_LEFT =
            "CroppedAreaLeftPixels";
    public static final String CROPPED_AREA_TOP =
            "CroppedAreaTopPixels";
    public static final String GOOGLE_PANO_NAMESPACE = "http://ns.google.com/photos/1.0/panorama/";

    private static final String TAG = "TinyPlanetActivity";
    /** Delay between a value update and the renderer running. */
    private static final int RENDER_DELAY_MILLIS = 50;
    /** Filename prefix to prepend to the original name for the new file. */
    private static final String FILENAME_PREFIX = "TINYPLANET_";

    private Uri mSourceImageUri;
    private TinyPlanetPreview mPreview;
    private int mPreviewSizePx = 0;
    private float mCurrentZoom = 0.5f;
    private float mCurrentAngle = 0;
    private ProgressDialog mDialog;

    /**
     * Lock for the result preview bitmap. We can't change it while we're trying
     * to draw it.
     */
    private Lock mResultLock = new ReentrantLock();

    /** The title of the original panoramic image. */
    private String mOriginalTitle = "";

    /** The padded source bitmap. */
    private Bitmap mSourceBitmap;
    /** The resulting preview bitmap. */
    private Bitmap mResultBitmap;

    /** Used to delay-post a tiny planet rendering task. */
    private Handler mHandler = new Handler();
    /** Whether rendering is in progress right now. */
    private Boolean mRendering = false;
    /**
     * Whether we should render one more time after the current rendering run is
     * done. This is needed when there was an update to the values during the
     * current rendering.
     */
    private Boolean mRenderOneMore = false;

    /** Tiny planet data plus size. */
    private static final class TinyPlanetImage {
        public final byte[] mJpegData;
        public final int mSize;

        public TinyPlanetImage(byte[] jpegData, int size) {
            mJpegData = jpegData;
            mSize = size;
        }
    }

    /**
     * Creates and executes a task to create a tiny planet with the current
     * values.
     */
    private final Runnable mCreateTinyPlanetRunnable = new Runnable() {
        @Override
        public void run() {
            synchronized (mRendering) {
                if (mRendering) {
                    mRenderOneMore = true;
                    return;
                }
                mRendering = true;
            }

            (new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... params) {
                    mResultLock.lock();
                    try {
                        if (mSourceBitmap == null || mResultBitmap == null) {
                            return null;
                        }

                        int width = mSourceBitmap.getWidth();
                        int height = mSourceBitmap.getHeight();
                        TinyPlanetNative.process(mSourceBitmap, width, height, mResultBitmap,
                                mPreviewSizePx,
                                mCurrentZoom, mCurrentAngle);
                    } finally {
                        mResultLock.unlock();
                    }
                    return null;
                }

                protected void onPostExecute(Void result) {
                    mPreview.setBitmap(mResultBitmap, mResultLock);
                    synchronized (mRendering) {
                        mRendering = false;
                        if (mRenderOneMore) {
                            mRenderOneMore = false;
                            scheduleUpdate();
                        }
                    }
                }
            }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NORMAL, R.style.Theme_Camera);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getDialog().setCanceledOnTouchOutside(true);

        View view = inflater.inflate(R.layout.tinyplanet_editor,
                container, false);
        mPreview = (TinyPlanetPreview) view.findViewById(R.id.preview);
        mPreview.setPreviewSizeChangeListener(this);

        // Zoom slider setup.
        SeekBar zoomSlider = (SeekBar) view.findViewById(R.id.zoomSlider);
        zoomSlider.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // Do nothing.
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // Do nothing.
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                onZoomChange(progress);
            }
        });

        // Rotation slider setup.
        SeekBar angleSlider = (SeekBar) view.findViewById(R.id.angleSlider);
        angleSlider.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // Do nothing.
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // Do nothing.
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                onAngleChange(progress);
            }
        });

        Button createButton = (Button) view.findViewById(R.id.creatTinyPlanetButton);
        createButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                onCreateTinyPlanet();
            }
        });

        mOriginalTitle = getArguments().getString(ARGUMENT_TITLE);
        mSourceImageUri = Uri.parse(getArguments().getString(ARGUMENT_URI));
        mSourceBitmap = createPaddedSourceImage(mSourceImageUri, true);

        if (mSourceBitmap == null) {
            Log.e(TAG, "Could not decode source image.");
            dismiss();
        }
        return view;
    }

    /**
     * From the given URI this method creates a 360/180 padded image that is
     * ready to be made a tiny planet.
     */
    private Bitmap createPaddedSourceImage(Uri sourceImageUri, boolean previewSize) {
        InputStream is = getInputStream(sourceImageUri);
        if (is == null) {
            Log.e(TAG, "Could not create input stream for image.");
            dismiss();
        }
        Bitmap sourceBitmap = BitmapFactory.decodeStream(is);

        is = getInputStream(sourceImageUri);
        XMPMeta xmp = XmpUtil.extractXMPMeta(is);

        if (xmp != null) {
            int size = previewSize ? getDisplaySize() : sourceBitmap.getWidth();
            sourceBitmap = createPaddedBitmap(sourceBitmap, xmp, size);
        }
        return sourceBitmap;
    }

    /**
     * Starts an asynchronous task to create a tiny planet. Once done, will add
     * the new image to the filmstrip and dismisses the fragment.
     */
    private void onCreateTinyPlanet() {
        // Make sure we stop rendering before we create the high-res tiny
        // planet.
        synchronized (mRendering) {
            mRenderOneMore = false;
        }

        final String savingTinyPlanet = getActivity().getResources().getString(
                R.string.saving_tiny_planet);
        (new AsyncTask<Void, Void, TinyPlanetImage>() {
            @Override
            protected void onPreExecute() {
                mDialog = ProgressDialog.show(getActivity(), null, savingTinyPlanet, true, false);
            }

            @Override
            protected TinyPlanetImage doInBackground(Void... params) {
                return createTinyPlanet();
            }

            @Override
            protected void onPostExecute(TinyPlanetImage image) {
                // Once created, store the new file and add it to the filmstrip.
                final CameraActivity activity = (CameraActivity) getActivity();
                MediaSaver mediaSaver = activity.getMediaSaver();
                OnMediaSavedListener doneListener =
                        new OnMediaSavedListener() {
                            @Override
                            public void onMediaSaved(Uri uri) {
                                // Add the new photo to the filmstrip and exit
                                // the fragment.
                                activity.notifyNewMedia(uri);
                                mDialog.dismiss();
                                TinyPlanetFragment.this.dismiss();
                            }
                        };
                String tinyPlanetTitle = FILENAME_PREFIX + mOriginalTitle;
                mediaSaver.addImage(image.mJpegData, tinyPlanetTitle, (new Date()).getTime(),
                        null,
                        image.mSize, image.mSize, 0, null, doneListener, getActivity()
                                .getContentResolver());
            }
        }).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    }

    /**
     * Creates the high quality tiny planet file and adds it to the media
     * service. Don't call this on the UI thread.
     */
    private TinyPlanetImage createTinyPlanet() {
        // Free some memory we don't need anymore as we're going to dimiss the
        // fragment after the tiny planet creation.
        mResultLock.lock();
        try {
            mResultBitmap.recycle();
            mResultBitmap = null;
            mSourceBitmap.recycle();
            mSourceBitmap = null;
        } finally {
            mResultLock.unlock();
        }

        // Create a high-resolution padded image.
        Bitmap sourceBitmap = createPaddedSourceImage(mSourceImageUri, false);
        int width = sourceBitmap.getWidth();
        int height = sourceBitmap.getHeight();

        int outputSize = width / 2;
        Bitmap resultBitmap = Bitmap.createBitmap(outputSize, outputSize,
                Bitmap.Config.ARGB_8888);

        TinyPlanetNative.process(sourceBitmap, width, height, resultBitmap,
                outputSize, mCurrentZoom, mCurrentAngle);

        // Free the sourceImage memory as we don't need it and we need memory
        // for the JPEG bytes.
        sourceBitmap.recycle();
        sourceBitmap = null;

        ByteArrayOutputStream jpeg = new ByteArrayOutputStream();
        resultBitmap.compress(CompressFormat.JPEG, 100, jpeg);
        return new TinyPlanetImage(addExif(jpeg.toByteArray()), outputSize);
    }

    /**
     * Adds basic EXIF data to the tiny planet image so it an be rewritten
     * later.
     *
     * @param jpeg the JPEG data of the tiny planet.
     * @return The JPEG data containing basic EXIF.
     */
    private byte[] addExif(byte[] jpeg) {
        ExifInterface exif = new ExifInterface();
        exif.addDateTimeStampTag(ExifInterface.TAG_DATE_TIME, System.currentTimeMillis(),
                TimeZone.getDefault());
        ByteArrayOutputStream jpegOut = new ByteArrayOutputStream();
        try {
            exif.writeExif(jpeg, jpegOut);
        } catch (IOException e) {
            Log.e(TAG, "Could not write EXIF", e);
        }
        return jpegOut.toByteArray();
    }

    private int getDisplaySize() {
        Display display = getActivity().getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        return Math.min(size.x, size.y);
    }

    @Override
    public void onSizeChanged(int sizePx) {
        mPreviewSizePx = sizePx;
        mResultLock.lock();
        try {
            if (mResultBitmap == null || mResultBitmap.getWidth() != sizePx
                    || mResultBitmap.getHeight() != sizePx) {
                if (mResultBitmap != null) {
                    mResultBitmap.recycle();
                }
                mResultBitmap = Bitmap.createBitmap(mPreviewSizePx, mPreviewSizePx,
                        Bitmap.Config.ARGB_8888);
            }
        } finally {
            mResultLock.unlock();
        }

        // Run directly and on this thread directly.
        mCreateTinyPlanetRunnable.run();
    }

    private void onZoomChange(int zoom) {
        // 1000 needs to be in sync with the max values declared in the layout
        // xml file.
        mCurrentZoom = zoom / 1000f;
        scheduleUpdate();
    }

    private void onAngleChange(int angle) {
        mCurrentAngle = (float) Math.toRadians(angle);
        scheduleUpdate();
    }

    /**
     * Delay-post a new preview rendering run.
     */
    private void scheduleUpdate() {
        mHandler.removeCallbacks(mCreateTinyPlanetRunnable);
        mHandler.postDelayed(mCreateTinyPlanetRunnable, RENDER_DELAY_MILLIS);
    }

    private InputStream getInputStream(Uri uri) {
        try {
            return getActivity().getContentResolver().openInputStream(uri);
        } catch (FileNotFoundException e) {
            Log.e(TAG, "Could not load source image.", e);
        }
        return null;
    }

    /**
     * To create a proper TinyPlanet, the input image must be 2:1 (360:180
     * degrees). So if needed, we pad the source image with black.
     */
    private static Bitmap createPaddedBitmap(Bitmap bitmapIn, XMPMeta xmp, int intermediateWidth) {
        try {
            int croppedAreaWidth =
                    getInt(xmp, CROPPED_AREA_IMAGE_WIDTH_PIXELS);
            int croppedAreaHeight =
                    getInt(xmp, CROPPED_AREA_IMAGE_HEIGHT_PIXELS);
            int fullPanoWidth =
                    getInt(xmp, CROPPED_AREA_FULL_PANO_WIDTH_PIXELS);
            int fullPanoHeight =
                    getInt(xmp, CROPPED_AREA_FULL_PANO_HEIGHT_PIXELS);
            int left = getInt(xmp, CROPPED_AREA_LEFT);
            int top = getInt(xmp, CROPPED_AREA_TOP);

            if (fullPanoWidth == 0 || fullPanoHeight == 0) {
                return bitmapIn;
            }
            // Make sure the intermediate image has the similar size to the
            // input.
            Bitmap paddedBitmap = null;
            float scale = intermediateWidth / (float) fullPanoWidth;
            while (paddedBitmap == null) {
                try {
                    paddedBitmap = Bitmap.createBitmap(
                            (int) (fullPanoWidth * scale), (int) (fullPanoHeight * scale),
                            Bitmap.Config.ARGB_8888);
                } catch (OutOfMemoryError e) {
                    System.gc();
                    scale /= 2;
                }
            }
            Canvas paddedCanvas = new Canvas(paddedBitmap);

            int right = left + croppedAreaWidth;
            int bottom = top + croppedAreaHeight;
            RectF destRect = new RectF(left * scale, top * scale, right * scale, bottom * scale);
            paddedCanvas.drawBitmap(bitmapIn, null, destRect, null);
            return paddedBitmap;
        } catch (XMPException ex) {
            // Do nothing, just use mSourceBitmap as is.
        }
        return bitmapIn;
    }

    private static int getInt(XMPMeta xmp, String key) throws XMPException {
        if (xmp.doesPropertyExist(GOOGLE_PANO_NAMESPACE, key)) {
            return xmp.getPropertyInteger(GOOGLE_PANO_NAMESPACE, key);
        } else {
            return 0;
        }
    }
}
