// vim: et:ts=4:sw=4:sts=4:ft=javascript

/*@
Ox.Theme <f> get/set theme
    ()      -> <s>  Get current theme
    (theme) -> <s>  Set current theme
    theme <s>   name of theme
@*/

Ox.Theme = (function() {

    var that = function(theme) {
        return theme ? setTheme(theme) : getTheme();
    };

    function getTheme() {
        var theme = '';
        Ox.forEach(Ox.UI.$body.attr('class').split(' '), function(className) {
            if (Ox.startsWith(className, 'OxTheme')) {
                theme = className.replace('OxTheme', '').toLowerCase();
                return false;
            }
        });
        return theme;
    }

    function renderElement(val, type) {
        var $element, background, color, lightness = that.lightness[getTheme()];
        if (type == 'hue') {
            background = Ox.rgb(val, 1, lightness.background).map(function(val) {
                return Math.round(val);
            });
            color = Ox.rgb(val, 1, lightness.color).map(function(val) {
                return Math.round(val);
            });
        } else if (type == 'saturation') {
            background = Ox.range(7).map(function(i) {
                return Ox.rgb(i * 60, val, lightness.background).map(function(val) {
                    return Math.round(val);
                });
            });
            color = Ox.rgb(0, 0, lightness.color).map(function(val) {
                return Math.round(val);
            });
        } else if (type == 'lightness') {
            background = Ox.range(3).map(function() {
                return Math.round(val * 255);
            });
            color = Ox.range(3).map(function() {
                return Math.round(val * 255) + (val < 0.5 ? 128 : -128);
            });
        } else if (type == 'gradient') {
            background = Ox.range(2).map(function(i) {
                return Ox.rgb(val, 1, lightness.background).map(function(val) {
                    return Math.round(val + (i == 0 ? 16 : -16));
                });
            });
            color = Ox.rgb(val, 1, lightness.color).map(function(val) {
                return Math.round(val);
            });
        }
        $element = $('<div>')
            .addClass(
                'OxColor'
                + (type == 'lightness' ? '' : ' OxColor' + Ox.toTitleCase(type))
            )
            .css({
                color: 'rgb(' + color.join(', ') + ')'
            })
            .data(type == 'lightness' ? {} : {OxColor: val});
        if (Ox.isNumber(background[0])) {
            $element.css({
                background: 'rgb(' + background.join(', ') + ')'
            });
        } else {
            ['moz', 'o', 'webkit'].forEach(function(browser) {
                $element.css({
                    background: '-' + browser + '-linear-gradient('
                        + (background.length == 2 ? 'top' : 'left') + ', '
                        + background.map(function(rgb, i) {
                            return 'rgb(' + rgb.join(', ') + ') '
                                + Math.round(i * 100 / (background.length - 1)) + '%';
                        }).join(', ')
                        + ')'
                });
            });
        }
        return $element;
    };

    function setTheme(theme) {
        var currentTheme = getTheme();
        if (theme != currentTheme) {
            Ox.UI.$body
                .addClass('OxTheme' + Ox.toTitleCase(theme))
                .removeClass('OxTheme' + Ox.toTitleCase(currentTheme));
            $('.OxColor').each(function() {
                var element = this;
                Ox.forEach(['hue', 'saturation', 'gradient'], function(type) {
                    if (element.className.indexOf('OxColor' + Ox.toTitleCase(type)) > -1) {
                        var $element = $(element),
                            val = $element.data('OxColor'),
                            $element_ = renderElement(val, type);
                            $element.css({
                                background: $element_.css('background'),
                                color: $element_.css('color')
                            });
                        return false;
                    }
                });
            });
            $('img:not(.OxVideo)').add('input[type="image"]:not(.OxVideo)').each(function(element) {
                var $element = $(this),
                    src = $element.attr('src');
                $element.attr({
                    src: Ox.UI.getImageURL(Ox.UI.getImageName(src), theme)
                });
            });
        }
        if (localStorage) {
            localStorage.OxTheme = theme;
        }
        return that;
    }

    that.formatColor = function(val, type) {
        return renderElement(val, type)
            .css({textAlign: 'center'})
            .html(Ox.formatNumber(val, 3));
    };

    that.formatColorLevel = function(index, values, hueRange) {
        hueRange = hueRange || (Ox.isBoolean(index) ? [0, 120] : [120, 0]);
        var step = (hueRange[1] - hueRange[0]) / (values.length - 1),
            hue = hueRange[0] + index * step;
        return renderElement(hue, 'gradient')
            .css({textAlign: 'center'})
            .html(values[+index]);
    };

    that.lightness = {
        classic: {background: 0.75, color: 0.25},
        modern: {background: 0.25, color: 0.75}
    };

    return that;

}());
