#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
**correction.py**

**Platform:**
    Windows, Linux, Mac Os X.

**Description:**
    Defines **Color** package spectral bandpass correction related objects.

**Others:**

"""

from __future__ import unicode_literals

import copy

import color.verbose

__author__ = "Thomas Mansencal"
__copyright__ = "Copyright (C) 2013 - 2014 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "thomas.mansencal@gmail.com"
__status__ = "Production"

__all__ = ["LOGGER",
           "bandpass_correction_stearns",
           "bandpass_correction"]

LOGGER = color.verbose.install_logger()

ALPHA_STEARNS = 0.083


def bandpass_correction_stearns(spd, in_place=False):
    """
    Implements spectral bandpass correction on given relative spectral power distribution using *Stearns and Stearns (1998)* method.

    Reference: **Stephen Westland, Caterina Ripamonti, Vien Cheung**, *Computational Colour Science Using MATLAB, 2nd Edition*, Page 38.

    Usage::

        >>> spd = color.SpectralPowerDistribution("Spd", {510: 49.6700, 520: 69.5900, 530: 81.7300, 540: 88.1900, 550: 86.0500})
        >>> corrected_spd = bandpass_correction_stearns(spd)
        >>> print corrected_spd.values
        [ 48.01664     70.37296888  82.13645358  88.88480681  85.87238   ]

    :param spd: Spectral power distribution.
    :type spd: SpectralPowerDistribution
    :param in_place: Correction will happen in place and will modify original spectral power distribution.
    :type in_place: bool
    :return: Corrected spectral power distribution.
    :rtype: SpectralPowerDistribution
    """

    values = spd.values
    values[0] = (1 + ALPHA_STEARNS) * values[0] - ALPHA_STEARNS * values[1]
    values[-1] = (1 + ALPHA_STEARNS) * values[-1] - ALPHA_STEARNS * values[-2]
    for i in range(1, len(values) - 1):
        values[i] = -ALPHA_STEARNS * values[i - 1] + (1. + 2. * ALPHA_STEARNS) * values[i] - ALPHA_STEARNS * values[
            i + 1]

    if in_place is False:
        spd = copy.deepcopy(spd)

    for i, (wavelength, value) in enumerate(spd):
        spd[wavelength] = values[i]
    return spd

def bandpass_correction(spd, in_place=False, method="Stearns"):
    """
    Implements spectral bandpass correction on given relative spectral power distribution using given method.

    :param spd: Spectral power distribution.
    :type spd: SpectralPowerDistribution
    :param in_place: Correction will happen in place and will modify original spectral power distribution.
    :type in_place: bool
    :param method: Correction method.
    :type method: unicode ("Stearns",)
    :return: Corrected spectral power distribution.
    :rtype: SpectralPowerDistribution
    """

    if method == "Stearns":
        return bandpass_correction_stearns(spd, in_place=in_place)