/*
 * 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 android.hardware.photography;

import static android.hardware.photography.CameraMetadata.Key;

/**
 * ! Do not edit this file directly !
 *
 * Generated automatically from CameraPropertiesKeys.mako
 *
 * TODO: Include a hash of the input files here that the build can check.
 */

/**
 * The base class for camera controls and information.
 *
 * This class defines the basic key/value map used for querying for camera
 * characteristics or capture results, and for setting camera request
 * parameters.
 *
 * @see CameraProperties
 * @see CameraMetadata
 * @hide
 **/
public final class CameraPropertiesKeys {
    public static final class Control {
        public static final Key<byte[]> AE_AVAILABLE_ANTIBANDING_MODES =
                new Key<byte[]>("android.control.aeAvailableAntibandingModes", byte[].class);
        public static final Key<int[]> AE_AVAILABLE_TARGET_FPS_RANGES =
                new Key<int[]>("android.control.aeAvailableTargetFpsRanges", int[].class);
        public static final Key<int[]> AE_COMPENSATION_RANGE =
                new Key<int[]>("android.control.aeCompensationRange", int[].class);
        public static final Key<Rational> AE_COMPENSATION_STEP =
                new Key<Rational>("android.control.aeCompensationStep", Rational.class);
        public static final Key<byte[]> AF_AVAILABLE_MODES =
                new Key<byte[]>("android.control.afAvailableModes", byte[].class);
        public static final Key<byte[]> AVAILABLE_EFFECTS =
                new Key<byte[]>("android.control.availableEffects", byte[].class);
        public static final Key<byte[]> AVAILABLE_SCENE_MODES =
                new Key<byte[]>("android.control.availableSceneModes", byte[].class);
        public static final Key<byte[]> AVAILABLE_VIDEO_STABILIZATION_MODES =
                new Key<byte[]>("android.control.availableVideoStabilizationModes", byte[].class);
        public static final Key<byte[]> AWB_AVAILABLE_MODES =
                new Key<byte[]>("android.control.awbAvailableModes", byte[].class);
        public static final Key<Integer> MAX_REGIONS =
                new Key<Integer>("android.control.maxRegions", int.class);

    }

    public static final class Flash {
        public static final class Info {
            public static final Key<Byte> AVAILABLE =
                    new Key<Byte>("android.flash.info.available", byte.class);
        }

    }

    public static final class Jpeg {
        public static final Key<android.hardware.photography.Size[]> AVAILABLE_THUMBNAIL_SIZES =
                new Key<android.hardware.photography.Size[]>("android.jpeg.availableThumbnailSizes", android.hardware.photography.Size[].class);

    }

    public static final class Lens {
        public static final class Info {
            public static final Key<float[]> AVAILABLE_APERTURES =
                    new Key<float[]>("android.lens.info.availableApertures", float[].class);
            public static final Key<float[]> AVAILABLE_FILTER_DENSITIES =
                    new Key<float[]>("android.lens.info.availableFilterDensities", float[].class);
            public static final Key<float[]> AVAILABLE_FOCAL_LENGTHS =
                    new Key<float[]>("android.lens.info.availableFocalLengths", float[].class);
            public static final Key<byte[]> AVAILABLE_OPTICAL_STABILIZATION =
                    new Key<byte[]>("android.lens.info.availableOpticalStabilization", byte[].class);
            public static final Key<Float> HYPERFOCAL_DISTANCE =
                    new Key<Float>("android.lens.info.hyperfocalDistance", float.class);
            public static final Key<Float> MINIMUM_FOCUS_DISTANCE =
                    new Key<Float>("android.lens.info.minimumFocusDistance", float.class);
            public static final Key<android.hardware.photography.Size> SHADING_MAP_SIZE =
                    new Key<android.hardware.photography.Size>("android.lens.info.shadingMapSize", android.hardware.photography.Size.class);
        }

            public static final class FacingKey extends Key<Lens.FacingKey.Enum> {
                public enum Enum {
                    FRONT,
                    BACK;
                }

                public static final Enum FRONT = Enum.FRONT;
                public static final Enum BACK = Enum.BACK;

                // TODO: remove requirement for constructor by making Key an interface
                private FacingKey(String name) {
                    super(name, Lens.FacingKey.Enum.class);
                }

            }

        public static final Key<Lens.FacingKey.Enum> FACING =
                new FacingKey("android.lens.facing");

    }

    public static final class Request {
        public static final Key<int[]> MAX_NUM_OUTPUT_STREAMS =
                new Key<int[]>("android.request.maxNumOutputStreams", int[].class);

    }

    public static final class Scaler {

            public static final class AvailableFormatsKey extends Key<Scaler.AvailableFormatsKey.Enum[]> {
                public enum Enum {
                    RAW_SENSOR,
                    YV12,
                    YCrCb_420_SP,
                    IMPLEMENTATION_DEFINED,
                    YCbCr_420_888,
                    BLOB;
                }

                public static final Enum RAW_SENSOR = Enum.RAW_SENSOR;
                public static final Enum YV12 = Enum.YV12;
                public static final Enum YCrCb_420_SP = Enum.YCrCb_420_SP;
                public static final Enum IMPLEMENTATION_DEFINED = Enum.IMPLEMENTATION_DEFINED;
                public static final Enum YCbCr_420_888 = Enum.YCbCr_420_888;
                public static final Enum BLOB = Enum.BLOB;

                // TODO: remove requirement for constructor by making Key an interface
                private AvailableFormatsKey(String name) {
                    super(name, Scaler.AvailableFormatsKey.Enum[].class);
                }

                static {
                    CameraMetadata.registerEnumValues(Scaler.AvailableFormatsKey.Enum.class, new int[] {
                        0x20,  // RAW_SENSOR
                        0x32315659,  // YV12
                        0x11,  // YCrCb_420_SP
                        0x22,  // IMPLEMENTATION_DEFINED
                        0x23,  // YCbCr_420_888
                        0x21  // BLOB
                    });
                }
            }

        public static final Key<Scaler.AvailableFormatsKey.Enum[]> AVAILABLE_FORMATS =
                new AvailableFormatsKey("android.scaler.availableFormats");
        public static final Key<long[]> AVAILABLE_JPEG_MIN_DURATIONS =
                new Key<long[]>("android.scaler.availableJpegMinDurations", long[].class);
        public static final Key<android.hardware.photography.Size[]> AVAILABLE_JPEG_SIZES =
                new Key<android.hardware.photography.Size[]>("android.scaler.availableJpegSizes", android.hardware.photography.Size[].class);
        public static final Key<Float> AVAILABLE_MAX_DIGITAL_ZOOM =
                new Key<Float>("android.scaler.availableMaxDigitalZoom", float.class);
        public static final Key<long[]> AVAILABLE_PROCESSED_MIN_DURATIONS =
                new Key<long[]>("android.scaler.availableProcessedMinDurations", long[].class);
        public static final Key<android.hardware.photography.Size[]> AVAILABLE_PROCESSED_SIZES =
                new Key<android.hardware.photography.Size[]>("android.scaler.availableProcessedSizes", android.hardware.photography.Size[].class);

    }

    public static final class Sensor {
        public static final class Info {
            public static final Key<android.graphics.Rect> ACTIVE_ARRAY_SIZE =
                    new Key<android.graphics.Rect>("android.sensor.info.activeArraySize", android.graphics.Rect.class);
            public static final Key<int[]> SENSITIVITY_RANGE =
                    new Key<int[]>("android.sensor.info.sensitivityRange", int[].class);
            public static final Key<long[]> EXPOSURE_TIME_RANGE =
                    new Key<long[]>("android.sensor.info.exposureTimeRange", long[].class);
            public static final Key<Long> MAX_FRAME_DURATION =
                    new Key<Long>("android.sensor.info.maxFrameDuration", long.class);
            public static final Key<android.hardware.photography.Size> PHYSICAL_SIZE =
                    new Key<android.hardware.photography.Size>("android.sensor.info.physicalSize", android.hardware.photography.Size.class);
        }
        public static final Key<Rational> BASE_GAIN_FACTOR =
                new Key<Rational>("android.sensor.baseGainFactor", Rational.class);
        public static final Key<Integer> MAX_ANALOG_SENSITIVITY =
                new Key<Integer>("android.sensor.maxAnalogSensitivity", int.class);
        public static final Key<Integer> ORIENTATION =
                new Key<Integer>("android.sensor.orientation", int.class);

    }

    public static final class Statistics {
        public static final class Info {
            public static final Key<byte[]> AVAILABLE_FACE_DETECT_MODES =
                    new Key<byte[]>("android.statistics.info.availableFaceDetectModes", byte[].class);
            public static final Key<Integer> MAX_FACE_COUNT =
                    new Key<Integer>("android.statistics.info.maxFaceCount", int.class);
        }

    }

    public static final class Tonemap {
        public static final Key<Integer> MAX_CURVE_POINTS =
                new Key<Integer>("android.tonemap.maxCurvePoints", int.class);

    }

    /**
     * @hide
     */
    public static final class Led {

            /**
             * @hide
             */
            public static final class AvailableLedsKey extends Key<Led.AvailableLedsKey.Enum[]> {
                public enum Enum {
                    TRANSMIT;
                }

                public static final Enum TRANSMIT = Enum.TRANSMIT;

                // TODO: remove requirement for constructor by making Key an interface
                private AvailableLedsKey(String name) {
                    super(name, Led.AvailableLedsKey.Enum[].class);
                }

            }

        /**
         * @hide
         */
        public static final Key<Led.AvailableLedsKey.Enum[]> AVAILABLE_LEDS =
                new AvailableLedsKey("android.led.availableLeds");

    }

    public static final class Info {

            public static final class SupportedHardwareLevelKey extends Key<Info.SupportedHardwareLevelKey.Enum> {
                public enum Enum {
                    LIMITED,
                    FULL;
                }

                public static final Enum LIMITED = Enum.LIMITED;
                public static final Enum FULL = Enum.FULL;

                // TODO: remove requirement for constructor by making Key an interface
                private SupportedHardwareLevelKey(String name) {
                    super(name, Info.SupportedHardwareLevelKey.Enum.class);
                }

            }

        public static final Key<Info.SupportedHardwareLevelKey.Enum> SUPPORTED_HARDWARE_LEVEL =
                new SupportedHardwareLevelKey("android.info.supportedHardwareLevel");

    }

}


