/*
 * 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.OrientationEventListener;
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;
    private OrientationEventHandler mOrientationHandler;

    /** 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);

        mOrientationHandler = new OrientationEventHandler(this);
    }

    private static class OrientationEventHandler extends OrientationEventListener {
        private TestingCamera mActivity;
        private int mCurrentRotation = -1;
        OrientationEventHandler(TestingCamera activity) {
            super(activity);
            mActivity = activity;
        }

        @Override
        public void onOrientationChanged(int orientation) {
            if (mActivity != null) {
                int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation();
                if (mCurrentRotation != rotation) {
                    mCurrentRotation = rotation;
                    mActivity.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mActivity.setCameraDisplayOrientation();
                            mActivity.resizePreview();
                        }
                    });
                }
            }
        }
    }

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

    @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;
        }
        mOrientationHandler.disable();
    }

    @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 || mState == CAMERA_UNINITIALIZED) {
                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
        if (mCamcorderProfile >= 0) {
            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));

        if (availableCamcorderProfileNames.size() == 0) {
            log("Camera " +  cameraId + " doesn't support camcorder profile");
            mCamcorderProfile = -1;
            return;
        }

        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 rotation = getWindowManager().getDefaultDisplay().getRotation();
        int width = mPreviewSizes.get(mPreviewSize).width;
        int height = mPreviewSizes.get(mPreviewSize).height;
        switch (rotation) {
            case Surface.ROTATION_0:
            case Surface.ROTATION_180:
                // Portrait
                // Switch the preview size so that the longer edge aligns with the taller
                // dimension.
                if (width > height) {
                    int tmp = height;
                    height = width;
                    width = tmp;
                }
                break;
            case Surface.ROTATION_90:
            case Surface.ROTATION_270:
                // Landscape
                // Possibly somewhat unlikely case but we should try to handle it too.
                if (height > width) {
                    int tmp = height;
                    height = width;
                    width = tmp;
                }
                break;
        }

        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));
        log("Setting layout params viewWidth: " + viewWidth + " viewHeight: " + viewHeight +
                " display rotation: " + rotation);

        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 static final int BIT_RATE_1080P = 16000000;
    private static final int BIT_RATE_MIN = 64000;
    private static final int BIT_RATE_MAX = 40000000;

    private int getVideoBitRate(Camera.Size sz) {
        int rate = BIT_RATE_1080P;
        float scaleFactor = sz.height * sz.width / (float)(1920 * 1080);
        rate = (int)(rate * scaleFactor);

        // Clamp to the MIN, MAX range.
        return Math.max(BIT_RATE_MIN, Math.min(BIT_RATE_MAX, rate));
    }

    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);

        Camera.Size videoRecordSize = mVideoRecordSizes.get(mVideoRecordSize);
        if (mCamcorderProfile >= 0) {
            mRecorder.setProfile(mCamcorderProfiles.get(mCamcorderProfile));
        } else {
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setVideoEncodingBitRate(getVideoBitRate(videoRecordSize));
            mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        }

        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);
            }
        }
    }
}
