package com.mining.app.zxing.camera;

import android.content.Context;
import android.graphics.Point;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.os.Handler;
import android.view.SurfaceHolder;

import java.io.IOException;

/**
 * 描述: 相机管理
 */
public final class CameraManager {
    private static CameraManager cameraManager;

    static final int SDK_INT;

    static {
        int sdkInt;
        try {
            sdkInt = android.os.Build.VERSION.SDK_INT;
        } catch (NumberFormatException nfe) {
            sdkInt = 10000;
        }
        SDK_INT = sdkInt;
    }

    private final CameraConfigurationManager configManager;
    private Camera camera;
    private boolean initialized;
    private boolean previewing;
    private final boolean useOneShotPreviewCallback;
    private final PreviewCallback previewCallback;
    private final AutoFocusCallback autoFocusCallback;
    private Parameters parameter;

    public static void init(Context context) {
        if (cameraManager == null) {
            cameraManager = new CameraManager(context);
        }
    }

    public static CameraManager get() {
        return cameraManager;
    }

    private CameraManager(Context context) {
        this.configManager = new CameraConfigurationManager(context);

        useOneShotPreviewCallback = SDK_INT > 3;
        previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback);
        autoFocusCallback = new AutoFocusCallback();
    }

    public void openDriver(SurfaceHolder holder) throws IOException {
        try {
            if (camera == null) {
                camera = Camera.open();
                if (camera == null) {
                    throw new IOException();
                }
                camera.setPreviewDisplay(holder);

                if (!initialized) {
                    initialized = true;
                    configManager.initFromCameraParameters(camera);
                }
                configManager.setDesiredCameraParameters(camera);
                FlashlightManager.enableFlashlight();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Point getCameraResolution() {
        return configManager.getCameraResolution();
    }

    public void closeDriver() {
        if (camera != null) {
            FlashlightManager.disableFlashlight();
            camera.release();
            camera = null;
        }
    }

    public void startPreview() {
        if (camera != null && !previewing) {
            camera.startPreview();
            previewing = true;
        }
    }

    public void stopPreview() {
        if (camera != null && previewing) {
            if (!useOneShotPreviewCallback) {
                camera.setPreviewCallback(null);
            }
            camera.stopPreview();
            previewCallback.setHandler(null, 0);
            autoFocusCallback.setHandler(null, 0);
            previewing = false;
        }
    }

    public void requestPreviewFrame(Handler handler, int message) {
        if (camera != null && previewing) {
            previewCallback.setHandler(handler, message);
            if (useOneShotPreviewCallback) {
                camera.setOneShotPreviewCallback(previewCallback);
            } else {
                camera.setPreviewCallback(previewCallback);
            }
        }
    }

    public void requestAutoFocus(Handler handler, int message) {
        if (camera != null && previewing) {
            autoFocusCallback.setHandler(handler, message);
            camera.autoFocus(autoFocusCallback);
        }
    }

    public void openLight() {
        try {
            if (camera != null) {
                parameter = camera.getParameters();
                parameter.setFlashMode(Parameters.FLASH_MODE_TORCH);
                camera.setParameters(parameter);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void offLight() {
        try {
            if (camera != null) {
                parameter = camera.getParameters();
                parameter.setFlashMode(Parameters.FLASH_MODE_OFF);
                camera.setParameters(parameter);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 是否开启了闪光灯
     *
     * @return
     */
    public boolean isFlashLightOn() {
        try {
            Parameters parameters = camera.getParameters();
            String flashMode = parameters.getFlashMode();
            if (flashMode.equals(Parameters.FLASH_MODE_TORCH)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;

        }
    }
}
