/*
 * 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 {

Daltonizer::Daltonizer() :
    mType(deuteranomaly), mMode(simulation), mDirty(true) {
}

Daltonizer::~Daltonizer() {
}

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

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

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

void Daltonizer::update() {
    // 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);

    // control: simulation post-correction (used for debugging):
    // set to identity or lms2lmsp, lms2lmsd, lms2lmst
    mat4 control;
    switch (mType) {
        case protanopia:
        case protanomaly:
            simulation = lms2lmsp;
            if (mMode == Daltonizer::correction)
                correction = errp;
            break;
        case deuteranopia:
        case deuteranomaly:
            simulation = lms2lmsd;
            if (mMode == Daltonizer::correction)
                correction = errd;
            break;
        case tritanopia:
        case tritanomaly:
            simulation = lms2lmst;
            if (mMode == Daltonizer::correction)
                correction = errt;
            break;
    }

    if (true) {
        control = simulation;
    }

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

} /* namespace android */
