/*
 * 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 CaptureResultKeys.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 CaptureResult
 * @see CameraMetadata
 * @hide
 **/
public final class CaptureResultKeys {
    public static final class ColorCorrection {
        public static final Key<Rational[]> TRANSFORM =
                new Key<Rational[]>("android.colorCorrection.transform", Rational[].class);
        public static final Key<float[]> GAINS =
                new Key<float[]>("android.colorCorrection.gains", float[].class);

    }

    public static final class Control {
        /**
         * @hide
         */
        public static final Key<Integer> AE_PRECAPTURE_ID =
                new Key<Integer>("android.control.aePrecaptureId", int.class);
        public static final Key<int[]> AE_REGIONS =
                new Key<int[]>("android.control.aeRegions", int[].class);

            public static final class AeStateKey extends Key<Control.AeStateKey.Enum> {
                public enum Enum {
                    INACTIVE,
                    SEARCHING,
                    CONVERGED,
                    LOCKED,
                    FLASH_REQUIRED,
                    PRECAPTURE;
                }

                public static final Enum INACTIVE = Enum.INACTIVE;
                public static final Enum SEARCHING = Enum.SEARCHING;
                public static final Enum CONVERGED = Enum.CONVERGED;
                public static final Enum LOCKED = Enum.LOCKED;
                public static final Enum FLASH_REQUIRED = Enum.FLASH_REQUIRED;
                public static final Enum PRECAPTURE = Enum.PRECAPTURE;

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

            }

        public static final Key<Control.AeStateKey.Enum> AE_STATE =
                new AeStateKey("android.control.aeState");

            public static final class AfModeKey extends Key<Control.AfModeKey.Enum> {
                public enum Enum {
                    OFF,
                    AUTO,
                    MACRO,
                    CONTINUOUS_VIDEO,
                    CONTINUOUS_PICTURE,
                    EDOF;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum AUTO = Enum.AUTO;
                public static final Enum MACRO = Enum.MACRO;
                public static final Enum CONTINUOUS_VIDEO = Enum.CONTINUOUS_VIDEO;
                public static final Enum CONTINUOUS_PICTURE = Enum.CONTINUOUS_PICTURE;
                public static final Enum EDOF = Enum.EDOF;

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

            }

        public static final Key<Control.AfModeKey.Enum> AF_MODE =
                new AfModeKey("android.control.afMode");
        public static final Key<int[]> AF_REGIONS =
                new Key<int[]>("android.control.afRegions", int[].class);

            public static final class AfStateKey extends Key<Control.AfStateKey.Enum> {
                public enum Enum {
                    INACTIVE,
                    PASSIVE_SCAN,
                    PASSIVE_FOCUSED,
                    ACTIVE_SCAN,
                    FOCUSED_LOCKED,
                    NOT_FOCUSED_LOCKED;
                }

                public static final Enum INACTIVE = Enum.INACTIVE;
                public static final Enum PASSIVE_SCAN = Enum.PASSIVE_SCAN;
                public static final Enum PASSIVE_FOCUSED = Enum.PASSIVE_FOCUSED;
                public static final Enum ACTIVE_SCAN = Enum.ACTIVE_SCAN;
                public static final Enum FOCUSED_LOCKED = Enum.FOCUSED_LOCKED;
                public static final Enum NOT_FOCUSED_LOCKED = Enum.NOT_FOCUSED_LOCKED;

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

            }

        public static final Key<Control.AfStateKey.Enum> AF_STATE =
                new AfStateKey("android.control.afState");
        /**
         * @hide
         */
        public static final Key<Integer> AF_TRIGGER_ID =
                new Key<Integer>("android.control.afTriggerId", int.class);

            public static final class AwbModeKey extends Key<Control.AwbModeKey.Enum> {
                public enum Enum {
                    OFF,
                    AUTO,
                    INCANDESCENT,
                    FLUORESCENT,
                    WARM_FLUORESCENT,
                    DAYLIGHT,
                    CLOUDY_DAYLIGHT,
                    TWILIGHT,
                    SHADE;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum AUTO = Enum.AUTO;
                public static final Enum INCANDESCENT = Enum.INCANDESCENT;
                public static final Enum FLUORESCENT = Enum.FLUORESCENT;
                public static final Enum WARM_FLUORESCENT = Enum.WARM_FLUORESCENT;
                public static final Enum DAYLIGHT = Enum.DAYLIGHT;
                public static final Enum CLOUDY_DAYLIGHT = Enum.CLOUDY_DAYLIGHT;
                public static final Enum TWILIGHT = Enum.TWILIGHT;
                public static final Enum SHADE = Enum.SHADE;

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

            }

        public static final Key<Control.AwbModeKey.Enum> AWB_MODE =
                new AwbModeKey("android.control.awbMode");
        public static final Key<int[]> AWB_REGIONS =
                new Key<int[]>("android.control.awbRegions", int[].class);

            public static final class AwbStateKey extends Key<Control.AwbStateKey.Enum> {
                public enum Enum {
                    INACTIVE,
                    SEARCHING,
                    CONVERGED,
                    LOCKED;
                }

                public static final Enum INACTIVE = Enum.INACTIVE;
                public static final Enum SEARCHING = Enum.SEARCHING;
                public static final Enum CONVERGED = Enum.CONVERGED;
                public static final Enum LOCKED = Enum.LOCKED;

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

            }

        public static final Key<Control.AwbStateKey.Enum> AWB_STATE =
                new AwbStateKey("android.control.awbState");

            public static final class ModeKey extends Key<Control.ModeKey.Enum> {
                public enum Enum {
                    OFF,
                    AUTO,
                    USE_SCENE_MODE;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum AUTO = Enum.AUTO;
                public static final Enum USE_SCENE_MODE = Enum.USE_SCENE_MODE;

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

            }

        public static final Key<Control.ModeKey.Enum> MODE =
                new ModeKey("android.control.mode");

    }

    public static final class Edge {

            public static final class ModeKey extends Key<Edge.ModeKey.Enum> {
                public enum Enum {
                    OFF,
                    FAST,
                    HIGH_QUALITY;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum FAST = Enum.FAST;
                public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY;

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

            }

        public static final Key<Edge.ModeKey.Enum> MODE =
                new ModeKey("android.edge.mode");

    }

    public static final class Flash {

            public static final class ModeKey extends Key<Flash.ModeKey.Enum> {
                public enum Enum {
                    OFF,
                    SINGLE,
                    TORCH;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum SINGLE = Enum.SINGLE;
                public static final Enum TORCH = Enum.TORCH;

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

            }

        public static final Key<Flash.ModeKey.Enum> MODE =
                new ModeKey("android.flash.mode");

            public static final class StateKey extends Key<Flash.StateKey.Enum> {
                public enum Enum {
                    UNAVAILABLE,
                    CHARGING,
                    READY,
                    FIRED;
                }

                public static final Enum UNAVAILABLE = Enum.UNAVAILABLE;
                public static final Enum CHARGING = Enum.CHARGING;
                public static final Enum READY = Enum.READY;
                public static final Enum FIRED = Enum.FIRED;

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

            }

        public static final Key<Flash.StateKey.Enum> STATE =
                new StateKey("android.flash.state");

    }

    public static final class Jpeg {
        public static final Key<double[]> GPS_COORDINATES =
                new Key<double[]>("android.jpeg.gpsCoordinates", double[].class);
        public static final Key<String> GPS_PROCESSING_METHOD =
                new Key<String>("android.jpeg.gpsProcessingMethod", String.class);
        public static final Key<Long> GPS_TIMESTAMP =
                new Key<Long>("android.jpeg.gpsTimestamp", long.class);
        public static final Key<Integer> ORIENTATION =
                new Key<Integer>("android.jpeg.orientation", int.class);
        public static final Key<Byte> QUALITY =
                new Key<Byte>("android.jpeg.quality", byte.class);
        public static final Key<Byte> THUMBNAIL_QUALITY =
                new Key<Byte>("android.jpeg.thumbnailQuality", byte.class);
        public static final Key<android.hardware.photography.Size> THUMBNAIL_SIZE =
                new Key<android.hardware.photography.Size>("android.jpeg.thumbnailSize", android.hardware.photography.Size.class);

    }

    public static final class Lens {
        public static final Key<Float> APERTURE =
                new Key<Float>("android.lens.aperture", float.class);
        public static final Key<Float> FILTER_DENSITY =
                new Key<Float>("android.lens.filterDensity", float.class);
        public static final Key<Float> FOCAL_LENGTH =
                new Key<Float>("android.lens.focalLength", float.class);
        public static final Key<Float> FOCUS_DISTANCE =
                new Key<Float>("android.lens.focusDistance", float.class);
        public static final Key<Float> FOCUS_RANGE =
                new Key<Float>("android.lens.focusRange", float.class);

            public static final class OpticalStabilizationModeKey extends Key<Lens.OpticalStabilizationModeKey.Enum> {
                public enum Enum {
                    OFF,
                    ON;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum ON = Enum.ON;

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

            }

        public static final Key<Lens.OpticalStabilizationModeKey.Enum> OPTICAL_STABILIZATION_MODE =
                new OpticalStabilizationModeKey("android.lens.opticalStabilizationMode");

            public static final class StateKey extends Key<Lens.StateKey.Enum> {
                public enum Enum {
                    STATIONARY;
                }

                public static final Enum STATIONARY = Enum.STATIONARY;

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

            }

        public static final Key<Lens.StateKey.Enum> STATE =
                new StateKey("android.lens.state");

    }

    public static final class NoiseReduction {

            public static final class ModeKey extends Key<NoiseReduction.ModeKey.Enum> {
                public enum Enum {
                    OFF,
                    FAST,
                    HIGH_QUALITY;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum FAST = Enum.FAST;
                public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY;

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

            }

        public static final Key<NoiseReduction.ModeKey.Enum> MODE =
                new ModeKey("android.noiseReduction.mode");

    }

    public static final class Request {
        public static final Key<Integer> FRAME_COUNT =
                new Key<Integer>("android.request.frameCount", int.class);
        /**
         * @hide
         */
        public static final Key<Integer> ID =
                new Key<Integer>("android.request.id", int.class);

    }

    public static final class Scaler {
        public static final Key<android.graphics.Rect> CROP_REGION =
                new Key<android.graphics.Rect>("android.scaler.cropRegion", android.graphics.Rect.class);

    }

    public static final class Sensor {
        public static final Key<Long> EXPOSURE_TIME =
                new Key<Long>("android.sensor.exposureTime", long.class);
        public static final Key<Long> FRAME_DURATION =
                new Key<Long>("android.sensor.frameDuration", long.class);
        public static final Key<Integer> SENSITIVITY =
                new Key<Integer>("android.sensor.sensitivity", int.class);
        public static final Key<Long> TIMESTAMP =
                new Key<Long>("android.sensor.timestamp", long.class);

    }

    public static final class Statistics {

            public static final class FaceDetectModeKey extends Key<Statistics.FaceDetectModeKey.Enum> {
                public enum Enum {
                    OFF,
                    SIMPLE,
                    FULL;
                }

                public static final Enum OFF = Enum.OFF;
                public static final Enum SIMPLE = Enum.SIMPLE;
                public static final Enum FULL = Enum.FULL;

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

            }

        public static final Key<Statistics.FaceDetectModeKey.Enum> FACE_DETECT_MODE =
                new FaceDetectModeKey("android.statistics.faceDetectMode");
        public static final Key<int[]> FACE_IDS =
                new Key<int[]>("android.statistics.faceIds", int[].class);
        public static final Key<int[]> FACE_LANDMARKS =
                new Key<int[]>("android.statistics.faceLandmarks", int[].class);
        public static final Key<android.graphics.Rect[]> FACE_RECTANGLES =
                new Key<android.graphics.Rect[]>("android.statistics.faceRectangles", android.graphics.Rect[].class);
        public static final Key<byte[]> FACE_SCORES =
                new Key<byte[]>("android.statistics.faceScores", byte[].class);
        public static final Key<float[]> LENS_SHADING_MAP =
                new Key<float[]>("android.statistics.lensShadingMap", float[].class);
        public static final Key<float[]> PREDICTED_COLOR_GAINS =
                new Key<float[]>("android.statistics.predictedColorGains", float[].class);
        public static final Key<Rational[]> PREDICTED_COLOR_TRANSFORM =
                new Key<Rational[]>("android.statistics.predictedColorTransform", Rational[].class);

            public static final class SceneFlickerKey extends Key<Statistics.SceneFlickerKey.Enum> {
                public enum Enum {
                    NONE,
                    _50HZ,
                    _60HZ;
                }

                public static final Enum NONE = Enum.NONE;
                public static final Enum _50HZ = Enum._50HZ;
                public static final Enum _60HZ = Enum._60HZ;

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

            }

        public static final Key<Statistics.SceneFlickerKey.Enum> SCENE_FLICKER =
                new SceneFlickerKey("android.statistics.sceneFlicker");

    }

    public static final class Tonemap {
        public static final Key<Float> CURVE_BLUE =
                new Key<Float>("android.tonemap.curveBlue", float.class);
        public static final Key<Float> CURVE_GREEN =
                new Key<Float>("android.tonemap.curveGreen", float.class);
        public static final Key<float[]> CURVE_RED =
                new Key<float[]>("android.tonemap.curveRed", float[].class);

            public static final class ModeKey extends Key<Tonemap.ModeKey.Enum> {
                public enum Enum {
                    CONTRAST_CURVE,
                    FAST,
                    HIGH_QUALITY;
                }

                public static final Enum CONTRAST_CURVE = Enum.CONTRAST_CURVE;
                public static final Enum FAST = Enum.FAST;
                public static final Enum HIGH_QUALITY = Enum.HIGH_QUALITY;

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

            }

        public static final Key<Tonemap.ModeKey.Enum> MODE =
                new ModeKey("android.tonemap.mode");

    }

    /**
     * @hide
     */
    public static final class Led {
        /**
         * @hide
         */
        public static final Key<Boolean> TRANSMIT =
                new Key<Boolean>("android.led.transmit", boolean.class);

    }

    public static final class BlackLevel {
        public static final Key<Boolean> LOCK =
                new Key<Boolean>("android.blackLevel.lock", boolean.class);

    }

}


