/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "video_processing.h"
#include "brightness_detection.h"
#include "trace.h"

#include <math.h>

namespace webrtc {

VPMBrightnessDetection::VPMBrightnessDetection() :
    _id(0)
{
    Reset();
}

VPMBrightnessDetection::~VPMBrightnessDetection()
{
}

WebRtc_Word32
VPMBrightnessDetection::ChangeUniqueId(const WebRtc_Word32 id)
{
    _id = id;
    return VPM_OK;
}

void
VPMBrightnessDetection::Reset()
{
    _frameCntBright = 0;
    _frameCntDark = 0;
}

WebRtc_Word32
VPMBrightnessDetection::ProcessFrame(const VideoFrame& frame,
                                     const VideoProcessingModule::FrameStats&
                                     stats)
{
    if (frame.Buffer() == NULL)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, _id,
                     "Null frame pointer");
        return VPM_PARAMETER_ERROR;
    }
    int width = frame.Width();
    int height = frame.Height();
    
    if (width == 0 || height == 0)
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, _id,
                     "Invalid frame size");
        return VPM_PARAMETER_ERROR;
    }

    if (!VideoProcessingModule::ValidFrameStats(stats))
    {
        WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoPreocessing, _id,
                     "Invalid frame stats");
        return VPM_PARAMETER_ERROR;
    }

    const WebRtc_UWord8 frameCntAlarm = 2;

    // Get proportion in lowest bins 
    WebRtc_UWord8 lowTh = 20;
    float propLow = 0;
    for (WebRtc_UWord32 i = 0; i < lowTh; i++)
    {
        propLow += stats.hist[i];
    }
    propLow /= stats.numPixels;

    // Get proportion in highest bins 
    unsigned char highTh = 230;
    float propHigh = 0;
    for (WebRtc_UWord32 i = highTh; i < 256; i++)
    {
        propHigh += stats.hist[i];
    }
    propHigh /= stats.numPixels;

    if(propHigh < 0.4)
    {
        if (stats.mean < 90 || stats.mean > 170)
        {
            // Standard deviation of Y
            float stdY = 0;
            uint8_t* buffer = frame.Buffer();
            for (int h = 0; h < height; h += (1 << stats.subSamplHeight))
            {
                WebRtc_UWord32 row = h*width;
                for (int w = 0; w < width; w += (1 << stats.subSamplWidth))
                {
                    stdY += (buffer[w + row] - stats.mean) * (buffer[w + row] -
                        stats.mean);
                }
            }           
            stdY = sqrt(stdY / stats.numPixels);

            // Get percentiles
            WebRtc_UWord32 sum = 0;
            WebRtc_UWord32 medianY = 140;
            WebRtc_UWord32 perc05 = 0;
            WebRtc_UWord32 perc95 = 255;
            float posPerc05 = stats.numPixels * 0.05f;
            float posMedian = stats.numPixels * 0.5f;
            float posPerc95 = stats.numPixels * 0.95f;
            for (WebRtc_UWord32 i = 0; i < 256; i++)
            {
                sum += stats.hist[i];

                if (sum < posPerc05)
                {
                    perc05 = i;     // 5th perc
                }
                if (sum < posMedian)
                {
                    medianY = i;    // 50th perc
                }
                if (sum < posPerc95)
                {
                    perc95 = i;     // 95th perc
                }
                else
                {
                    break;
                }
            }

            // Check if image is too dark
            if ((stdY < 55) && (perc05 < 50))
            { 
                if (medianY < 60 || stats.mean < 80 ||  perc95 < 130 ||
                    propLow > 0.20)
                {
                    _frameCntDark++;
                }
                else
                {
                    _frameCntDark = 0;
                }
            } 
            else
            {
                _frameCntDark = 0;
            }

            // Check if image is too bright
            if ((stdY < 52) && (perc95 > 200) && (medianY > 160))
            {
                if (medianY > 185 || stats.mean > 185 || perc05 > 140 ||
                    propHigh > 0.25)
                {
                    _frameCntBright++;  
                }
                else 
                {
                    _frameCntBright = 0;
                }
            } 
            else
            {
                _frameCntBright = 0;
            }

        } 
        else
        {
            _frameCntDark = 0;
            _frameCntBright = 0;
        }

    } 
    else
    {
        _frameCntBright++;
        _frameCntDark = 0;
    }
    
    if (_frameCntDark > frameCntAlarm)
    {
        return VideoProcessingModule::kDarkWarning;
    }
    else if (_frameCntBright > frameCntAlarm)
    {
        return VideoProcessingModule::kBrightWarning;
    }
    else
    {
        return VideoProcessingModule::kNoWarning;
    }
}

} //namespace
