/*
 * 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.testingcamera;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.ErrorCallback;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.renderscript.RenderScript;
import android.text.Layout;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.util.SparseArray;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * A simple test application for the camera API.
 *
 * The goal of this application is to allow all camera API features to be
 * exercised, and all information provided by the API to be shown.
 */
public class TestingCamera extends Activity
    implements SurfaceHolder.Callback, Camera.PreviewCallback,
        Camera.ErrorCallback {

    /** UI elements */
    private SurfaceView mPreviewView;
    private SurfaceHolder mPreviewHolder;
    private LinearLayout mPreviewColumn;

    private SurfaceView mCallbackView;
    private SurfaceHolder mCallbackHolder;

    private Spinner mCameraSpinner;
    private CheckBox mKeepOpenCheckBox;
    private Button mInfoButton;
    private Spinner mPreviewSizeSpinner;
    private Spinner mPreviewFrameRateSpinner;
    private ToggleButton mPreviewToggle;
    private ToggleButton mHDRToggle;
    private Spinner mAutofocusModeSpinner;
    private Button mAutofocusButton;
    private Button mCancelAutofocusButton;
    private TextView mFlashModeSpinnerLabel;
    private Spinner mFlashModeSpinner;
    private ToggleButton mExposureLockToggle;
    private Spinner mSnapshotSizeSpinner;
    private Button  mTakePictureButton;
    private Spinner mCamcorderProfileSpinner;
    private Spinner mVideoRecordSizeSpinner;
    private Spinner mVideoFrameRateSpinner;
    private ToggleButton mRecordToggle;
    private CheckBox mRecordHandoffCheckBox;
    private ToggleButton mRecordStabilizationToggle;
    private ToggleButton mRecordHintToggle;
    private ToggleButton mLockCameraToggle;
    private Spinner mCallbackFormatSpinner;
    private ToggleButton mCallbackToggle;
    private TextView mColorEffectSpinnerLabel;
    private Spinner mColorEffectSpinner;
    private SeekBar mZoomSeekBar;

    private TextView mLogView;

    SnapshotDialogFragment mSnapshotDialog = null;

    private Set<View> mOpenOnlyControls = new HashSet<View>();
    private Set<View> mPreviewOnlyControls = new HashSet<View>();

    private SparseArray<String> mFormatNames;

    /** Camera state */
    private int mCameraId;
    private Camera mCamera;
    private Camera.Parameters mParams;
    private List<Camera.Size> mPreviewSizes;
    private int mPreviewSize = 0;
    private List<Integer> mPreviewFrameRates;
    private int mPreviewFrameRate = 0;
    private List<Integer> mPreviewFormats;
    private int mPreviewFormat = 0;
    private List<String> mAfModes;
    private int mAfMode = 0;
    private List<String> mFlashModes;
    private int mFlashMode = 0;
    private List<Camera.Size> mSnapshotSizes;
    private int mSnapshotSize = 0;
    private List<CamcorderProfile> mCamcorderProfiles;
    private int mCamcorderProfile = 0;
    private List<Camera.Size> mVideoRecordSizes;
    private int mVideoRecordSize = 0;
    private List<Integer> mVideoFrameRates;
    private int mVideoFrameRate = 0;
    private List<String> mColorEffects;
    private int mColorEffect = 0;
    private int mZoom = 0;

    private MediaRecorder mRecorder;
    private File mRecordingFile;

    private RenderScript mRS;

    private boolean mCallbacksEnabled = false;
    private CallbackProcessor mCallbackProcessor = null;
    long mLastCallbackTimestamp = -1;
    float mCallbackAvgFrameDuration = 30;
    int mCallbackFrameCount = 0;
    private static final float MEAN_FPS_HISTORY_COEFF = 0.9f;
    private static final float MEAN_FPS_MEASUREMENT_COEFF = 0.1f;
    private static final int   FPS_REPORTING_PERIOD = 200; // frames
    private static final int CALLBACK_BUFFER_COUNT = 3;

    private static final int CAMERA_UNINITIALIZED = 0;
    private static final int CAMERA_OPEN = 1;
    private static final int CAMERA_PREVIEW = 2;
    private static final int CAMERA_TAKE_PICTURE = 3;
    private static final int CAMERA_RECORD = 4;
    private int mState = CAMERA_UNINITIALIZED;

    private static final int NO_CAMERA_ID = -1;

    /** Misc variables */

    private static final String TAG = "TestingCamera";
    private static final int PERMISSIONS_REQUEST_CAMERA = 1;
    private static final int PERMISSIONS_REQUEST_RECORDING = 2;
    static final int PERMISSIONS_REQUEST_SNAPSHOT = 3;

    /** Activity lifecycle */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        mPreviewColumn = (LinearLayout) findViewById(R.id.preview_column);

        mPreviewView = (SurfaceView) findViewById(R.id.preview);
        mPreviewView.getHolder().addCallback(this);

        mCallbackView = (SurfaceView)findViewById(R.id.callback_view);

        mCameraSpinner = (Spinner) findViewById(R.id.camera_spinner);
        mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener);

        mKeepOpenCheckBox = (CheckBox) findViewById(R.id.keep_open_checkbox);

        mInfoButton = (Button) findViewById(R.id.info_button);
        mInfoButton.setOnClickListener(mInfoButtonListener);
        mOpenOnlyControls.add(mInfoButton);

        mPreviewSizeSpinner = (Spinner) findViewById(R.id.preview_size_spinner);
        mPreviewSizeSpinner.setOnItemSelectedListener(mPreviewSizeListener);
        mOpenOnlyControls.add(mPreviewSizeSpinner);

        mPreviewFrameRateSpinner = (Spinner) findViewById(R.id.preview_frame_rate_spinner);
        mPreviewFrameRateSpinner.setOnItemSelectedListener(mPreviewFrameRateListener);
        mOpenOnlyControls.add(mPreviewFrameRateSpinner);

        mHDRToggle = (ToggleButton) findViewById(R.id.hdr_mode);
        mHDRToggle.setOnClickListener(mHDRToggleListener);
        mOpenOnlyControls.add(mHDRToggle);

        mPreviewToggle = (ToggleButton) findViewById(R.id.start_preview);
        mPreviewToggle.setOnClickListener(mPreviewToggleListener);
        mOpenOnlyControls.add(mPreviewToggle);

        mAutofocusModeSpinner = (Spinner) findViewById(R.id.af_mode_spinner);
        mAutofocusModeSpinner.setOnItemSelectedListener(mAutofocusModeListener);
        mOpenOnlyControls.add(mAutofocusModeSpinner);

        mAutofocusButton = (Button) findViewById(R.id.af_button);
        mAutofocusButton.setOnClickListener(mAutofocusButtonListener);
        mPreviewOnlyControls.add(mAutofocusButton);

        mCancelAutofocusButton = (Button) findViewById(R.id.af_cancel_button);
        mCancelAutofocusButton.setOnClickListener(mCancelAutofocusButtonListener);
        mPreviewOnlyControls.add(mCancelAutofocusButton);

        mFlashModeSpinnerLabel = (TextView) findViewById(R.id.flash_mode_spinner_label);

        mFlashModeSpinner = (Spinner) findViewById(R.id.flash_mode_spinner);
        mFlashModeSpinner.setOnItemSelectedListener(mFlashModeListener);
        mOpenOnlyControls.add(mFlashModeSpinner);

        mExposureLockToggle = (ToggleButton) findViewById(R.id.exposure_lock);
        mExposureLockToggle.setOnClickListener(mExposureLockToggleListener);
        mOpenOnlyControls.add(mExposureLockToggle);

        mZoomSeekBar = (SeekBar) findViewById(R.id.zoom_seekbar);
        mZoomSeekBar.setOnSeekBarChangeListener(mZoomSeekBarListener);

        mSnapshotSizeSpinner = (Spinner) findViewById(R.id.snapshot_size_spinner);
        mSnapshotSizeSpinner.setOnItemSelectedListener(mSnapshotSizeListener);
        mOpenOnlyControls.add(mSnapshotSizeSpinner);

        mTakePictureButton = (Button) findViewById(R.id.take_picture);
        mTakePictureButton.setOnClickListener(mTakePictureListener);
        mPreviewOnlyControls.add(mTakePictureButton);

        mCamcorderProfileSpinner = (Spinner) findViewById(R.id.camcorder_profile_spinner);
        mCamcorderProfileSpinner.setOnItemSelectedListener(mCamcorderProfileListener);
        mOpenOnlyControls.add(mCamcorderProfileSpinner);

        mVideoRecordSizeSpinner = (Spinner) findViewById(R.id.video_record_size_spinner);
        mVideoRecordSizeSpinner.setOnItemSelectedListener(mVideoRecordSizeListener);
        mOpenOnlyControls.add(mVideoRecordSizeSpinner);

        mVideoFrameRateSpinner = (Spinner) findViewById(R.id.video_frame_rate_spinner);
        mVideoFrameRateSpinner.setOnItemSelectedListener(mVideoFrameRateListener);
        mOpenOnlyControls.add(mVideoFrameRateSpinner);

        mRecordToggle = (ToggleButton) findViewById(R.id.start_record);
        mRecordToggle.setOnClickListener(mRecordToggleListener);
        mPreviewOnlyControls.add(mRecordToggle);

        mRecordHandoffCheckBox = (CheckBox) findViewById(R.id.record_handoff_checkbox);

        mRecordStabilizationToggle = (ToggleButton) findViewById(R.id.record_stabilization);
        mRecordStabilizationToggle.setOnClickListener(mRecordStabilizationToggleListener);
        mOpenOnlyControls.add(mRecordStabilizationToggle);

        mRecordHintToggle = (ToggleButton) findViewById(R.id.record_hint);
        mRecordHintToggle.setOnClickListener(mRecordHintToggleListener);
        mOpenOnlyControls.add(mRecordHintToggle);

        mLockCameraToggle = (ToggleButton) findViewById(R.id.lock_camera);
        mLockCameraToggle.setOnClickListener(mLockCameraToggleListener);
        mLockCameraToggle.setChecked(true); // ON by default
        mOpenOnlyControls.add(mLockCameraToggle);

        mCallbackFormatSpinner = (Spinner) findViewById(R.id.callback_format_spinner);
        mCallbackFormatSpinner.setOnItemSelectedListener(mCallbackFormatListener);
        mOpenOnlyControls.add(mCallbackFormatSpinner);

        mCallbackToggle = (ToggleButton) findViewById(R.id.enable_callbacks);
        mCallbackToggle.setOnClickListener(mCallbackToggleListener);
        mOpenOnlyControls.add(mCallbackToggle);

        mColorEffectSpinnerLabel = (TextView) findViewById(R.id.color_effect_spinner_label);

        mColorEffectSpinner = (Spinner) findViewById(R.id.color_effect_spinner);
        mColorEffectSpinner.setOnItemSelectedListener(mColorEffectListener);
        mOpenOnlyControls.add(mColorEffectSpinner);

        mLogView = (TextView) findViewById(R.id.log);
        mLogView.setMovementMethod(new ScrollingMovementMethod());

        mOpenOnlyControls.addAll(mPreviewOnlyControls);

        mFormatNames = new SparseArray<String>(7);
        mFormatNames.append(ImageFormat.JPEG, "JPEG");
        mFormatNames.append(ImageFormat.NV16, "NV16");
        mFormatNames.append(ImageFormat.NV21, "NV21");
        mFormatNames.append(ImageFormat.RGB_565, "RGB_565");
        mFormatNames.append(ImageFormat.UNKNOWN, "UNKNOWN");
        mFormatNames.append(ImageFormat.YUY2, "YUY2");
        mFormatNames.append(ImageFormat.YV12, "YV12");

        int numCameras = Camera.getNumberOfCameras();
        String[] cameraNames = new String[numCameras + 1];
        cameraNames[0] = "None";
        for (int i = 0; i < numCameras; i++) {
            cameraNames[i + 1] = "Camera " + i;
        }

        mCameraSpinner.setAdapter(
                new ArrayAdapter<String>(this,
                        R.layout.spinner_item, cameraNames));
        if (numCameras > 0) {
            mCameraId = 0;
            mCameraSpinner.setSelection(mCameraId + 1);
        } else {
            resetCamera();
            mCameraSpinner.setSelection(0);
        }

        mRS = RenderScript.create(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        log("onResume: Setting up");
        setUpCamera();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mState == CAMERA_RECORD) {
            stopRecording(false);
        }
        if (mKeepOpenCheckBox.isChecked()) {
            log("onPause: Not releasing camera");

            if (mState == CAMERA_PREVIEW) {
                mCamera.stopPreview();
                mState = CAMERA_OPEN;
            }
        } else {
            log("onPause: Releasing camera");

            if (mCamera != null) {
                mCamera.release();
            }
            mState = CAMERA_UNINITIALIZED;
        }
    }

    @Override
    public void onRequestPermissionsResult (int requestCode, String[] permissions,
            int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST_CAMERA) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                log("Camera permission granted");
                setUpCamera();
            } else {
                log("Camera permission denied, can't do anything");
                finish();
            }
        } else if (requestCode == PERMISSIONS_REQUEST_RECORDING) {
            mRecordToggle.setChecked(false);
            for (int i = 0; i < grantResults.length; i++) {
                if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                    log("Recording permission " + permissions[i] + " denied");
                    return;
                }
                log("Recording permissions granted");
                setUpCamera();
            }
        } else if (requestCode == PERMISSIONS_REQUEST_SNAPSHOT) {
            if (mSnapshotDialog != null) {
                mSnapshotDialog.onRequestPermissionsResult(requestCode, permissions,
                    grantResults);
            }
        }

    }

    /** SurfaceHolder.Callback methods */
    @Override
    public void surfaceChanged(SurfaceHolder holder,
            int format,
            int width,
            int height) {
        if (holder == mPreviewView.getHolder()) {
            if (mState >= CAMERA_OPEN) {
                final int previewWidth =
                        mPreviewSizes.get(mPreviewSize).width;
                final int previewHeight =
                        mPreviewSizes.get(mPreviewSize).height;

                if ( Math.abs((float)previewWidth / previewHeight -
                        (float)width/height) > 0.01f) {
                    Handler h = new Handler();
                    h.post(new Runnable() {
                        @Override
                        public void run() {
                            layoutPreview();
                        }
                    });
                }
            }

            if (mPreviewHolder != null) {
                return;
            }
            log("Surface holder available: " + width + " x " + height);
            mPreviewHolder = holder;
            try {
                if (mCamera != null) {
                    mCamera.setPreviewDisplay(holder);
                }
            } catch (IOException e) {
                logE("Unable to set up preview!");
            }
        } else if (holder == mCallbackView.getHolder()) {
            mCallbackHolder = holder;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mPreviewHolder = null;
    }

    public void setCameraDisplayOrientation() {
        android.hardware.Camera.CameraInfo info =
                new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(mCameraId, info);
        int rotation = getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0: degrees = 0; break;
            case Surface.ROTATION_90: degrees = 90; break;
            case Surface.ROTATION_180: degrees = 180; break;
            case Surface.ROTATION_270: degrees = 270; break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        log(String.format(
            "Camera sensor orientation %d, UI rotation %d, facing %s. Final orientation %d",
            info.orientation, rotation,
            info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT ? "FRONT" : "BACK",
            result));
        mCamera.setDisplayOrientation(result);
    }

    /** UI controls enable/disable for all open-only controls */
    private void enableOpenOnlyControls(boolean enabled) {
        for (View v : mOpenOnlyControls) {
                v.setEnabled(enabled);
        }
    }

    /** UI controls enable/disable for all preview-only controls */
    private void enablePreviewOnlyControls(boolean enabled) {
        for (View v : mPreviewOnlyControls) {
                v.setEnabled(enabled);
        }
    }

    /** UI listeners */

    private AdapterView.OnItemSelectedListener mCameraSpinnerListener =
                new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            int cameraId = pos - 1;
            if (mCameraId != cameraId) {
                resetCamera();
                mCameraId = cameraId;
                mPreviewToggle.setChecked(false);
                setUpCamera();
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private OnClickListener mInfoButtonListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mCameraId != NO_CAMERA_ID) {
                FragmentManager fm = getFragmentManager();
                InfoDialogFragment infoDialog = new InfoDialogFragment();
                infoDialog.updateInfo(mCameraId, mCamera);
                infoDialog.show(fm, "info_dialog_fragment");
            }
        }
    };

    private AdapterView.OnItemSelectedListener mPreviewSizeListener =
        new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                View view, int pos, long id) {
            if (pos == mPreviewSize) return;
            if (mState == CAMERA_PREVIEW) {
                log("Stopping preview and callbacks to switch resolutions");
                stopCallbacks();
                mCamera.stopPreview();
            }

            mPreviewSize = pos;
            int width = mPreviewSizes.get(mPreviewSize).width;
            int height = mPreviewSizes.get(mPreviewSize).height;
            mParams.setPreviewSize(width, height);

            log("Setting preview size to " + width + "x" + height);

            mCamera.setParameters(mParams);
            resizePreview();

            if (mState == CAMERA_PREVIEW) {
                log("Restarting preview");
                mCamera.startPreview();
            }
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private AdapterView.OnItemSelectedListener mPreviewFrameRateListener =
                new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos == mPreviewFrameRate) return;
            mPreviewFrameRate = pos;
            mParams.setPreviewFrameRate(mPreviewFrameRates.get(mPreviewFrameRate));

            log("Setting preview frame rate to " + ((TextView)view).getText());

            mCamera.setParameters(mParams);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private View.OnClickListener mHDRToggleListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mState == CAMERA_TAKE_PICTURE) {
                logE("Can't change preview state while taking picture!");
                return;
            }

            if (mHDRToggle.isChecked()) {
                log("Turning on HDR");
                mParams.setSceneMode(Camera.Parameters.SCENE_MODE_HDR);
            } else {
                log("Turning off HDR");
                mParams.setSceneMode(Camera.Parameters.SCENE_MODE_AUTO);
            }
            mCamera.setParameters(mParams);
        }
    };

    private View.OnClickListener mPreviewToggleListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mState == CAMERA_TAKE_PICTURE) {
                logE("Can't change preview state while taking picture!");
                return;
            }
            if (mPreviewToggle.isChecked()) {
                log("Starting preview");
                mCamera.startPreview();
                mState = CAMERA_PREVIEW;
                enablePreviewOnlyControls(true);
            } else {
                log("Stopping preview");
                mCamera.stopPreview();
                mState = CAMERA_OPEN;

                enablePreviewOnlyControls(false);
            }
        }
    };

    private OnItemSelectedListener mAutofocusModeListener =
                new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos == mAfMode) return;

            mAfMode = pos;
            String focusMode = mAfModes.get(mAfMode);
            log("Setting focus mode to " + focusMode);
            if (focusMode == Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE ||
                        focusMode == Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO) {
                mCamera.setAutoFocusMoveCallback(mAutofocusMoveCallback);
            }
            mParams.setFocusMode(focusMode);

            mCamera.setParameters(mParams);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {

        }
    };

    private OnClickListener mAutofocusButtonListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            log("Triggering autofocus");
            mCamera.autoFocus(mAutofocusCallback);
        }
    };

    private OnClickListener mCancelAutofocusButtonListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            log("Cancelling autofocus");
            mCamera.cancelAutoFocus();
        }
    };

    private Camera.AutoFocusCallback mAutofocusCallback =
            new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            log("Autofocus completed: " + (success ? "success" : "failure") );
        }
    };

    private Camera.AutoFocusMoveCallback mAutofocusMoveCallback =
            new Camera.AutoFocusMoveCallback() {
        @Override
        public void onAutoFocusMoving(boolean start, Camera camera) {
            log("Autofocus movement: " + (start ? "starting" : "stopped") );
        }
    };

    private OnItemSelectedListener mFlashModeListener =
                new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos == mFlashMode) return;

            mFlashMode = pos;
            String flashMode = mFlashModes.get(mFlashMode);
            log("Setting flash mode to " + flashMode);
            mParams.setFlashMode(flashMode);
            mCamera.setParameters(mParams);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {

        }
    };


    private AdapterView.OnItemSelectedListener mSnapshotSizeListener =
            new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                View view, int pos, long id) {
            if (pos == mSnapshotSize) return;

            mSnapshotSize = pos;
            int width = mSnapshotSizes.get(mSnapshotSize).width;
            int height = mSnapshotSizes.get(mSnapshotSize).height;
            log("Setting snapshot size to " + width + " x " + height);

            mParams.setPictureSize(width, height);

            mCamera.setParameters(mParams);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private View.OnClickListener mTakePictureListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            log("Taking picture");
            if (mState == CAMERA_PREVIEW) {
                mState = CAMERA_TAKE_PICTURE;
                enablePreviewOnlyControls(false);
                mPreviewToggle.setChecked(false);

                mCamera.takePicture(mShutterCb, mRawCb, mPostviewCb, mJpegCb);
            } else {
                logE("Can't take picture while not running preview!");
            }
        }
    };

    private AdapterView.OnItemSelectedListener mCamcorderProfileListener =
                new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos != mCamcorderProfile) {
                log("Setting camcorder profile to " + ((TextView)view).getText());
                mCamcorderProfile = pos;
            }

            // Additionally change video recording size to match
            mVideoRecordSize = 0; // "default", in case it's not found
            int width = mCamcorderProfiles.get(pos).videoFrameWidth;
            int height = mCamcorderProfiles.get(pos).videoFrameHeight;
            for (int i = 0; i < mVideoRecordSizes.size(); i++) {
                Camera.Size s = mVideoRecordSizes.get(i);
                if (width == s.width && height == s.height) {
                    mVideoRecordSize = i;
                    break;
                }
            }
            log("Setting video record size to " + mVideoRecordSize);
            mVideoRecordSizeSpinner.setSelection(mVideoRecordSize);
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private AdapterView.OnItemSelectedListener mVideoRecordSizeListener =
                new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos == mVideoRecordSize) return;

            log("Setting video record size to " + ((TextView)view).getText());
            mVideoRecordSize = pos;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private AdapterView.OnItemSelectedListener mVideoFrameRateListener =
                new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos == mVideoFrameRate) return;

            log("Setting video frame rate to " + ((TextView)view).getText());
            mVideoFrameRate = pos;
        }

        @Override
        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private View.OnClickListener mRecordToggleListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!mLockCameraToggle.isChecked()) {
                logE("Re-lock camera before recording");
                return;
            }

            mPreviewToggle.setEnabled(false);
            if (mState == CAMERA_PREVIEW) {
                startRecording();
            } else if (mState == CAMERA_RECORD) {
                stopRecording(false);
            } else {
                logE("Can't toggle recording in current state!");
            }
            mPreviewToggle.setEnabled(true);
        }
    };

    private View.OnClickListener mRecordStabilizationToggleListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean on = ((ToggleButton) v).isChecked();
            mParams.setVideoStabilization(on);

            mCamera.setParameters(mParams);
        }
    };

    private View.OnClickListener mRecordHintToggleListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean on = ((ToggleButton) v).isChecked();
            mParams.setRecordingHint(on);

            mCamera.setParameters(mParams);
        }
    };

    private View.OnClickListener mLockCameraToggleListener =
            new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (mState == CAMERA_RECORD) {
                logE("Stop recording before toggling lock");
                return;
            }

            boolean on = ((ToggleButton) v).isChecked();

            if (on) {
                mCamera.lock();
                log("Locked camera");
            } else {
                mCamera.unlock();
                log("Unlocked camera");
            }
        }
    };

    private Camera.ShutterCallback mShutterCb = new Camera.ShutterCallback() {
        @Override
        public void onShutter() {
            log("Shutter callback received");
        }
    };

    private Camera.PictureCallback mRawCb = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            log("Raw callback received");
        }
    };

    private Camera.PictureCallback mPostviewCb = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            log("Postview callback received");
        }
    };

    private Camera.PictureCallback mJpegCb = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            log("JPEG picture callback received");
            FragmentManager fm = getFragmentManager();
            mSnapshotDialog = new SnapshotDialogFragment();

            mSnapshotDialog.updateImage(data);
            mSnapshotDialog.show(fm, "snapshot_dialog_fragment");

            mPreviewToggle.setEnabled(true);

            mState = CAMERA_OPEN;
        }
    };

    private AdapterView.OnItemSelectedListener mCallbackFormatListener =
            new AdapterView.OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            mPreviewFormat = pos;

            log("Setting preview format to " +
                    mFormatNames.get(mPreviewFormats.get(mPreviewFormat)));

            switch (mState) {
            case CAMERA_UNINITIALIZED:
                return;
            case CAMERA_OPEN:
                break;
            case CAMERA_PREVIEW:
                if (mCallbacksEnabled) {
                    log("Stopping preview and callbacks to switch formats");
                    stopCallbacks();
                    mCamera.stopPreview();
                }
                break;
            case CAMERA_RECORD:
                logE("Can't update format while recording active");
                return;
            }

            mParams.setPreviewFormat(mPreviewFormats.get(mPreviewFormat));
            mCamera.setParameters(mParams);

            if (mCallbacksEnabled) {
                if (mState == CAMERA_PREVIEW) {
                    mCamera.startPreview();
                }
            }

            configureCallbacks(mCallbackView.getWidth(), mCallbackView.getHeight());
        }

        public void onNothingSelected(AdapterView<?> parent) {

        }
    };

    private View.OnClickListener mCallbackToggleListener =
                new View.OnClickListener() {
        public void onClick(View v) {
            if (mCallbacksEnabled) {
                log("Disabling preview callbacks");
                stopCallbacks();
                mCallbacksEnabled = false;
                resizePreview();
                mCallbackView.setVisibility(View.GONE);

            } else {
                log("Enabling preview callbacks");
                mCallbacksEnabled = true;
                resizePreview();
                mCallbackView.setVisibility(View.VISIBLE);
            }
        }
    };


    // Internal methods

    void setUpCamera() {
        if (mCameraId == NO_CAMERA_ID) return;

        log("Setting up camera " + mCameraId);
        logIndent(1);

        if (mState < CAMERA_OPEN) {
            log("Opening camera " + mCameraId);

            if (checkSelfPermission(Manifest.permission.CAMERA)
                    != PackageManager.PERMISSION_GRANTED) {
                log("Requested camera permission");
                requestPermissions(new String[] {Manifest.permission.CAMERA},
                        PERMISSIONS_REQUEST_CAMERA);
                return;
            }


            try {
                mCamera = Camera.open(mCameraId);
            } catch (RuntimeException e) {
                logE("Exception opening camera: " + e.getMessage());
                resetCamera();
                mCameraSpinner.setSelection(0);
                logIndent(-1);
                return;
            }
            mState = CAMERA_OPEN;
        }

        mCamera.setErrorCallback(this);

        setCameraDisplayOrientation();
        mParams = mCamera.getParameters();
        mHDRToggle.setEnabled(false);
        if (mParams != null) {
            List<String> sceneModes = mParams.getSupportedSceneModes();
            if (sceneModes != null) {
                for (String mode : sceneModes) {
                    if (Camera.Parameters.SCENE_MODE_HDR.equals(mode)){
                        mHDRToggle.setEnabled(true);
                        break;
                    }
                }
            } else {
                Log.i(TAG, "Supported scene modes is null");
            }
        }

        // Set up preview size selection

        log("Configuring camera");
        logIndent(1);

        updatePreviewSizes(mParams);
        updatePreviewFrameRate(mCameraId);
        updatePreviewFormats(mParams);
        updateAfModes(mParams);
        updateFlashModes(mParams);
        updateSnapshotSizes(mParams);
        updateCamcorderProfile(mCameraId);
        updateVideoRecordSize(mCameraId);
        updateVideoFrameRate(mCameraId);
        updateColorEffects(mParams);

        // Trigger updating video record size to match camcorder profile
        mCamcorderProfileSpinner.setSelection(mCamcorderProfile);

        if (mParams.isVideoStabilizationSupported()) {
            log("Video stabilization is supported");
            mRecordStabilizationToggle.setEnabled(true);
        } else {
            log("Video stabilization not supported");
            mRecordStabilizationToggle.setEnabled(false);
        }

        if (mParams.isAutoExposureLockSupported()) {
            log("Auto-Exposure locking is supported");
            mExposureLockToggle.setEnabled(true);
        } else {
            log("Auto-Exposure locking is not supported");
            mExposureLockToggle.setEnabled(false);
        }

        if (mParams.isZoomSupported()) {
            int maxZoom = mParams.getMaxZoom();
            mZoomSeekBar.setMax(maxZoom);
            log("Zoom is supported, set max to " + maxZoom);
            mZoomSeekBar.setEnabled(true);
        } else {
            log("Zoom is not supported");
            mZoomSeekBar.setEnabled(false);
        }

        // Update parameters based on above updates
        mCamera.setParameters(mParams);

        if (mPreviewHolder != null) {
            log("Setting preview display");
            try {
                mCamera.setPreviewDisplay(mPreviewHolder);
            } catch(IOException e) {
                Log.e(TAG, "Unable to set up preview!");
            }
        }

        logIndent(-1);

        enableOpenOnlyControls(true);

        resizePreview();
        if (mPreviewToggle.isChecked()) {
            log("Starting preview" );
            mCamera.startPreview();
            mState = CAMERA_PREVIEW;
        } else {
            mState = CAMERA_OPEN;
            enablePreviewOnlyControls(false);
        }
        logIndent(-1);
    }

    private void resetCamera() {
        if (mState >= CAMERA_OPEN) {
            log("Closing old camera");
            mCamera.release();
        }
        mCamera = null;
        mCameraId = NO_CAMERA_ID;
        mState = CAMERA_UNINITIALIZED;

        enableOpenOnlyControls(false);
    }

    private void updateAfModes(Parameters params) {
        mAfModes = params.getSupportedFocusModes();

        mAutofocusModeSpinner.setAdapter(
                new ArrayAdapter<String>(this, R.layout.spinner_item,
                        mAfModes.toArray(new String[0])));

        mAfMode = 0;

        params.setFocusMode(mAfModes.get(mAfMode));

        log("Setting AF mode to " + mAfModes.get(mAfMode));
    }

    private void updateFlashModes(Parameters params) {
        mFlashModes = params.getSupportedFlashModes();

        if (mFlashModes != null) {
            mFlashModeSpinnerLabel.setVisibility(View.VISIBLE);
            mFlashModeSpinner.setVisibility(View.VISIBLE);
            mFlashModeSpinner.setAdapter(
                    new ArrayAdapter<String>(this, R.layout.spinner_item,
                            mFlashModes.toArray(new String[0])));

            mFlashMode = 0;

            params.setFlashMode(mFlashModes.get(mFlashMode));

            log("Setting Flash mode to " + mFlashModes.get(mFlashMode));
        } else {
            // this camera has no flash
            mFlashModeSpinnerLabel.setVisibility(View.GONE);
            mFlashModeSpinner.setVisibility(View.GONE);
        }
    }

    private View.OnClickListener mExposureLockToggleListener =
            new View.OnClickListener() {
        public void onClick(View v) {
            boolean on = ((ToggleButton) v).isChecked();
            log("Auto-Exposure was " + mParams.getAutoExposureLock());
            mParams.setAutoExposureLock(on);
            log("Auto-Exposure is now " + mParams.getAutoExposureLock());
        }
    };

    private final SeekBar.OnSeekBarChangeListener mZoomSeekBarListener =
            new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            mZoom = progress;
            mParams.setZoom(mZoom);
            mCamera.setParameters(mParams);
        }
        @Override
        public void onStartTrackingTouch(SeekBar seekBar) { }
        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
            log("Zoom set to " + mZoom + " / " + mParams.getMaxZoom() + " (" +
                    ((float)(mParams.getZoomRatios().get(mZoom))/100) + "x)");
        }
    };

    private void updatePreviewSizes(Camera.Parameters params) {
        mPreviewSizes = params.getSupportedPreviewSizes();

        String[] availableSizeNames = new String[mPreviewSizes.size()];
        int i = 0;
        for (Camera.Size previewSize: mPreviewSizes) {
            availableSizeNames[i++] =
                Integer.toString(previewSize.width) + " x " +
                Integer.toString(previewSize.height);
        }
        mPreviewSizeSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, availableSizeNames));

        mPreviewSize = 0;

        int width = mPreviewSizes.get(mPreviewSize).width;
        int height = mPreviewSizes.get(mPreviewSize).height;
        params.setPreviewSize(width, height);
        log("Setting preview size to " + width + " x " + height);
    }

    private void updatePreviewFrameRate(int cameraId) {
        List<Integer> frameRates = mParams.getSupportedPreviewFrameRates();
        int defaultPreviewFrameRate = mParams.getPreviewFrameRate();

        List<String> frameRateStrings = new ArrayList<String>();
        mPreviewFrameRates = new ArrayList<Integer>();

        int currentIndex = 0;
        for (Integer frameRate : frameRates) {
            mPreviewFrameRates.add(frameRate);
            if(frameRate == defaultPreviewFrameRate) {
                frameRateStrings.add(frameRate.toString() + " (Default)");
                mPreviewFrameRate = currentIndex;
            } else {
                frameRateStrings.add(frameRate.toString());
            }
            currentIndex++;
        }

        String[] nameArray = (String[])frameRateStrings.toArray(new String[0]);
        mPreviewFrameRateSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, nameArray));

        mPreviewFrameRateSpinner.setSelection(mPreviewFrameRate);
        log("Setting preview frame rate to " + nameArray[mPreviewFrameRate]);
    }

    private void updatePreviewFormats(Camera.Parameters params) {
        mPreviewFormats = params.getSupportedPreviewFormats();

        String[] availableFormatNames = new String[mPreviewFormats.size()];
        int i = 0;
        for (Integer previewFormat: mPreviewFormats) {
            availableFormatNames[i++] = mFormatNames.get(previewFormat);
        }
        mCallbackFormatSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, availableFormatNames));

        mPreviewFormat = 0;
        mCallbacksEnabled = false;
        mCallbackToggle.setChecked(false);
        mCallbackView.setVisibility(View.GONE);

        params.setPreviewFormat(mPreviewFormats.get(mPreviewFormat));
        log("Setting preview format to " +
                mFormatNames.get(mPreviewFormats.get(mPreviewFormat)));
    }

    private void updateSnapshotSizes(Camera.Parameters params) {
        String[] availableSizeNames;
        mSnapshotSizes = params.getSupportedPictureSizes();

        availableSizeNames = new String[mSnapshotSizes.size()];
        int i = 0;
        for (Camera.Size snapshotSize : mSnapshotSizes) {
            availableSizeNames[i++] =
                Integer.toString(snapshotSize.width) + " x " +
                Integer.toString(snapshotSize.height);
        }
        mSnapshotSizeSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, availableSizeNames));

        mSnapshotSize = 0;

        int snapshotWidth = mSnapshotSizes.get(mSnapshotSize).width;
        int snapshotHeight = mSnapshotSizes.get(mSnapshotSize).height;
        params.setPictureSize(snapshotWidth, snapshotHeight);
        log("Setting snapshot size to " + snapshotWidth + " x " + snapshotHeight);
    }

    private void updateCamcorderProfile(int cameraId) {
        // Have to query all of these individually,
        final int PROFILES[] = new int[] {
            CamcorderProfile.QUALITY_2160P,
            CamcorderProfile.QUALITY_1080P,
            CamcorderProfile.QUALITY_480P,
            CamcorderProfile.QUALITY_720P,
            CamcorderProfile.QUALITY_CIF,
            CamcorderProfile.QUALITY_HIGH,
            CamcorderProfile.QUALITY_LOW,
            CamcorderProfile.QUALITY_QCIF,
            CamcorderProfile.QUALITY_QVGA,
            CamcorderProfile.QUALITY_TIME_LAPSE_2160P,
            CamcorderProfile.QUALITY_TIME_LAPSE_1080P,
            CamcorderProfile.QUALITY_TIME_LAPSE_480P,
            CamcorderProfile.QUALITY_TIME_LAPSE_720P,
            CamcorderProfile.QUALITY_TIME_LAPSE_CIF,
            CamcorderProfile.QUALITY_TIME_LAPSE_HIGH,
            CamcorderProfile.QUALITY_TIME_LAPSE_LOW,
            CamcorderProfile.QUALITY_TIME_LAPSE_QCIF,
            CamcorderProfile.QUALITY_TIME_LAPSE_QVGA
        };

        final String PROFILE_NAMES[] = new String[] {
            "2160P",
            "1080P",
            "480P",
            "720P",
            "CIF",
            "HIGH",
            "LOW",
            "QCIF",
            "QVGA",
            "TIME_LAPSE_2160P",
            "TIME_LAPSE_1080P",
            "TIME_LAPSE_480P",
            "TIME_LAPSE_720P",
            "TIME_LAPSE_CIF",
            "TIME_LAPSE_HIGH",
            "TIME_LAPSE_LOW",
            "TIME_LAPSE_QCIF",
            "TIME_LAPSE_QVGA"
        };

        List<String> availableCamcorderProfileNames = new ArrayList<String>();
        mCamcorderProfiles = new ArrayList<CamcorderProfile>();

        for (int i = 0; i < PROFILES.length; i++) {
            if (CamcorderProfile.hasProfile(cameraId, PROFILES[i])) {
                availableCamcorderProfileNames.add(PROFILE_NAMES[i]);
                mCamcorderProfiles.add(CamcorderProfile.get(cameraId, PROFILES[i]));
            }
        }
        String[] nameArray = (String[])availableCamcorderProfileNames.toArray(new String[0]);
        mCamcorderProfileSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, nameArray));

        mCamcorderProfile = 0;
        log("Setting camcorder profile to " + nameArray[mCamcorderProfile]);

    }

    private void updateVideoRecordSize(int cameraId) {
        List<Camera.Size> videoSizes = mParams.getSupportedVideoSizes();
        if (videoSizes == null) { // TODO: surface this to the user
            log("Failed to get video size list, using preview sizes instead");
            videoSizes = mParams.getSupportedPreviewSizes();
        }

        List<String> availableVideoRecordSizes = new ArrayList<String>();
        mVideoRecordSizes = new ArrayList<Camera.Size>();

        availableVideoRecordSizes.add("Default");
        mVideoRecordSizes.add(mCamera.new Size(0,0));

        for (Camera.Size s : videoSizes) {
              availableVideoRecordSizes.add(s.width + "x" + s.height);
              mVideoRecordSizes.add(s);
        }
        String[] nameArray = (String[])availableVideoRecordSizes.toArray(new String[0]);
        mVideoRecordSizeSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, nameArray));

        mVideoRecordSize = 0;
        log("Setting video record profile to " + nameArray[mVideoRecordSize]);
    }

    private void updateVideoFrameRate(int cameraId) {
        // Use preview framerates as video framerates
        List<Integer> frameRates = mParams.getSupportedPreviewFrameRates();

        List<String> frameRateStrings = new ArrayList<String>();
        mVideoFrameRates = new ArrayList<Integer>();

        frameRateStrings.add("Default");
        mVideoFrameRates.add(0);

        for (Integer frameRate : frameRates) {
            frameRateStrings.add(frameRate.toString());
            mVideoFrameRates.add(frameRate);
        }
        String[] nameArray = (String[])frameRateStrings.toArray(new String[0]);
        mVideoFrameRateSpinner.setAdapter(
                new ArrayAdapter<String>(
                        this, R.layout.spinner_item, nameArray));

        mVideoFrameRate = 0;
        log("Setting recording frame rate to " + nameArray[mVideoFrameRate]);
    }

    void resizePreview() {
        // Reset preview layout parameters, to trigger layout pass
        // This will eventually call layoutPreview below
        Resources res = getResources();
        mPreviewView.setLayoutParams(
                new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0,
                        mCallbacksEnabled ?
                        res.getInteger(R.integer.preview_with_callback_weight):
                        res.getInteger(R.integer.preview_only_weight) ));
    }

    void layoutPreview() {
        int width = mPreviewSizes.get(mPreviewSize).width;
        int height = mPreviewSizes.get(mPreviewSize).height;
        float previewAspect = ((float) width) / height;

        int viewHeight = mPreviewView.getHeight();
        int viewWidth = mPreviewView.getWidth();
        float viewAspect = ((float) viewWidth) / viewHeight;
        if ( previewAspect > viewAspect) {
            viewHeight = (int) (viewWidth / previewAspect);
        } else {
            viewWidth = (int) (viewHeight * previewAspect);
        }
        mPreviewView.setLayoutParams(
                new LayoutParams(viewWidth, viewHeight));

        if (mCallbacksEnabled) {
            int callbackHeight = mCallbackView.getHeight();
            int callbackWidth = mCallbackView.getWidth();
            float callbackAspect = ((float) callbackWidth) / callbackHeight;
            if ( previewAspect > callbackAspect) {
                callbackHeight = (int) (callbackWidth / previewAspect);
            } else {
                callbackWidth = (int) (callbackHeight * previewAspect);
            }
            mCallbackView.setLayoutParams(
                    new LayoutParams(callbackWidth, callbackHeight));
            configureCallbacks(callbackWidth, callbackHeight);
        }
    }


    private void configureCallbacks(int callbackWidth, int callbackHeight) {
        if (mState >= CAMERA_OPEN && mCallbacksEnabled) {
            mCamera.setPreviewCallbackWithBuffer(null);
            int width = mPreviewSizes.get(mPreviewSize).width;
            int height = mPreviewSizes.get(mPreviewSize).height;
            int format = mPreviewFormats.get(mPreviewFormat);

            mCallbackProcessor = new CallbackProcessor(width, height, format,
                    getResources(), mCallbackView,
                    callbackWidth, callbackHeight, mRS);

            int size = getCallbackBufferSize(width, height, format);
            log("Configuring callbacks:" + width + " x " + height +
                    " , format " + format);
            for (int i = 0; i < CALLBACK_BUFFER_COUNT; i++) {
                mCamera.addCallbackBuffer(new byte[size]);
            }
            mCamera.setPreviewCallbackWithBuffer(this);
        }
        mLastCallbackTimestamp = -1;
        mCallbackFrameCount = 0;
        mCallbackAvgFrameDuration = 30;
    }

    private void stopCallbacks() {
        if (mState >= CAMERA_OPEN) {
            mCamera.setPreviewCallbackWithBuffer(null);
            if (mCallbackProcessor != null) {
                if (!mCallbackProcessor.stop()) {
                    logE("Can't stop preview callback processing!");
                }
            }
        }
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        long timestamp = SystemClock.elapsedRealtime();
        if (mLastCallbackTimestamp != -1) {
            long frameDuration = timestamp - mLastCallbackTimestamp;
            mCallbackAvgFrameDuration =
                    mCallbackAvgFrameDuration * MEAN_FPS_HISTORY_COEFF +
                    frameDuration * MEAN_FPS_MEASUREMENT_COEFF;
        }
        mLastCallbackTimestamp = timestamp;
        if (mState < CAMERA_PREVIEW || !mCallbacksEnabled) {
            mCamera.addCallbackBuffer(data);
            return;
        }
        mCallbackFrameCount++;
        if (mCallbackFrameCount % FPS_REPORTING_PERIOD == 0) {
            log("Got " + FPS_REPORTING_PERIOD + " callback frames, fps "
                    + 1e3/mCallbackAvgFrameDuration);
        }
        mCallbackProcessor.displayCallback(data);

        mCamera.addCallbackBuffer(data);
    }

    @Override
    public void onError(int error, Camera camera) {
        String errorName;
        switch (error) {
        case Camera.CAMERA_ERROR_SERVER_DIED:
            errorName = "SERVER_DIED";
            break;
        case Camera.CAMERA_ERROR_UNKNOWN:
            errorName = "UNKNOWN";
            break;
        default:
            errorName = "?";
            break;
        }
        logE("Camera error received: " + errorName + " (" + error + ")" );
        logE("Shutting down camera");
        resetCamera();
        mCameraSpinner.setSelection(0);
    }

    static final int MEDIA_TYPE_IMAGE = 0;
    static final int MEDIA_TYPE_VIDEO = 1;
    @SuppressLint("SimpleDateFormat")
    File getOutputMediaFile(int type){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.

        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)) {
                return null;
        }

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                  Environment.DIRECTORY_DCIM), "TestingCamera");
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                logE("Failed to create directory for pictures/video");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE){
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
            "IMG_"+ timeStamp + ".jpg");
        } else if(type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator +
            "VID_"+ timeStamp + ".mp4");
        } else {
            return null;
        }

        return mediaFile;
    }

    void notifyMediaScannerOfFile(File newFile,
                final MediaScannerConnection.OnScanCompletedListener listener) {
        final Handler h = new Handler();
        MediaScannerConnection.scanFile(this,
                new String[] { newFile.toString() },
                null,
                new MediaScannerConnection.OnScanCompletedListener() {
                    @Override
                    public void onScanCompleted(final String path, final Uri uri) {
                        h.post(new Runnable() {
                            @Override
                            public void run() {
                                log("MediaScanner notified: " +
                                        path + " -> " + uri);
                                if (listener != null)
                                    listener.onScanCompleted(path, uri);
                            }
                        });
                    }
                });
    }

    private void deleteFile(File badFile) {
        if (badFile.exists()) {
            boolean success = badFile.delete();
            if (success) log("Deleted file " + badFile.toString());
            else log("Unable to delete file " + badFile.toString());
        }
    }

    private void startRecording() {
        log("Starting recording");

        if  ((checkSelfPermission(Manifest.permission.RECORD_AUDIO)
                != PackageManager.PERMISSION_GRANTED)
            || (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED)) {
            log("Requesting recording permissions (audio, storage)");
            requestPermissions(new String[] {
                    Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE},
                PERMISSIONS_REQUEST_RECORDING);
            return;
        }

        logIndent(1);
        log("Configuring MediaRecoder");

        mRecordHandoffCheckBox.setEnabled(false);
        if (mRecordHandoffCheckBox.isChecked()) {
            mCamera.release();
        } else {
            mCamera.unlock();
        }

        if (mRecorder != null) {
            mRecorder.release();
        }

        mRecorder = new MediaRecorder();
        mRecorder.setOnErrorListener(mRecordingErrorListener);
        mRecorder.setOnInfoListener(mRecordingInfoListener);
        if (!mRecordHandoffCheckBox.isChecked()) {
            mRecorder.setCamera(mCamera);
        }
        mRecorder.setPreviewDisplay(mPreviewHolder.getSurface());

        mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mRecorder.setProfile(mCamcorderProfiles.get(mCamcorderProfile));
        Camera.Size videoRecordSize = mVideoRecordSizes.get(mVideoRecordSize);
        if (videoRecordSize.width > 0 && videoRecordSize.height > 0) {
            mRecorder.setVideoSize(videoRecordSize.width, videoRecordSize.height);
        }
        if (mVideoFrameRates.get(mVideoFrameRate) > 0) {
            mRecorder.setVideoFrameRate(mVideoFrameRates.get(mVideoFrameRate));
        }
        File outputFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
        log("File name:" + outputFile.toString());
        mRecorder.setOutputFile(outputFile.toString());

        boolean ready = false;
        log("Preparing MediaRecorder");
        try {
            mRecorder.prepare();
            ready = true;
        } catch (Exception e) {
            StringWriter writer = new StringWriter();
            e.printStackTrace(new PrintWriter(writer));
            logE("Exception preparing MediaRecorder:\n" + writer.toString());
        }

        if (ready) {
            try {
                log("Starting MediaRecorder");
                mRecorder.start();
                mState = CAMERA_RECORD;
                log("Recording active");
                mRecordingFile = outputFile;
            } catch (Exception e) {
                StringWriter writer = new StringWriter();
                e.printStackTrace(new PrintWriter(writer));
                logE("Exception starting MediaRecorder:\n" + writer.toString());
                ready = false;
            }
        }

        if (!ready) {
            mRecordToggle.setChecked(false);
            mRecordHandoffCheckBox.setEnabled(true);

            if (mRecordHandoffCheckBox.isChecked()) {
                mState = CAMERA_UNINITIALIZED;
                setUpCamera();
            }
        }
        logIndent(-1);
    }

    private MediaRecorder.OnErrorListener mRecordingErrorListener =
            new MediaRecorder.OnErrorListener() {
        @Override
        public void onError(MediaRecorder mr, int what, int extra) {
            logE("MediaRecorder reports error: " + what + ", extra "
                    + extra);
            if (mState == CAMERA_RECORD) {
                stopRecording(true);
            }
        }
    };

    private MediaRecorder.OnInfoListener mRecordingInfoListener =
            new MediaRecorder.OnInfoListener() {
        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
            log("MediaRecorder reports info: " + what + ", extra "
                    + extra);
        }
    };

    private void stopRecording(boolean error) {
        log("Stopping recording");
        mRecordHandoffCheckBox.setEnabled(true);
        mRecordToggle.setChecked(false);
        if (mRecorder != null) {
            try {
                mRecorder.stop();
            } catch (RuntimeException e) {
                // this can happen if there were no frames received by recorder
                logE("Could not create output file");
                error = true;
            }

            if (mRecordHandoffCheckBox.isChecked()) {
                mState = CAMERA_UNINITIALIZED;
                setUpCamera();
            } else {
                mCamera.lock();
                mState = CAMERA_PREVIEW;
            }

            if (!error) {
                notifyMediaScannerOfFile(mRecordingFile, null);
            } else {
                deleteFile(mRecordingFile);
            }
            mRecordingFile = null;
        } else {
            logE("Recorder is unexpectedly null!");
        }
    }

    static int getCallbackBufferSize(int width, int height, int format) {
        int size = -1;
        switch (format) {
        case ImageFormat.NV21:
            size = width * height * 3 / 2;
            break;
        case ImageFormat.YV12:
            int y_stride = (int) (Math.ceil( width / 16.) * 16);
            int y_size = y_stride * height;
            int c_stride = (int) (Math.ceil(y_stride / 32.) * 16);
            int c_size = c_stride * height/2;
            size = y_size + c_size * 2;
            break;
        case ImageFormat.NV16:
        case ImageFormat.RGB_565:
        case ImageFormat.YUY2:
            size = 2 * width * height;
            break;
        case ImageFormat.JPEG:
            Log.e(TAG, "JPEG callback buffers not supported!");
            size = 0;
            break;
        case ImageFormat.UNKNOWN:
            Log.e(TAG, "Unknown-format callback buffers not supported!");
            size = 0;
            break;
        }
        return size;
    }

    private OnItemSelectedListener mColorEffectListener =
                new OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> parent,
                        View view, int pos, long id) {
            if (pos == mColorEffect) return;

            mColorEffect = pos;
            String colorEffect = mColorEffects.get(mColorEffect);
            log("Setting color effect to " + colorEffect);
            mParams.setColorEffect(colorEffect);
            mCamera.setParameters(mParams);
        }

        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
        }
    };

    private void updateColorEffects(Parameters params) {
        mColorEffects = params.getSupportedColorEffects();
        if (mColorEffects != null) {
            mColorEffectSpinnerLabel.setVisibility(View.VISIBLE);
            mColorEffectSpinner.setVisibility(View.VISIBLE);
            mColorEffectSpinner.setAdapter(
                    new ArrayAdapter<String>(this, R.layout.spinner_item,
                            mColorEffects.toArray(new String[0])));
            mColorEffect = 0;
            params.setColorEffect(mColorEffects.get(mColorEffect));
            log("Setting Color Effect to " + mColorEffects.get(mColorEffect));
        } else {
            mColorEffectSpinnerLabel.setVisibility(View.GONE);
            mColorEffectSpinner.setVisibility(View.GONE);
        }
    }

    private int mLogIndentLevel = 0;
    private String mLogIndent = "\t";
    /** Increment or decrement log indentation level */
    synchronized void logIndent(int delta) {
        mLogIndentLevel += delta;
        if (mLogIndentLevel < 0) mLogIndentLevel = 0;
        char[] mLogIndentArray = new char[mLogIndentLevel + 1];
        for (int i = -1; i < mLogIndentLevel; i++) {
            mLogIndentArray[i + 1] = '\t';
        }
        mLogIndent = new String(mLogIndentArray);
    }

    @SuppressLint("SimpleDateFormat")
    SimpleDateFormat mDateFormatter = new SimpleDateFormat("HH:mm:ss.SSS");
    /** Log both to log text view and to device logcat */
    void log(String logLine) {
        Log.d(TAG, logLine);
        logAndScrollToBottom(logLine, mLogIndent);
    }

    void logE(String logLine) {
        Log.e(TAG, logLine);
        logAndScrollToBottom(logLine, mLogIndent + "!!! ");
    }

    synchronized private void logAndScrollToBottom(String logLine, String logIndent) {
        StringBuffer logEntry = new StringBuffer(32);
        logEntry.append("\n").append(mDateFormatter.format(new Date())).append(logIndent);
        logEntry.append(logLine);
        mLogView.append(logEntry);
        final Layout layout = mLogView.getLayout();
        if (layout != null){
            int scrollDelta = layout.getLineBottom(mLogView.getLineCount() - 1)
                - mLogView.getScrollY() - mLogView.getHeight();
            if(scrollDelta > 0) {
                mLogView.scrollBy(0, scrollDelta);
            }
        }
    }
}
