package com.ragnarok.rxcamera.config;

import android.graphics.Point;
import android.hardware.Camera;

/**
 * Created by ragnarok on 15/11/1.
 * store the config of camera, you must set the config from {@link RxCameraConfig.Builder}
 */
public class RxCameraConfig {

    public static Point DEFAULT_PREFER_PREVIEW_SIZE = new Point(320, 240);

    public final boolean isFaceCamera;

    public final int currentCameraId;

    public final Point preferPreviewSize;

    public final boolean acceptSquarePreview;

    public final int minPreferPreviewFrameRate;

    public final int maxPreferPreviewFrameRate;

    public final int previewFormat;

    public final int displayOrientation;

    public final boolean isAutoFocus;

    public final int previewBufferSize;

    public final boolean isHandleSurfaceEvent;

    public final int cameraOrientation;

    public RxCameraConfig(Builder builder) {
        isFaceCamera = builder.isFaceCamera;
        currentCameraId = builder.currentCameraId;
        preferPreviewSize = builder.preferPreviewSize;
        acceptSquarePreview = builder.acceptSquarePreview;
        minPreferPreviewFrameRate = builder.minPreferPreviewFrameRate;
        maxPreferPreviewFrameRate = builder.maxPreferPreviewFrameRate;
        previewFormat = builder.previewFormat;
        displayOrientation = builder.displayOrientation;
        isAutoFocus = builder.isAutoFocus;
        previewBufferSize = builder.previewBufferSize;
        isHandleSurfaceEvent = builder.isHandleSurfaceEvent;
        cameraOrientation = builder.cameraOrientation;
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder("RxCameraConfig ");
        result.append(String.format("isFaceCamera: %b, currentCameraId: %d, ", isFaceCamera, currentCameraId));
        result.append(String.format("preferPreviewSize: %s, ", preferPreviewSize));
        result.append(String.format("minPreferPreviewFrameRate: %d, maxPreferPreviewFrameRate: %d, ", minPreferPreviewFrameRate, maxPreferPreviewFrameRate));
        result.append(String.format("previewFormat: %d, ", previewFormat));
        result.append(String.format("displayOrientation: %d, ", displayOrientation));
        result.append(String.format("isAutoFocus: %b", isAutoFocus));
        result.append(String.format("previewBufferSize: %d, ", previewBufferSize));
        result.append(String.format("isHandleSurfaceEvent: %b, ", isHandleSurfaceEvent));
        result.append(String.format("cameraOrientation: %d, ", cameraOrientation));
        result.append(String.format("acceptSquarePreview: %s", acceptSquarePreview));
        return result.toString();
    }

    public static class Builder {
        private boolean isFaceCamera = false;
        private int currentCameraId = -1;
        private Point preferPreviewSize = null;
        private boolean acceptSquarePreview = true;
        private int minPreferPreviewFrameRate = -1;
        private int maxPreferPreviewFrameRate = -1;
        private int previewFormat = -1;
        private int displayOrientation = -1;
        private boolean isAutoFocus = false;
        private int previewBufferSize = -1;
        private boolean isHandleSurfaceEvent = false;
        private int cameraOrientation = -1;

        public Builder useFrontCamera() {
            isFaceCamera = true;
            currentCameraId = CameraUtil.getFrontCameraId();
            return this;
        }

        public Builder useBackCamera() {
            isFaceCamera = false;
            currentCameraId = CameraUtil.getBackCameraId();
            return this;
        }

        public Builder setPreferPreviewSize(Point size, boolean acceptSquarePreview) {
            if (size == null) {
                return this;
            }
            preferPreviewSize = size;
            this.acceptSquarePreview = acceptSquarePreview;
            return this;
        }

        public Builder setPreferPreviewFrameRate(int minFrameRate, int maxFrameRate) {
            if (minFrameRate <= 0 || maxFrameRate <= 0 || maxFrameRate < minFrameRate) {
                return this;
            }
            minPreferPreviewFrameRate = minFrameRate;
            maxPreferPreviewFrameRate = maxFrameRate;
            return this;
        }

        public Builder setPreviewFormat(int previewFormat) {
            this.previewFormat = previewFormat;
            return this;
        }

        public Builder setDisplayOrientation(int displayOrientation) {
            this.displayOrientation = displayOrientation;
            return this;
        }

        public Builder setAutoFocus(boolean isAutoFocus) {
            this.isAutoFocus = isAutoFocus;
            return this;
        }

        public Builder setHandleSurfaceEvent(boolean isHandle) {
            isHandleSurfaceEvent = isHandle;
            return this;
        }

        public Builder setPreviewBufferSize(int size) {
            previewBufferSize = size;
            return this;
        }

        private Builder setProperConfigVal() {
            if (currentCameraId == -1) {
                if (isFaceCamera) {
                    currentCameraId = CameraUtil.getFrontCameraId();
                } else {
                    currentCameraId = CameraUtil.getBackCameraId();
                }
            }
            if (preferPreviewSize == null) {
                preferPreviewSize = RxCameraConfig.DEFAULT_PREFER_PREVIEW_SIZE;
            }

            Camera.CameraInfo cameraInfo = CameraUtil.getCameraInfo(currentCameraId);
            if (cameraInfo != null) {
                cameraOrientation = cameraInfo.orientation;
            }
            return this;
        }

        public RxCameraConfig build() {
            setProperConfigVal();
            if (displayOrientation != 0 &&
                    displayOrientation != 90 &&
                    displayOrientation != 180 &&
                    displayOrientation != 270)
                throw new IllegalArgumentException("display orientation: " +displayOrientation + ". (must be 0, 90, 180, or 270)");
            return new RxCameraConfig(this);
        }
    }
}

@@ -4472,24 +4472,344 @@
 entation) %7B%0A
+            if (displayOrientation != 0 &&%0A                    displayOrientation != 90 &&%0A                    displayOrientation != 180 &&%0A                    displayOrientation != 270)%0A                throw new IllegalArgumentException(%22display orientation: %22 +displayOrientation + %22. (must be 0, 90, 180, or 270)%22);%0A%0A
             
@@ -6075,327 +6075,8 @@
 ();%0A
-            if (displayOrientation != 0 &&%0A                    displayOrientation != 90 &&%0A                    displayOrientation != 180 &&%0A                    displayOrientation != 270)%0A                throw new IllegalArgumentException(%22display orientation: %22 +displayOrientation + %22. (must be 0, 90, 180, or 270)%22);%0A
     

Check valid displayOrientation only when it's set. If it's not set, current implementation crashes because default value -1 does not pass the check to be 0,90,180,270