/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.camera.app;

import android.content.Context;
import android.hardware.Camera;
import android.os.Handler;
import android.util.Log;

import com.android.camera.CameraDisabledException;
import com.android.camera.util.CameraUtil;

/**
 * A class which implements {@link com.android.camera.app.CameraProvider} used
 * by {@link com.android.camera.CameraActivity}.
 * TODO: Make this class package private.
 */
public class CameraController implements CameraManager.CameraOpenCallback, CameraProvider {
    private final String TAG = "CameraController";
    private final Context mContext;
    private CameraManager.CameraOpenCallback mCallbackReceiver;
    private final Handler mCallbackHandler;
    private final CameraManager mCameraManager;
    private final Camera.CameraInfo[] mCameraInfos;
    private final int mNumberOfCameras;
    private final int mFirstBackCameraId;
    private final int mFirstFrontCameraId;

    private CameraManager.CameraProxy mCameraProxy;
    private int mRequestingCameraId = -1;

    /**
     * Constructor.
     *
     * @param context The {@link android.content.Context} used to check if the
     *                camera is disabled.
     * @param handler The {@link android.os.Handler} to post the camera
     *                callbacks to.
     * @param cameraManager Used for camera open/close.
     */
    public CameraController(Context context, CameraManager.CameraOpenCallback callbackReceiver,
            Handler handler, CameraManager cameraManager) {
        mContext = context;
        mCallbackReceiver = callbackReceiver;
        mCallbackHandler = handler;
        mCameraManager = cameraManager;
        mNumberOfCameras = Camera.getNumberOfCameras();
        mCameraInfos = new Camera.CameraInfo[mNumberOfCameras];
        for (int i = 0; i < mNumberOfCameras; i++) {
            mCameraInfos[i] = new Camera.CameraInfo();
            Camera.getCameraInfo(i, mCameraInfos[i]);
        }

        int firstFront = -1;
        int firstBack = -1;
        // Get the first (smallest) back and first front camera id.
        for (int i = mNumberOfCameras - 1; i >= 0; i--) {
            if (mCameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                firstBack = i;
            } else {
                if (mCameraInfos[i].facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                    firstFront = i;
                }
            }
        }
        mFirstBackCameraId = firstBack;
        mFirstFrontCameraId = firstFront;
    }

    @Override
    public Camera.CameraInfo[] getCameraInfo() {
        return mCameraInfos;
    }

    @Override
    public int getNumberOfCameras() {
        return mNumberOfCameras;
    }

    @Override
    public int getFirstBackCameraId() {
        return mFirstBackCameraId;
    }

    @Override
    public int getFirstFrontCameraId() {
        return mFirstFrontCameraId;
    }

    @Override
    public boolean isFrontFacingCamera(int id) {
        if (id >= mCameraInfos.length || mCameraInfos[id] == null) {
            Log.e(TAG, "Camera info not available:" + id);
            return false;
        }
        return (mCameraInfos[id].facing == Camera.CameraInfo.CAMERA_FACING_FRONT);
    }

    @Override
    public boolean isBackFacingCamera(int id) {
        if (id >= mCameraInfos.length || mCameraInfos[id] == null) {
            Log.e(TAG, "Camera info not available:" + id);
            return false;
        }
        return (mCameraInfos[id].facing == Camera.CameraInfo.CAMERA_FACING_BACK);
    }

    @Override
    public void onCameraOpened(CameraManager.CameraProxy camera) {
        mRequestingCameraId = -1;
        mCameraProxy = camera;
        mCallbackReceiver.onCameraOpened(camera);
    }

    @Override
    public void onCameraDisabled(int cameraId) {
        mCallbackReceiver.onCameraDisabled(cameraId);
    }

    @Override
    public void onDeviceOpenFailure(int cameraId) {
        mCallbackReceiver.onDeviceOpenFailure(cameraId);
    }

    @Override
    public void onReconnectionFailure(CameraManager mgr) {
        mCallbackReceiver.onReconnectionFailure(mgr);
    }

    @Override
    public void requestCamera(int id) {
        // Double open is avoided.
        if (mRequestingCameraId == id) {
            return;
        }
        mRequestingCameraId = id;
        if (mCameraProxy == null) {
            // No camera yet.
            checkAndOpenCamera(mContext, mCameraManager, id, mCallbackHandler, this);
        } else if (mCameraProxy.getCameraId() != id) {
            // Already has another camera opened.
            mCameraProxy.release(false);
            mCameraProxy = null;
            checkAndOpenCamera(mContext, mCameraManager, id, mCallbackHandler, this);
        } else {
            // The same camera, just do a reconnect.
            mCameraProxy.reconnect(mCallbackHandler, this);
            mCameraProxy = null;
        }
    }

    @Override
    public void releaseCamera(int id) {
        if (mCameraProxy.getCameraId() != id) {
            throw new IllegalStateException("Trying to release an unopened camera.");
        }
        if (mRequestingCameraId != -1) {
            mRequestingCameraId = -1;
        }
    }

    public void removeCallbackReceiver() {
        mCallbackReceiver = null;
    }

    /**
     * Closes the opened camera device.
     * TODO: Make this method package private.
     */
    public void closeCamera() {
        Log.v(TAG, "closing camera");
        if (mCameraProxy == null) {
            return;
        }
        mCameraProxy.release(true);
        mCameraProxy = null;
        mRequestingCameraId = -1;
    }

    private static void checkAndOpenCamera(Context context, CameraManager cameraManager,
            final int cameraId, Handler handler, final CameraManager.CameraOpenCallback cb) {
        try {
            CameraUtil.throwIfCameraDisabled(context);
            cameraManager.cameraOpen(handler, cameraId, cb);
        } catch (CameraDisabledException ex) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    cb.onCameraDisabled(cameraId);
                }
            });
        }
    }

    public void setOneShotPreviewCallback(Handler handler,
            CameraManager.CameraPreviewDataCallback cb) {
        mCameraProxy.setOneShotPreviewCallback(handler, cb);
    }
}
