/**
* COLOR UTIL Library
 * - used for manipulation of colors
* */
var ColorUtil = (function(){
    var rgb_regex = /rgba?\((\d+), ?(\d+), ?(\d+)(?:, ?(\d*\.?\d+))?\)/;
    var getMax = function(arr){
        var max = arr[0];
        if(arr.length > 1){
            for(var i = 1; i < arr.length; i++){
                if(arr[i] > max) max = arr[i];
            }
        }
        return max;
    };
    var getMin = function(arr){
        var min = arr[0];
        if(arr.length > 1){
            for(var i = 1; i < arr.length; i++){
                if(arr[i] < min) min = arr[i];
            }
        }
        return min;
    };
    return{
        getHueFromRGB : function(rgb){
            var colors = rgb_regex.exec(rgb);
            // console.log(colors[1],colors[2],colors[3]);
            //console.log(rgb, colors);

            var R = ((colors[1]==0)?0.0000001:colors[1]) / 255;
            var G = ((colors[2]==0)?0.0000001:colors[2]) / 255;
            var B = ((colors[3]==0)?0.0000001:colors[3]) / 255;

            // This color adjust, has some edge cases that it doesn't account for,
            // The fallback is gracefull, so not the biggest issue currently.
            // TODO: revise this color adjustment if-block.
            if(R-B === 0 || R-G === 0 || R-G === 0){
                R+=0.0000001;
                G-=0.0000001;
                // returns false if white so that the saturation gets set to zero
                // and then it is not set to hue=0 which is red.
                return false;
            }

            //console.log('rgb:',R,G,B);
            var max = getMax([R,G,B]);
            var min = getMin([R,G,B]);
            var hue;
            switch(max){
                case R:
                    hue = (G-B)/(max-min);
                    break;
                case G:
                    hue = 2.0 + (B-R)/(max-min);
                    break;
                case B:
                    hue = 4.0 + (R-G)/(max-min);
                    break;
            }
            hue *= 60;
            hue = hue < 0? hue + 360:hue;
            return hue; // Returns in degrees
        },
        getLuminaceFromRGB : function(rgb, type='digital', fast=false){
            // Type = photometric OR Digital (default)
            // Fast = true=>use approximation
            // Math from: https://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
            var colors = rgb_regex.exec(rgb);
            //console.log(colors[1],colors[2],colors[3]);

            var R = ((colors[1]==0)?0.0000001:colors[1]) / 255;
            var G = ((colors[2]==0)?0.0000001:colors[2]) / 255;
            var B = ((colors[3]==0)?0.0000001:colors[3]) / 255;
            var luminance;
            if(!fast){
                if(type === 'photometric'){
                    luminance = 0.2126*R + 0.7152*G + 0.0722*B;
                } else {
                    luminance = 0.299*R + 0.587*G + 0.114*B;
                }
            } else {
                if(type === 'photometric'){
                    luminance = (R+R+B+G+G+G)/6;
                } else {
                    luminance = (R+R+R+B+G+G+G+G)>>3;
                }
            }
            return luminance;
        },
        luminanceDistance : function(color_array, reference_color, threshold=2, limit=1){
            var count = 0;
            for(var i = 0; i < color_array.length; i++) {
                if(Math.abs(reference_color - color_array[i]) < threshold){
                    count++;
                }
                //console.log('diff '+i+':', Math.abs(reference_color - color_array[i]));
            }
            return count;
        }
    };
})();

// console.log(base_color_override, hue_override, saturation_override, light_shift_override);
// Initialization code
if(document.querySelector('body')){
    
    var saturation = saturation_override || "20%";
    var styles = getComputedStyle(document.querySelector('body'));
    var newHue =  hue_override || ColorUtil.getHueFromRGB(base_color_override || styles.backgroundColor);
    if(true || (styles.backgroundColor && styles.backgroundColor !== '' && !isNaN(newHue) ) ){
        //console.log('generating custom colors');
        if(newHue == false){
            saturation = saturation_override || '0%';
            newHue = 0;
        }
        document.documentElement.style.setProperty('--primary-hue', newHue);
        document.documentElement.style.setProperty('--saturation', saturation) ;

        var customVars = getComputedStyle(document.documentElement);
        var colors = [
            parseInt(customVars.getPropertyValue('--lightest').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--verylight').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--lighter').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--light').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--med-light').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--medium').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--dark').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--darker').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--verydark').replace(/.*\((\d\d?\d?)%.*\).*/,"$1")),
            parseInt(customVars.getPropertyValue('--darkest').replace(/.*\((\d\d?\d?)%.*\).*/,"$1"))
        ];
        //console.log(colors);
        if(ColorUtil.luminanceDistance(colors, ColorUtil.getLuminaceFromRGB(base_color_override || styles.backgroundColor)*100, 2) !== 0){
            // console.log('light shift');
            var light_shift_factor = light_shift_override || '0.95';
            document.documentElement.style.setProperty('--light-shift-factor', light_shift_factor);
        }
    }
//console.log("hue: ",styles.getPropertyValue('--primary-hue'));
//console.log('luminance:',ColorUtil.getLuminaceFromRGB(styles.backgroundColor));
} else {
    // Wasn't included in the proper place
    console.warn("ColorUtil: needs to be included right after the body tag.");
}

