/*
 * Copyright (C) 2014 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 android.hardware.camera2.legacy;

import android.graphics.SurfaceTexture;
import android.hardware.camera2.impl.CameraDeviceImpl;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.view.Surface;

import java.util.Collection;

import static com.android.internal.util.Preconditions.*;

/**
 * GLThreadManager handles the thread used for rendering into the configured output surfaces.
 */
public class GLThreadManager {
    private final String TAG;
    private static final boolean DEBUG = false;

    private static final int MSG_NEW_CONFIGURATION = 1;
    private static final int MSG_NEW_FRAME = 2;
    private static final int MSG_CLEANUP = 3;
    private static final int MSG_DROP_FRAMES = 4;
    private static final int MSG_ALLOW_FRAMES = 5;

    private CaptureCollector mCaptureCollector;

    private final CameraDeviceState mDeviceState;

    private final SurfaceTextureRenderer mTextureRenderer;

    private final RequestHandlerThread mGLHandlerThread;

    private final RequestThreadManager.FpsCounter mPrevCounter =
            new RequestThreadManager.FpsCounter("GL Preview Producer");

    /**
     * Container object for Configure messages.
     */
    private static class ConfigureHolder {
        public final ConditionVariable condition;
        public final Collection<Pair<Surface, Size>> surfaces;
        public final CaptureCollector collector;

        public ConfigureHolder(ConditionVariable condition, Collection<Pair<Surface,
                Size>> surfaces, CaptureCollector collector) {
            this.condition = condition;
            this.surfaces = surfaces;
            this.collector = collector;
        }
    }

    private final Handler.Callback mGLHandlerCb = new Handler.Callback() {
        private boolean mCleanup = false;
        private boolean mConfigured = false;
        private boolean mDroppingFrames = false;

        @SuppressWarnings("unchecked")
        @Override
        public boolean handleMessage(Message msg) {
            if (mCleanup) {
                return true;
            }
            try {
                switch (msg.what) {
                    case MSG_NEW_CONFIGURATION:
                        ConfigureHolder configure = (ConfigureHolder) msg.obj;
                        mTextureRenderer.cleanupEGLContext();
                        mTextureRenderer.configureSurfaces(configure.surfaces);
                        mCaptureCollector = checkNotNull(configure.collector);
                        configure.condition.open();
                        mConfigured = true;
                        break;
                    case MSG_NEW_FRAME:
                        if (mDroppingFrames) {
                            Log.w(TAG, "Ignoring frame.");
                            break;
                        }
                        if (DEBUG) {
                            mPrevCounter.countAndLog();
                        }
                        if (!mConfigured) {
                            Log.e(TAG, "Dropping frame, EGL context not configured!");
                        }
                        mTextureRenderer.drawIntoSurfaces(mCaptureCollector);
                        break;
                    case MSG_CLEANUP:
                        mTextureRenderer.cleanupEGLContext();
                        mCleanup = true;
                        mConfigured = false;
                        break;
                    case MSG_DROP_FRAMES:
                        mDroppingFrames = true;
                        break;
                    case MSG_ALLOW_FRAMES:
                        mDroppingFrames = false;
                        break;
                    case RequestHandlerThread.MSG_POKE_IDLE_HANDLER:
                        // OK: Ignore message.
                        break;
                    default:
                        Log.e(TAG, "Unhandled message " + msg.what + " on GLThread.");
                        break;
                }
            } catch (Exception e) {
                Log.e(TAG, "Received exception on GL render thread: ", e);
                mDeviceState.setError(CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE);
            }
            return true;
        }
    };

    /**
     * Create a new GL thread and renderer.
     *
     * @param cameraId the camera id for this thread.
     * @param facing direction the camera is facing.
     * @param state {@link CameraDeviceState} to use for error handling.
     */
    public GLThreadManager(int cameraId, int facing, CameraDeviceState state) {
        mTextureRenderer = new SurfaceTextureRenderer(facing);
        TAG = String.format("CameraDeviceGLThread-%d", cameraId);
        mGLHandlerThread = new RequestHandlerThread(TAG, mGLHandlerCb);
        mDeviceState = state;
    }

    /**
     * Start the thread.
     *
     * <p>
     * This must be called before queueing new frames.
     * </p>
     */
    public void start() {
        mGLHandlerThread.start();
    }

    /**
     * Wait until the thread has started.
     */
    public void waitUntilStarted() {
        mGLHandlerThread.waitUntilStarted();
    }

    /**
     * Quit the thread.
     *
     * <p>
     * No further methods can be called after this.
     * </p>
     */
    public void quit() {
        Handler handler = mGLHandlerThread.getHandler();
        handler.sendMessageAtFrontOfQueue(handler.obtainMessage(MSG_CLEANUP));
        mGLHandlerThread.quitSafely();
        try {
            mGLHandlerThread.join();
        } catch (InterruptedException e) {
            Log.e(TAG, String.format("Thread %s (%d) interrupted while quitting.",
                    mGLHandlerThread.getName(), mGLHandlerThread.getId()));
        }
    }

    /**
     * Queue a new call to draw into the surfaces specified in the next available preview
     * request from the {@link CaptureCollector} passed to
     * {@link #setConfigurationAndWait(java.util.Collection, CaptureCollector)};
     */
    public void queueNewFrame() {
        Handler handler = mGLHandlerThread.getHandler();

        /**
         * Avoid queuing more than one new frame.  If we are not consuming faster than frames
         * are produced, drop frames rather than allowing the queue to back up.
         */
        if (!handler.hasMessages(MSG_NEW_FRAME)) {
            handler.sendMessage(handler.obtainMessage(MSG_NEW_FRAME));
        } else {
            Log.e(TAG, "GLThread dropping frame.  Not consuming frames quickly enough!");
        }
    }

    /**
     * Configure the GL renderer for the given set of output surfaces, and block until
     * this configuration has been applied.
     *
     * @param surfaces a collection of pairs of {@link android.view.Surface}s and their
     *                 corresponding sizes to configure.
     * @param collector a {@link CaptureCollector} to retrieve requests from.
     */
    public void setConfigurationAndWait(Collection<Pair<Surface, Size>> surfaces,
                                        CaptureCollector collector) {
        checkNotNull(collector, "collector must not be null");
        Handler handler = mGLHandlerThread.getHandler();

        final ConditionVariable condition = new ConditionVariable(/*closed*/false);
        ConfigureHolder configure = new ConfigureHolder(condition, surfaces, collector);

        Message m = handler.obtainMessage(MSG_NEW_CONFIGURATION, /*arg1*/0, /*arg2*/0, configure);
        handler.sendMessage(m);

        // Block until configuration applied.
        condition.block();
    }

    /**
     * Get the underlying surface to produce frames from.
     *
     * <p>
     * This returns the surface that is drawn into the set of surfaces passed in for each frame.
     * This method should only be called after a call to
     * {@link #setConfigurationAndWait(java.util.Collection)}.  Calling this before the first call
     * to {@link #setConfigurationAndWait(java.util.Collection)}, after {@link #quit()}, or
     * concurrently to one of these calls may result in an invalid
     * {@link android.graphics.SurfaceTexture} being returned.
     * </p>
     *
     * @return an {@link android.graphics.SurfaceTexture} to draw to.
     */
    public SurfaceTexture getCurrentSurfaceTexture() {
        return mTextureRenderer.getSurfaceTexture();
    }

    /**
     * Ignore any subsequent calls to {@link #queueNewFrame(java.util.Collection)}.
     */
    public void ignoreNewFrames() {
        mGLHandlerThread.getHandler().sendEmptyMessage(MSG_DROP_FRAMES);
    }

    /**
     * Wait until no messages are queued.
     */
    public void waitUntilIdle() {
        mGLHandlerThread.waitUntilIdle();
    }

    /**
     * Re-enable drawing new frames after a call to {@link #ignoreNewFrames()}.
     */
    public void allowNewFrames() {
        mGLHandlerThread.getHandler().sendEmptyMessage(MSG_ALLOW_FRAMES);
    }
}
