/*
 * Copyright (C) 2011 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;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


/**
 * Encapsulates the mobile filter framework components needed to record video
 * with effects applied. Modeled after MediaRecorder.
 */
@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) // uses SurfaceTexture
public class EffectsRecorder {
    private static final String TAG = "EffectsRecorder";

    private static Class<?> sClassFilter;
    private static Method sFilterIsAvailable;
    private static EffectsRecorder sEffectsRecorder;
    // The index of the current effects recorder.
    private static int sEffectsRecorderIndex;

    private static boolean sReflectionInited = false;

    private static Class<?> sClsLearningDoneListener;
    private static Class<?> sClsOnRunnerDoneListener;
    private static Class<?> sClsOnRecordingDoneListener;
    private static Class<?> sClsSurfaceTextureSourceListener;

    private static Method sFilterSetInputValue;

    private static Constructor<?> sCtPoint;
    private static Constructor<?> sCtQuad;

    private static Method sLearningDoneListenerOnLearningDone;

    private static Method sObjectEquals;
    private static Method sObjectToString;

    private static Class<?> sClsGraphRunner;
    private static Method sGraphRunnerGetGraph;
    private static Method sGraphRunnerSetDoneCallback;
    private static Method sGraphRunnerRun;
    private static Method sGraphRunnerGetError;
    private static Method sGraphRunnerStop;

    private static Method sFilterGraphGetFilter;
    private static Method sFilterGraphTearDown;

    private static Method sOnRunnerDoneListenerOnRunnerDone;

    private static Class<?> sClsGraphEnvironment;
    private static Constructor<?> sCtGraphEnvironment;
    private static Method sGraphEnvironmentCreateGLEnvironment;
    private static Method sGraphEnvironmentGetRunner;
    private static Method sGraphEnvironmentAddReferences;
    private static Method sGraphEnvironmentLoadGraph;
    private static Method sGraphEnvironmentGetContext;

    private static Method sFilterContextGetGLEnvironment;
    private static Method sGLEnvironmentIsActive;
    private static Method sGLEnvironmentActivate;
    private static Method sGLEnvironmentDeactivate;
    private static Method sSurfaceTextureTargetDisconnect;
    private static Method sOnRecordingDoneListenerOnRecordingDone;
    private static Method sSurfaceTextureSourceListenerOnSurfaceTextureSourceReady;

    private Object mLearningDoneListener;
    private Object mRunnerDoneCallback;
    private Object mSourceReadyCallback;
    // A callback to finalize the media after the recording is done.
    private Object mRecordingDoneListener;

    static {
        try {
            sClassFilter = Class.forName("android.filterfw.core.Filter");
            sFilterIsAvailable = sClassFilter.getMethod("isAvailable",
                    String.class);
        } catch (ClassNotFoundException ex) {
            Log.v(TAG, "Can't find the class android.filterfw.core.Filter");
        } catch (NoSuchMethodException e) {
            Log.v(TAG, "Can't find the method Filter.isAvailable");
        }
    }

    public static final int  EFFECT_NONE        = 0;
    public static final int  EFFECT_GOOFY_FACE  = 1;
    public static final int  EFFECT_BACKDROPPER = 2;

    public static final int  EFFECT_GF_SQUEEZE     = 0;
    public static final int  EFFECT_GF_BIG_EYES    = 1;
    public static final int  EFFECT_GF_BIG_MOUTH   = 2;
    public static final int  EFFECT_GF_SMALL_MOUTH = 3;
    public static final int  EFFECT_GF_BIG_NOSE    = 4;
    public static final int  EFFECT_GF_SMALL_EYES  = 5;
    public static final int  NUM_OF_GF_EFFECTS = EFFECT_GF_SMALL_EYES + 1;

    public static final int  EFFECT_MSG_STARTED_LEARNING = 0;
    public static final int  EFFECT_MSG_DONE_LEARNING    = 1;
    public static final int  EFFECT_MSG_SWITCHING_EFFECT = 2;
    public static final int  EFFECT_MSG_EFFECTS_STOPPED  = 3;
    public static final int  EFFECT_MSG_RECORDING_DONE   = 4;
    public static final int  EFFECT_MSG_PREVIEW_RUNNING  = 5;

    private Context mContext;
    private Handler mHandler;

    private CameraManager.CameraProxy mCameraDevice;
    private CamcorderProfile mProfile;
    private double mCaptureRate = 0;
    private SurfaceTexture mPreviewSurfaceTexture;
    private int mPreviewWidth;
    private int mPreviewHeight;
    private MediaRecorder.OnInfoListener mInfoListener;
    private MediaRecorder.OnErrorListener mErrorListener;

    private String mOutputFile;
    private FileDescriptor mFd;
    private int mOrientationHint = 0;
    private long mMaxFileSize = 0;
    private int mMaxDurationMs = 0;
    private int mCameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
    private int mCameraDisplayOrientation;

    private int mEffect = EFFECT_NONE;
    private int mCurrentEffect = EFFECT_NONE;
    private EffectsListener mEffectsListener;

    private Object mEffectParameter;

    private Object mGraphEnv;
    private int mGraphId;
    private Object mRunner = null;
    private Object mOldRunner = null;

    private SurfaceTexture mTextureSource;

    private static final int STATE_CONFIGURE              = 0;
    private static final int STATE_WAITING_FOR_SURFACE    = 1;
    private static final int STATE_STARTING_PREVIEW       = 2;
    private static final int STATE_PREVIEW                = 3;
    private static final int STATE_RECORD                 = 4;
    private static final int STATE_RELEASED               = 5;
    private int mState = STATE_CONFIGURE;

    private boolean mLogVerbose = Log.isLoggable(TAG, Log.VERBOSE);
    private SoundClips.Player mSoundPlayer;

    /** Determine if a given effect is supported at runtime
     * Some effects require libraries not available on all devices
     */
    public static boolean isEffectSupported(int effectId) {
        if (sFilterIsAvailable == null)  return false;

        try {
            switch (effectId) {
                case EFFECT_GOOFY_FACE:
                    return (Boolean) sFilterIsAvailable.invoke(null,
                            "com.google.android.filterpacks.facedetect.GoofyRenderFilter");
                case EFFECT_BACKDROPPER:
                    return (Boolean) sFilterIsAvailable.invoke(null,
                            "android.filterpacks.videoproc.BackDropperFilter");
                default:
                    return false;
            }
        } catch (Exception ex) {
            Log.e(TAG, "Fail to check filter", ex);
        }
        return false;
    }

    public EffectsRecorder(Context context) {
        if (mLogVerbose) Log.v(TAG, "EffectsRecorder created (" + this + ")");

        if (!sReflectionInited) {
            try {
                sFilterSetInputValue = sClassFilter.getMethod("setInputValue",
                        new Class[] {String.class, Object.class});

                Class<?> clsPoint = Class.forName("android.filterfw.geometry.Point");
                sCtPoint = clsPoint.getConstructor(new Class[] {float.class,
                        float.class});

                Class<?> clsQuad = Class.forName("android.filterfw.geometry.Quad");
                sCtQuad = clsQuad.getConstructor(new Class[] {clsPoint, clsPoint,
                        clsPoint, clsPoint});

                Class<?> clsBackDropperFilter = Class.forName(
                        "android.filterpacks.videoproc.BackDropperFilter");
                sClsLearningDoneListener = Class.forName(
                        "android.filterpacks.videoproc.BackDropperFilter$LearningDoneListener");
                sLearningDoneListenerOnLearningDone = sClsLearningDoneListener
                        .getMethod("onLearningDone", new Class[] {clsBackDropperFilter});

                sObjectEquals = Object.class.getMethod("equals", new Class[] {Object.class});
                sObjectToString = Object.class.getMethod("toString");

                sClsOnRunnerDoneListener = Class.forName(
                        "android.filterfw.core.GraphRunner$OnRunnerDoneListener");
                sOnRunnerDoneListenerOnRunnerDone = sClsOnRunnerDoneListener.getMethod(
                        "onRunnerDone", new Class[] {int.class});

                sClsGraphRunner = Class.forName("android.filterfw.core.GraphRunner");
                sGraphRunnerGetGraph = sClsGraphRunner.getMethod("getGraph");
                sGraphRunnerSetDoneCallback = sClsGraphRunner.getMethod(
                        "setDoneCallback", new Class[] {sClsOnRunnerDoneListener});
                sGraphRunnerRun = sClsGraphRunner.getMethod("run");
                sGraphRunnerGetError = sClsGraphRunner.getMethod("getError");
                sGraphRunnerStop = sClsGraphRunner.getMethod("stop");

                Class<?> clsFilterContext = Class.forName("android.filterfw.core.FilterContext");
                sFilterContextGetGLEnvironment = clsFilterContext.getMethod(
                        "getGLEnvironment");

                Class<?> clsFilterGraph = Class.forName("android.filterfw.core.FilterGraph");
                sFilterGraphGetFilter = clsFilterGraph.getMethod("getFilter",
                        new Class[] {String.class});
                sFilterGraphTearDown = clsFilterGraph.getMethod("tearDown",
                        new Class[] {clsFilterContext});

                sClsGraphEnvironment = Class.forName("android.filterfw.GraphEnvironment");
                sCtGraphEnvironment = sClsGraphEnvironment.getConstructor();
                sGraphEnvironmentCreateGLEnvironment = sClsGraphEnvironment.getMethod(
                        "createGLEnvironment");
                sGraphEnvironmentGetRunner = sClsGraphEnvironment.getMethod(
                        "getRunner", new Class[] {int.class, int.class});
                sGraphEnvironmentAddReferences = sClsGraphEnvironment.getMethod(
                        "addReferences", new Class[] {Object[].class});
                sGraphEnvironmentLoadGraph = sClsGraphEnvironment.getMethod(
                        "loadGraph", new Class[] {Context.class, int.class});
                sGraphEnvironmentGetContext = sClsGraphEnvironment.getMethod(
                        "getContext");

                Class<?> clsGLEnvironment = Class.forName("android.filterfw.core.GLEnvironment");
                sGLEnvironmentIsActive = clsGLEnvironment.getMethod("isActive");
                sGLEnvironmentActivate = clsGLEnvironment.getMethod("activate");
                sGLEnvironmentDeactivate = clsGLEnvironment.getMethod("deactivate");

                Class<?> clsSurfaceTextureTarget = Class.forName(
                        "android.filterpacks.videosrc.SurfaceTextureTarget");
                sSurfaceTextureTargetDisconnect = clsSurfaceTextureTarget.getMethod(
                        "disconnect", new Class[] {clsFilterContext});

                sClsOnRecordingDoneListener = Class.forName(
                        "android.filterpacks.videosink.MediaEncoderFilter$OnRecordingDoneListener");
                sOnRecordingDoneListenerOnRecordingDone =
                        sClsOnRecordingDoneListener.getMethod("onRecordingDone");

                sClsSurfaceTextureSourceListener = Class.forName(
                        "android.filterpacks.videosrc.SurfaceTextureSource$SurfaceTextureSourceListener");
                sSurfaceTextureSourceListenerOnSurfaceTextureSourceReady =
                        sClsSurfaceTextureSourceListener.getMethod(
                                "onSurfaceTextureSourceReady",
                                new Class[] {SurfaceTexture.class});
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }

            sReflectionInited = true;
        }

        sEffectsRecorderIndex++;
        Log.v(TAG, "Current effects recorder index is " + sEffectsRecorderIndex);
        sEffectsRecorder = this;
        SerializableInvocationHandler sih = new SerializableInvocationHandler(
                sEffectsRecorderIndex);
        mLearningDoneListener = Proxy.newProxyInstance(
                sClsLearningDoneListener.getClassLoader(),
                new Class[] {sClsLearningDoneListener}, sih);
        mRunnerDoneCallback = Proxy.newProxyInstance(
                sClsOnRunnerDoneListener.getClassLoader(),
                new Class[] {sClsOnRunnerDoneListener}, sih);
        mSourceReadyCallback = Proxy.newProxyInstance(
                sClsSurfaceTextureSourceListener.getClassLoader(),
                new Class[] {sClsSurfaceTextureSourceListener}, sih);
        mRecordingDoneListener =  Proxy.newProxyInstance(
                sClsOnRecordingDoneListener.getClassLoader(),
                new Class[] {sClsOnRecordingDoneListener}, sih);

        mContext = context;
        mHandler = new Handler(Looper.getMainLooper());
        mSoundPlayer = SoundClips.getPlayer(context);
    }

    public synchronized void setCamera(CameraManager.CameraProxy cameraDevice) {
        switch (mState) {
            case STATE_PREVIEW:
                throw new RuntimeException("setCamera cannot be called while previewing!");
            case STATE_RECORD:
                throw new RuntimeException("setCamera cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException("setCamera called on an already released recorder!");
            default:
                break;
        }

        mCameraDevice = cameraDevice;
    }

    public void setProfile(CamcorderProfile profile) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setProfile cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException("setProfile called on an already released recorder!");
            default:
                break;
        }
        mProfile = profile;
    }

    public void setOutputFile(String outputFile) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setOutputFile cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException("setOutputFile called on an already released recorder!");
            default:
                break;
        }

        mOutputFile = outputFile;
        mFd = null;
    }

    public void setOutputFile(FileDescriptor fd) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setOutputFile cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException("setOutputFile called on an already released recorder!");
            default:
                break;
        }

        mOutputFile = null;
        mFd = fd;
    }

    /**
     * Sets the maximum filesize (in bytes) of the recording session.
     * This will be passed on to the MediaEncoderFilter and then to the
     * MediaRecorder ultimately. If zero or negative, the MediaRecorder will
     * disable the limit
    */
    public synchronized void setMaxFileSize(long maxFileSize) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setMaxFileSize cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setMaxFileSize called on an already released recorder!");
            default:
                break;
        }
        mMaxFileSize = maxFileSize;
    }

    /**
    * Sets the maximum recording duration (in ms) for the next recording session
    * Setting it to zero (the default) disables the limit.
    */
    public synchronized void setMaxDuration(int maxDurationMs) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setMaxDuration cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setMaxDuration called on an already released recorder!");
            default:
                break;
        }
        mMaxDurationMs = maxDurationMs;
    }


    public void setCaptureRate(double fps) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setCaptureRate cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setCaptureRate called on an already released recorder!");
            default:
                break;
        }

        if (mLogVerbose) Log.v(TAG, "Setting time lapse capture rate to " + fps + " fps");
        mCaptureRate = fps;
    }

    public void setPreviewSurfaceTexture(SurfaceTexture previewSurfaceTexture,
                                  int previewWidth,
                                  int previewHeight) {
        if (mLogVerbose) Log.v(TAG, "setPreviewSurfaceTexture(" + this + ")");
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException(
                    "setPreviewSurfaceTexture cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setPreviewSurfaceTexture called on an already released recorder!");
            default:
                break;
        }

        mPreviewSurfaceTexture = previewSurfaceTexture;
        mPreviewWidth = previewWidth;
        mPreviewHeight = previewHeight;

        switch (mState) {
            case STATE_WAITING_FOR_SURFACE:
                startPreview();
                break;
            case STATE_STARTING_PREVIEW:
            case STATE_PREVIEW:
                initializeEffect(true);
                break;
        }
    }

    public void setEffect(int effect, Object effectParameter) {
        if (mLogVerbose) Log.v(TAG,
                               "setEffect: effect ID " + effect +
                               ", parameter " + effectParameter.toString());
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setEffect cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException("setEffect called on an already released recorder!");
            default:
                break;
        }

        mEffect = effect;
        mEffectParameter = effectParameter;

        if (mState == STATE_PREVIEW ||
                mState == STATE_STARTING_PREVIEW) {
            initializeEffect(false);
        }
    }

    public interface EffectsListener {
        public void onEffectsUpdate(int effectId, int effectMsg);
        public void onEffectsError(Exception exception, String filePath);
    }

    public void setEffectsListener(EffectsListener listener) {
        mEffectsListener = listener;
    }

    private void setFaceDetectOrientation() {
        if (mCurrentEffect == EFFECT_GOOFY_FACE) {
            Object rotateFilter = getGraphFilter(mRunner, "rotate");
            Object metaRotateFilter = getGraphFilter(mRunner, "metarotate");
            setInputValue(rotateFilter, "rotation", mOrientationHint);
            int reverseDegrees = (360 - mOrientationHint) % 360;
            setInputValue(metaRotateFilter, "rotation", reverseDegrees);
        }
    }

    private void setRecordingOrientation() {
        if (mState != STATE_RECORD && mRunner != null) {
            Object bl = newInstance(sCtPoint, new Object[] {0, 0});
            Object br = newInstance(sCtPoint, new Object[] {1, 0});
            Object tl = newInstance(sCtPoint, new Object[] {0, 1});
            Object tr = newInstance(sCtPoint, new Object[] {1, 1});
            Object recordingRegion;
            if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                // The back camera is not mirrored, so use a identity transform
                recordingRegion = newInstance(sCtQuad, new Object[] {bl, br, tl, tr});
            } else {
                // Recording region needs to be tweaked for front cameras, since they
                // mirror their preview
                if (mOrientationHint == 0 || mOrientationHint == 180) {
                    // Horizontal flip in landscape
                    recordingRegion = newInstance(sCtQuad, new Object[] {br, bl, tr, tl});
                } else {
                    // Horizontal flip in portrait
                    recordingRegion = newInstance(sCtQuad, new Object[] {tl, tr, bl, br});
                }
            }
            Object recorder = getGraphFilter(mRunner, "recorder");
            setInputValue(recorder, "inputRegion", recordingRegion);
        }
    }
    public void setOrientationHint(int degrees) {
        switch (mState) {
            case STATE_RELEASED:
                throw new RuntimeException(
                        "setOrientationHint called on an already released recorder!");
            default:
                break;
        }
        if (mLogVerbose) Log.v(TAG, "Setting orientation hint to: " + degrees);
        mOrientationHint = degrees;
        setFaceDetectOrientation();
        setRecordingOrientation();
    }

    public void setCameraDisplayOrientation(int orientation) {
        if (mState != STATE_CONFIGURE) {
            throw new RuntimeException(
                "setCameraDisplayOrientation called after configuration!");
        }
        mCameraDisplayOrientation = orientation;
    }

    public void setCameraFacing(int facing) {
        switch (mState) {
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setCameraFacing called on alrady released recorder!");
            default:
                break;
        }
        mCameraFacing = facing;
        setRecordingOrientation();
    }

    public void setOnInfoListener(MediaRecorder.OnInfoListener infoListener) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setInfoListener cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setInfoListener called on an already released recorder!");
            default:
                break;
        }
        mInfoListener = infoListener;
    }

    public void setOnErrorListener(MediaRecorder.OnErrorListener errorListener) {
        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("setErrorListener cannot be called while recording!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "setErrorListener called on an already released recorder!");
            default:
                break;
        }
        mErrorListener = errorListener;
    }

    private void initializeFilterFramework() {
        mGraphEnv = newInstance(sCtGraphEnvironment);
        invoke(mGraphEnv, sGraphEnvironmentCreateGLEnvironment);

        int videoFrameWidth = mProfile.videoFrameWidth;
        int videoFrameHeight = mProfile.videoFrameHeight;
        if (mCameraDisplayOrientation == 90 || mCameraDisplayOrientation == 270) {
            int tmp = videoFrameWidth;
            videoFrameWidth = videoFrameHeight;
            videoFrameHeight = tmp;
        }

        invoke(mGraphEnv, sGraphEnvironmentAddReferences,
                new Object[] {new Object[] {
                "textureSourceCallback", mSourceReadyCallback,
                "recordingWidth", videoFrameWidth,
                "recordingHeight", videoFrameHeight,
                "recordingProfile", mProfile,
                "learningDoneListener", mLearningDoneListener,
                "recordingDoneListener", mRecordingDoneListener}});
        mRunner = null;
        mGraphId = -1;
        mCurrentEffect = EFFECT_NONE;
    }

    private synchronized void initializeEffect(boolean forceReset) {
        if (forceReset ||
            mCurrentEffect != mEffect ||
            mCurrentEffect == EFFECT_BACKDROPPER) {

            invoke(mGraphEnv, sGraphEnvironmentAddReferences,
                    new Object[] {new Object[] {
                    "previewSurfaceTexture", mPreviewSurfaceTexture,
                    "previewWidth", mPreviewWidth,
                    "previewHeight", mPreviewHeight,
                    "orientation", mOrientationHint}});
            if (mState == STATE_PREVIEW ||
                    mState == STATE_STARTING_PREVIEW) {
                // Switching effects while running. Inform video camera.
                sendMessage(mCurrentEffect, EFFECT_MSG_SWITCHING_EFFECT);
            }

            switch (mEffect) {
                case EFFECT_GOOFY_FACE:
                    mGraphId = (Integer) invoke(mGraphEnv,
                            sGraphEnvironmentLoadGraph,
                            new Object[] {mContext, R.raw.goofy_face});
                    break;
                case EFFECT_BACKDROPPER:
                    sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_STARTED_LEARNING);
                    mGraphId = (Integer) invoke(mGraphEnv,
                            sGraphEnvironmentLoadGraph,
                            new Object[] {mContext, R.raw.backdropper});
                    break;
                default:
                    throw new RuntimeException("Unknown effect ID" + mEffect + "!");
            }
            mCurrentEffect = mEffect;

            mOldRunner = mRunner;
            mRunner = invoke(mGraphEnv, sGraphEnvironmentGetRunner,
                    new Object[] {mGraphId,
                    getConstant(sClsGraphEnvironment, "MODE_ASYNCHRONOUS")});
            invoke(mRunner, sGraphRunnerSetDoneCallback, new Object[] {mRunnerDoneCallback});
            if (mLogVerbose) {
                Log.v(TAG, "New runner: " + mRunner
                      + ". Old runner: " + mOldRunner);
            }
            if (mState == STATE_PREVIEW ||
                    mState == STATE_STARTING_PREVIEW) {
                // Switching effects while running. Stop existing runner.
                // The stop callback will take care of starting new runner.
                mCameraDevice.stopPreview();
                mCameraDevice.setPreviewTextureAsync(null);
                invoke(mOldRunner, sGraphRunnerStop);
            }
        }

        switch (mCurrentEffect) {
            case EFFECT_GOOFY_FACE:
                tryEnableVideoStabilization(true);
                Object goofyFilter = getGraphFilter(mRunner, "goofyrenderer");
                setInputValue(goofyFilter, "currentEffect",
                        ((Integer) mEffectParameter).intValue());
                break;
            case EFFECT_BACKDROPPER:
                tryEnableVideoStabilization(false);
                Object backgroundSrc = getGraphFilter(mRunner, "background");
                if (ApiHelper.HAS_EFFECTS_RECORDING_CONTEXT_INPUT) {
                    // Set the context first before setting sourceUrl to
                    // guarantee the content URI get resolved properly.
                    setInputValue(backgroundSrc, "context", mContext);
                }
                setInputValue(backgroundSrc, "sourceUrl", mEffectParameter);
                // For front camera, the background video needs to be mirrored in the
                // backdropper filter
                if (mCameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    Object replacer = getGraphFilter(mRunner, "replacer");
                    setInputValue(replacer, "mirrorBg", true);
                    if (mLogVerbose) Log.v(TAG, "Setting the background to be mirrored");
                }
                break;
            default:
                break;
        }
        setFaceDetectOrientation();
        setRecordingOrientation();
    }

    public synchronized void startPreview() {
        if (mLogVerbose) Log.v(TAG, "Starting preview (" + this + ")");

        switch (mState) {
            case STATE_STARTING_PREVIEW:
            case STATE_PREVIEW:
                // Already running preview
                Log.w(TAG, "startPreview called when already running preview");
                return;
            case STATE_RECORD:
                throw new RuntimeException("Cannot start preview when already recording!");
            case STATE_RELEASED:
                throw new RuntimeException("setEffect called on an already released recorder!");
            default:
                break;
        }

        if (mEffect == EFFECT_NONE) {
            throw new RuntimeException("No effect selected!");
        }
        if (mEffectParameter == null) {
            throw new RuntimeException("No effect parameter provided!");
        }
        if (mProfile == null) {
            throw new RuntimeException("No recording profile provided!");
        }
        if (mPreviewSurfaceTexture == null) {
            if (mLogVerbose) Log.v(TAG, "Passed a null surface; waiting for valid one");
            mState = STATE_WAITING_FOR_SURFACE;
            return;
        }
        if (mCameraDevice == null) {
            throw new RuntimeException("No camera to record from!");
        }

        if (mLogVerbose) Log.v(TAG, "Initializing filter framework and running the graph.");
        initializeFilterFramework();

        initializeEffect(true);

        mState = STATE_STARTING_PREVIEW;
        invoke(mRunner, sGraphRunnerRun);
        // Rest of preview startup handled in mSourceReadyCallback
    }

    private Object invokeObjectEquals(Object proxy, Object[] args) {
        return Boolean.valueOf(proxy == args[0]);
    }

    private Object invokeObjectToString() {
        return "Proxy-" + toString();
    }

    private void invokeOnLearningDone() {
        if (mLogVerbose) Log.v(TAG, "Learning done callback triggered");
        // Called in a processing thread, so have to post message back to UI
        // thread
        sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_DONE_LEARNING);
        enable3ALocks(true);
    }

    private void invokeOnRunnerDone(Object[] args) {
        int runnerDoneResult = (Integer) args[0];
        synchronized (EffectsRecorder.this) {
            if (mLogVerbose) {
                Log.v(TAG,
                      "Graph runner done (" + EffectsRecorder.this
                      + ", mRunner " + mRunner
                      + ", mOldRunner " + mOldRunner + ")");
            }
            if (runnerDoneResult ==
                    (Integer) getConstant(sClsGraphRunner, "RESULT_ERROR")) {
                // Handle error case
                Log.e(TAG, "Error running filter graph!");
                Exception e = null;
                if (mRunner != null) {
                    e = (Exception) invoke(mRunner, sGraphRunnerGetError);
                } else if (mOldRunner != null) {
                    e = (Exception) invoke(mOldRunner, sGraphRunnerGetError);
                }
                raiseError(e);
            }
            if (mOldRunner != null) {
                // Tear down old graph if available
                if (mLogVerbose) Log.v(TAG, "Tearing down old graph.");
                Object glEnv = getContextGLEnvironment(mGraphEnv);
                if (glEnv != null && !(Boolean) invoke(glEnv, sGLEnvironmentIsActive)) {
                    invoke(glEnv, sGLEnvironmentActivate);
                }
                getGraphTearDown(mOldRunner,
                        invoke(mGraphEnv, sGraphEnvironmentGetContext));
                if (glEnv != null && (Boolean) invoke(glEnv, sGLEnvironmentIsActive)) {
                    invoke(glEnv, sGLEnvironmentDeactivate);
                }
                mOldRunner = null;
            }
            if (mState == STATE_PREVIEW ||
                    mState == STATE_STARTING_PREVIEW) {
                // Switching effects, start up the new runner
                if (mLogVerbose) {
                    Log.v(TAG, "Previous effect halted. Running graph again. state: "
                            + mState);
                }
                tryEnable3ALocks(false);
                // In case of an error, the graph restarts from beginning and in case
                // of the BACKDROPPER effect, the learner re-learns the background.
                // Hence, we need to show the learning dialogue to the user
                // to avoid recording before the learning is done. Else, the user
                // could start recording before the learning is done and the new
                // background comes up later leading to an end result video
                // with a heterogeneous background.
                // For BACKDROPPER effect, this path is also executed sometimes at
                // the end of a normal recording session. In such a case, the graph
                // does not restart and hence the learner does not re-learn. So we
                // do not want to show the learning dialogue then.
                if (runnerDoneResult == (Integer) getConstant(
                        sClsGraphRunner, "RESULT_ERROR")
                        && mCurrentEffect == EFFECT_BACKDROPPER) {
                    sendMessage(EFFECT_BACKDROPPER, EFFECT_MSG_STARTED_LEARNING);
                }
                invoke(mRunner, sGraphRunnerRun);
            } else if (mState != STATE_RELEASED) {
                // Shutting down effects
                if (mLogVerbose) Log.v(TAG, "Runner halted, restoring direct preview");
                tryEnable3ALocks(false);
                sendMessage(EFFECT_NONE, EFFECT_MSG_EFFECTS_STOPPED);
            } else {
                // STATE_RELEASED - camera will be/has been released as well, do nothing.
            }
        }
    }

    private void invokeOnSurfaceTextureSourceReady(Object[] args) {
        SurfaceTexture source = (SurfaceTexture) args[0];
        if (mLogVerbose) Log.v(TAG, "SurfaceTexture ready callback received");
        synchronized (EffectsRecorder.this) {
            mTextureSource = source;

            if (mState == STATE_CONFIGURE) {
                // Stop preview happened while the runner was doing startup tasks
                // Since we haven't started anything up, don't do anything
                // Rest of cleanup will happen in onRunnerDone
                if (mLogVerbose) Log.v(TAG, "Ready callback: Already stopped, skipping.");
                return;
            }
            if (mState == STATE_RELEASED) {
                // EffectsRecorder has been released, so don't touch the camera device
                // or anything else
                if (mLogVerbose) Log.v(TAG, "Ready callback: Already released, skipping.");
                return;
            }
            if (source == null) {
                if (mLogVerbose) {
                    Log.v(TAG, "Ready callback: source null! Looks like graph was closed!");
                }
                if (mState == STATE_PREVIEW ||
                        mState == STATE_STARTING_PREVIEW ||
                        mState == STATE_RECORD) {
                    // A null source here means the graph is shutting down
                    // unexpectedly, so we need to turn off preview before
                    // the surface texture goes away.
                    if (mLogVerbose) {
                        Log.v(TAG, "Ready callback: State: " + mState
                                + ". stopCameraPreview");
                    }

                    stopCameraPreview();
                }
                return;
            }

            // Lock AE/AWB to reduce transition flicker
            tryEnable3ALocks(true);

            mCameraDevice.stopPreview();
            if (mLogVerbose) Log.v(TAG, "Runner active, connecting effects preview");
            mCameraDevice.setPreviewTextureAsync(mTextureSource);

            mCameraDevice.startPreviewAsync();

            // Unlock AE/AWB after preview started
            tryEnable3ALocks(false);

            mState = STATE_PREVIEW;

            if (mLogVerbose) Log.v(TAG, "Start preview/effect switch complete");

            // Sending a message to listener that preview is complete
            sendMessage(mCurrentEffect, EFFECT_MSG_PREVIEW_RUNNING);
        }
    }

    private void invokeOnRecordingDone() {
        // Forward the callback to the VideoModule object (as an asynchronous event).
        if (mLogVerbose) Log.v(TAG, "Recording done callback triggered");
        sendMessage(EFFECT_NONE, EFFECT_MSG_RECORDING_DONE);
    }

    public synchronized void startRecording() {
        if (mLogVerbose) Log.v(TAG, "Starting recording (" + this + ")");

        switch (mState) {
            case STATE_RECORD:
                throw new RuntimeException("Already recording, cannot begin anew!");
            case STATE_RELEASED:
                throw new RuntimeException(
                    "startRecording called on an already released recorder!");
            default:
                break;
        }

        if ((mOutputFile == null) && (mFd == null)) {
            throw new RuntimeException("No output file name or descriptor provided!");
        }

        if (mState == STATE_CONFIGURE) {
            startPreview();
        }

        Object recorder = getGraphFilter(mRunner, "recorder");
        if (mFd != null) {
            setInputValue(recorder, "outputFileDescriptor", mFd);
        } else {
            setInputValue(recorder, "outputFile", mOutputFile);
        }
        // It is ok to set the audiosource without checking for timelapse here
        // since that check will be done in the MediaEncoderFilter itself
        setInputValue(recorder, "audioSource", MediaRecorder.AudioSource.CAMCORDER);
        setInputValue(recorder, "recordingProfile", mProfile);
        setInputValue(recorder, "orientationHint", mOrientationHint);
        // Important to set the timelapseinterval to 0 if the capture rate is not >0
        // since the recorder does not get created every time the recording starts.
        // The recorder infers whether the capture is timelapsed based on the value of
        // this interval
        boolean captureTimeLapse = mCaptureRate > 0;
        if (captureTimeLapse) {
            double timeBetweenFrameCapture = 1 / mCaptureRate;
            setInputValue(recorder, "timelapseRecordingIntervalUs",
                    (long) (1000000 * timeBetweenFrameCapture));

        } else {
            setInputValue(recorder, "timelapseRecordingIntervalUs", 0L);
        }

        if (mInfoListener != null) {
            setInputValue(recorder, "infoListener", mInfoListener);
        }
        if (mErrorListener != null) {
            setInputValue(recorder, "errorListener", mErrorListener);
        }
        setInputValue(recorder, "maxFileSize", mMaxFileSize);
        setInputValue(recorder, "maxDurationMs", mMaxDurationMs);
        setInputValue(recorder, "recording", true);
        mSoundPlayer.play(SoundClips.START_VIDEO_RECORDING);
        mState = STATE_RECORD;
    }

    public synchronized void stopRecording() {
        if (mLogVerbose) Log.v(TAG, "Stop recording (" + this + ")");

        switch (mState) {
            case STATE_CONFIGURE:
            case STATE_STARTING_PREVIEW:
            case STATE_PREVIEW:
                Log.w(TAG, "StopRecording called when recording not active!");
                return;
            case STATE_RELEASED:
                throw new RuntimeException("stopRecording called on released EffectsRecorder!");
            default:
                break;
        }
        Object recorder = getGraphFilter(mRunner, "recorder");
        setInputValue(recorder, "recording", false);
        mSoundPlayer.play(SoundClips.STOP_VIDEO_RECORDING);
        mState = STATE_PREVIEW;
    }

    // Called to tell the filter graph that the display surfacetexture is not valid anymore.
    // So the filter graph should not hold any reference to the surface created with that.
    public synchronized void disconnectDisplay() {
        if (mLogVerbose) Log.v(TAG, "Disconnecting the graph from the " +
            "SurfaceTexture");
        Object display = getGraphFilter(mRunner, "display");
        invoke(display, sSurfaceTextureTargetDisconnect, new Object[] {
                invoke(mGraphEnv, sGraphEnvironmentGetContext)});
    }

    // The VideoModule will call this to notify that the camera is being
    // released to the outside world. This call should happen after the
    // stopRecording call. Else, the effects may throw an exception.
    // With the recording stopped, the stopPreview call will not try to
    // release the camera again.
    // This must be called in onPause() if the effects are ON.
    public synchronized void disconnectCamera() {
        if (mLogVerbose) Log.v(TAG, "Disconnecting the effects from Camera");
        stopCameraPreview();
        mCameraDevice = null;
    }

    // In a normal case, when the disconnect is not called, we should not
    // set the camera device to null, since on return callback, we try to
    // enable 3A locks, which need the cameradevice.
    public synchronized void stopCameraPreview() {
        if (mLogVerbose) Log.v(TAG, "Stopping camera preview.");
        if (mCameraDevice == null) {
            Log.d(TAG, "Camera already null. Nothing to disconnect");
            return;
        }
        mCameraDevice.stopPreview();
        mCameraDevice.setPreviewTextureAsync(null);
    }

    // Stop and release effect resources
    public synchronized void stopPreview() {
        if (mLogVerbose) Log.v(TAG, "Stopping preview (" + this + ")");
        switch (mState) {
            case STATE_CONFIGURE:
                Log.w(TAG, "StopPreview called when preview not active!");
                return;
            case STATE_RELEASED:
                throw new RuntimeException("stopPreview called on released EffectsRecorder!");
            default:
                break;
        }

        if (mState == STATE_RECORD) {
            stopRecording();
        }

        mCurrentEffect = EFFECT_NONE;

        // This will not do anything if the camera has already been disconnected.
        stopCameraPreview();

        mState = STATE_CONFIGURE;
        mOldRunner = mRunner;
        invoke(mRunner, sGraphRunnerStop);
        mRunner = null;
        // Rest of stop and release handled in mRunnerDoneCallback
    }

    // Try to enable/disable video stabilization if supported; otherwise return false
    // It is called from a synchronized block.
    boolean tryEnableVideoStabilization(boolean toggle) {
        if (mLogVerbose) Log.v(TAG, "tryEnableVideoStabilization.");
        if (mCameraDevice == null) {
            Log.d(TAG, "Camera already null. Not enabling video stabilization.");
            return false;
        }
        Camera.Parameters params = mCameraDevice.getParameters();

        String vstabSupported = params.get("video-stabilization-supported");
        if ("true".equals(vstabSupported)) {
            if (mLogVerbose) Log.v(TAG, "Setting video stabilization to " + toggle);
            params.set("video-stabilization", toggle ? "true" : "false");
            mCameraDevice.setParameters(params);
            return true;
        }
        if (mLogVerbose) Log.v(TAG, "Video stabilization not supported");
        return false;
    }

    // Try to enable/disable 3A locks if supported; otherwise return false
    @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
    synchronized boolean tryEnable3ALocks(boolean toggle) {
        if (mLogVerbose) Log.v(TAG, "tryEnable3ALocks");
        if (mCameraDevice == null) {
            Log.d(TAG, "Camera already null. Not tryenabling 3A locks.");
            return false;
        }
        Camera.Parameters params = mCameraDevice.getParameters();
        if (Util.isAutoExposureLockSupported(params) &&
            Util.isAutoWhiteBalanceLockSupported(params)) {
            params.setAutoExposureLock(toggle);
            params.setAutoWhiteBalanceLock(toggle);
            mCameraDevice.setParameters(params);
            return true;
        }
        return false;
    }

    // Try to enable/disable 3A locks if supported; otherwise, throw error
    // Use this when locks are essential to success
    synchronized void enable3ALocks(boolean toggle) {
        if (mLogVerbose) Log.v(TAG, "Enable3ALocks");
        if (mCameraDevice == null) {
            Log.d(TAG, "Camera already null. Not enabling 3A locks.");
            return;
        }
        Camera.Parameters params = mCameraDevice.getParameters();
        if (!tryEnable3ALocks(toggle)) {
            throw new RuntimeException("Attempt to lock 3A on camera with no locking support!");
        }
    }

    static class SerializableInvocationHandler
            implements InvocationHandler, Serializable {
        private final int mEffectsRecorderIndex;
        public SerializableInvocationHandler(int index) {
            mEffectsRecorderIndex = index;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            if (sEffectsRecorder == null) return null;
            if (mEffectsRecorderIndex != sEffectsRecorderIndex) {
                Log.v(TAG, "Ignore old callback " + mEffectsRecorderIndex);
                return null;
            }
            if (method.equals(sObjectEquals)) {
                return sEffectsRecorder.invokeObjectEquals(proxy, args);
            } else if (method.equals(sObjectToString)) {
                return sEffectsRecorder.invokeObjectToString();
            } else if (method.equals(sLearningDoneListenerOnLearningDone)) {
                sEffectsRecorder.invokeOnLearningDone();
            } else if (method.equals(sOnRunnerDoneListenerOnRunnerDone)) {
                sEffectsRecorder.invokeOnRunnerDone(args);
            } else if (method.equals(
                    sSurfaceTextureSourceListenerOnSurfaceTextureSourceReady)) {
                sEffectsRecorder.invokeOnSurfaceTextureSourceReady(args);
            } else if (method.equals(sOnRecordingDoneListenerOnRecordingDone)) {
                sEffectsRecorder.invokeOnRecordingDone();
            }
            return null;
        }
    }

    // Indicates that all camera/recording activity needs to halt
    public synchronized void release() {
        if (mLogVerbose) Log.v(TAG, "Releasing (" + this + ")");

        switch (mState) {
            case STATE_RECORD:
            case STATE_STARTING_PREVIEW:
            case STATE_PREVIEW:
                stopPreview();
                // Fall-through
            default:
                if (mSoundPlayer != null) {
                    mSoundPlayer.release();
                    mSoundPlayer = null;
                }
                mState = STATE_RELEASED;
                break;
        }
        sEffectsRecorder = null;
    }

    private void sendMessage(final int effect, final int msg) {
        if (mEffectsListener != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    mEffectsListener.onEffectsUpdate(effect, msg);
                }
            });
        }
    }

    private void raiseError(final Exception exception) {
        if (mEffectsListener != null) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (mFd != null) {
                        mEffectsListener.onEffectsError(exception, null);
                    } else {
                        mEffectsListener.onEffectsError(exception, mOutputFile);
                    }
                }
            });
        }
    }

    // invoke method on receiver with no arguments
    private Object invoke(Object receiver, Method method) {
        try {
            return method.invoke(receiver);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    // invoke method on receiver with arguments
    private Object invoke(Object receiver, Method method, Object[] args) {
        try {
            return method.invoke(receiver, args);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private void setInputValue(Object receiver, String key, Object value) {
        try {
            sFilterSetInputValue.invoke(receiver, new Object[] {key, value});
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private Object newInstance(Constructor<?> ct, Object[] initArgs) {
        try {
            return ct.newInstance(initArgs);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private Object newInstance(Constructor<?> ct) {
        try {
            return ct.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private Object getGraphFilter(Object receiver, String name) {
        try {
            return sFilterGraphGetFilter.invoke(sGraphRunnerGetGraph
                    .invoke(receiver), new Object[] {name});
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private Object getContextGLEnvironment(Object receiver) {
        try {
            return sFilterContextGetGLEnvironment
                    .invoke(sGraphEnvironmentGetContext.invoke(receiver));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private void getGraphTearDown(Object receiver, Object filterContext) {
        try {
            sFilterGraphTearDown.invoke(sGraphRunnerGetGraph.invoke(receiver),
                    new Object[]{filterContext});
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private Object getConstant(Class<?> cls, String name) {
        try {
            return cls.getDeclaredField(name).get(null);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}
