/*
 * Copyright (C) 2012 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.
 */

/**
 * The Scene class implements a simple physical simulation of a scene, using the
 * CIE 1931 colorspace to represent light in physical units (lux).
 *
 * It's fairly approximate, but does provide a scene with realistic widely
 * variable illumination levels and colors over time.
 *
 */

#ifndef HW_EMULATOR_CAMERA2_SCENE_H
#define HW_EMULATOR_CAMERA2_SCENE_H

#include "utils/Timers.h"

namespace android {

class Scene {
  public:
    Scene(int sensorWidthPx,
            int sensorHeightPx,
            float sensorSensitivity);
    ~Scene();

    // Set the filter coefficients for the red, green, and blue filters on the
    // sensor. Used as an optimization to pre-calculate various illuminance
    // values. Two different green filters can be provided, to account for
    // possible cross-talk on a Bayer sensor. Must be called before
    // calculateScene.
    void setColorFilterXYZ(
        float rX, float rY, float rZ,
        float grX, float grY, float grZ,
        float gbX, float gbY, float gbZ,
        float bX, float bY, float bZ);

    // Set time of day (24-hour clock). This controls the general light levels
    // in the scene. Must be called before calculateScene
    void setHour(int hour);
    // Get current hour
    int getHour();

    // Set the duration of exposure for determining luminous exposure.
    // Must be called before calculateScene
    void setExposureDuration(float seconds);

    // Calculate scene information for current hour and the time offset since
    // the hour. Must be called at least once before calling getLuminousExposure.
    // Resets pixel readout location to 0,0
    void calculateScene(nsecs_t time);

    // Set sensor pixel readout location.
    void setReadoutPixel(int x, int y);

    // Get sensor response in physical units (electrons) for light hitting the
    // current readout pixel, after passing through color filters. The color
    // channels are 0=R, 1=Gr, 2=Gb, 3=B. The readout pixel will be
    // auto-incremented.
    uint32_t getPixelElectrons(int x, int y, int c);

  private:
    // Sensor color filtering coefficients in XYZ
    float mFilterR[3];
    float mFilterGr[3];
    float mFilterGb[3];
    float mFilterB[3];

    int mOffsetX, mOffsetY;
    int mMapDiv;

    int mSensorWidth;
    int mSensorHeight;
    int mCurrentX;
    int mCurrentY;
    int mSubX;
    int mSubY;
    int mSceneX;
    int mSceneY;
    int mSceneIdx;
    uint32_t *mCurrentSceneMaterial;

    int mHour;
    float mExposureDuration;
    float mSensorSensitivity;

    enum Materials {
        GRASS = 0,
        GRASS_SHADOW,
        HILL,
        WALL,
        ROOF,
        DOOR,
        CHIMNEY,
        WINDOW,
        SUN,
        SKY,
        MOON,
        NUM_MATERIALS
    };

    uint32_t mCurrentColors[NUM_MATERIALS*4];

    /**
     * Constants for scene definition. These are various degrees of approximate.
     */

    // Aperture of imaging lens
    static const float kAperture;

    // Sun, moon illuminance levels in 2-hour increments. These don't match any
    // real day anywhere.
    static const uint32_t kTimeStep = 2;
    static const float kSunlight[];
    static const float kMoonlight[];
    static const int kSunOverhead;
    static const int kMoonOverhead;

    // Illumination levels for various conditions, in lux
    static const float kDirectSunIllum;
    static const float kDaylightShadeIllum;
    static const float kSunsetIllum;
    static const float kTwilightIllum;
    static const float kFullMoonIllum;
    static const float kClearNightIllum;
    static const float kStarIllum;
    static const float kLivingRoomIllum;

    // Chromaticity of various illumination sources
    static const float kIncandescentXY[2];
    static const float kDirectSunlightXY[2];
    static const float kDaylightXY[2];
    static const float kNoonSkyXY[2];
    static const float kMoonlightXY[2];
    static const float kSunsetXY[2];

    static const uint8_t kSelfLit;
    static const uint8_t kShadowed;
    static const uint8_t kSky;

    static const float kMaterials_xyY[NUM_MATERIALS][3];
    static const uint8_t kMaterialsFlags[NUM_MATERIALS];

    static const int kSceneWidth;
    static const int kSceneHeight;
    static const uint8_t kScene[];
};

}

#endif // HW_EMULATOR_CAMERA2_SCENE_H
