/*
 * Copyright 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.
 */

#include "Daltonizer.h"
#include <ui/mat4.h>

namespace android {

void Daltonizer::setType(ColorBlindnessType type) {
    if (type != mType) {
        mDirty = true;
        mType = type;
    }
}

void Daltonizer::setMode(ColorBlindnessMode mode) {
    if (mode != mMode) {
        mDirty = true;
        mMode = mode;
    }
}

const mat4& Daltonizer::operator()() {
    if (mDirty) {
        mDirty = false;
        update();
    }
    return mColorTransform;
}

void Daltonizer::update() {
    if (mType == ColorBlindnessType::None) {
        mColorTransform = mat4();
        return;
    }

    // converts a linear RGB color to the XYZ space
    const mat4 rgb2xyz( 0.4124, 0.2126, 0.0193, 0,
                        0.3576, 0.7152, 0.1192, 0,
                        0.1805, 0.0722, 0.9505, 0,
                        0     , 0     , 0     , 1);

    // converts a XYZ color to the LMS space.
    const mat4 xyz2lms( 0.7328,-0.7036, 0.0030, 0,
                        0.4296, 1.6975, 0.0136, 0,
                       -0.1624, 0.0061, 0.9834, 0,
                        0     , 0     , 0     , 1);

    // Direct conversion from linear RGB to LMS
    const mat4 rgb2lms(xyz2lms*rgb2xyz);

    // And back from LMS to linear RGB
    const mat4 lms2rgb(inverse(rgb2lms));

    // To simulate color blindness we need to "remove" the data lost by the absence of
    // a cone. This cannot be done by just zeroing out the corresponding LMS component
    // because it would create a color outside of the RGB gammut.
    // Instead we project the color along the axis of the missing component onto a plane
    // within the RGB gammut:
    //  - since the projection happens along the axis of the missing component, a
    //    color blind viewer perceives the projected color the same.
    //  - We use the plane defined by 3 points in LMS space: black, white and
    //    blue and red for protanopia/deuteranopia and tritanopia respectively.

    // LMS space red
    const vec3& lms_r(rgb2lms[0].rgb);
    // LMS space blue
    const vec3& lms_b(rgb2lms[2].rgb);
    // LMS space white
    const vec3 lms_w((rgb2lms * vec4(1)).rgb);

    // To find the planes we solve the a*L + b*M + c*S = 0 equation for the LMS values
    // of the three known points. This equation is trivially solved, and has for
    // solution the following cross-products:
    const vec3 p0 = cross(lms_w, lms_b);    // protanopia/deuteranopia
    const vec3 p1 = cross(lms_w, lms_r);    // tritanopia

    // The following 3 matrices perform the projection of a LMS color onto the given plane
    // along the selected axis

    // projection for protanopia (L = 0)
    const mat4 lms2lmsp(  0.0000, 0.0000, 0.0000, 0,
                    -p0.y / p0.x, 1.0000, 0.0000, 0,
                    -p0.z / p0.x, 0.0000, 1.0000, 0,
                          0     , 0     , 0     , 1);

    // projection for deuteranopia (M = 0)
    const mat4 lms2lmsd(  1.0000, -p0.x / p0.y, 0.0000, 0,
                          0.0000,       0.0000, 0.0000, 0,
                          0.0000, -p0.z / p0.y, 1.0000, 0,
                          0     ,       0     , 0     , 1);

    // projection for tritanopia (S = 0)
    const mat4 lms2lmst(  1.0000, 0.0000, -p1.x / p1.z, 0,
                          0.0000, 1.0000, -p1.y / p1.z, 0,
                          0.0000, 0.0000,       0.0000, 0,
                          0     ,       0     , 0     , 1);

    // We will calculate the error between the color and the color viewed by
    // a color blind user and "spread" this error onto the healthy cones.
    // The matrices below perform this last step and have been chosen arbitrarily.

    // The amount of correction can be adjusted here.

    // error spread for protanopia
    const mat4 errp(    1.0, 0.7, 0.7, 0,
                        0.0, 1.0, 0.0, 0,
                        0.0, 0.0, 1.0, 0,
                          0,   0,   0, 1);

    // error spread for deuteranopia
    const mat4 errd(    1.0, 0.0, 0.0, 0,
                        0.7, 1.0, 0.7, 0,
                        0.0, 0.0, 1.0, 0,
                          0,   0,   0, 1);

    // error spread for tritanopia
    const mat4 errt(    1.0, 0.0, 0.0, 0,
                        0.0, 1.0, 0.0, 0,
                        0.7, 0.7, 1.0, 0,
                          0,   0,   0, 1);

    const mat4 identity;

    // And the magic happens here...
    // We construct the matrix that will perform the whole correction.

    // simulation: type of color blindness to simulate:
    // set to either lms2lmsp, lms2lmsd, lms2lmst
    mat4 simulation;

    // correction: type of color blindness correction (should match the simulation above):
    // set to identity, errp, errd, errt ([0] for simulation only)
    mat4 correction(0);

    switch (mType) {
        case ColorBlindnessType::Protanomaly:
            simulation = lms2lmsp;
            if (mMode == ColorBlindnessMode::Correction)
                correction = errp;
            break;
        case ColorBlindnessType::Deuteranomaly:
            simulation = lms2lmsd;
            if (mMode == ColorBlindnessMode::Correction)
                correction = errd;
            break;
        case ColorBlindnessType::Tritanomaly:
            simulation = lms2lmst;
            if (mMode == ColorBlindnessMode::Correction)
                correction = errt;
            break;
        case ColorBlindnessType::None:
            // We already caught this at the beginning of the method, but the
            // compiler doesn't know that
            break;
    }

    mColorTransform = lms2rgb *
        (simulation * rgb2lms + correction * (rgb2lms - simulation * rgb2lms));
}

} /* namespace android */
