/*
 * Copyright © 2012 Linaro Limited
 *
 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
 *
 * glmark2 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * glmark2.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
 */
#include "gl-visual-config.h"
#include "util.h"
#include "log.h"

#include <vector>

GLVisualConfig::GLVisualConfig(const std::string &s) :
    red(1), green(1), blue(1), alpha(1), depth(1), buffer(1)
{
    std::vector<std::string> elems;

    Util::split(s, ':', elems);

    for (std::vector<std::string>::const_iterator iter = elems.begin();
         iter != elems.end();
         iter++)
    {
        std::vector<std::string> opt;

        Util::split(*iter, '=', opt);
        if (opt.size() == 2) {
            if (opt[0] == "r" || opt[0] == "red")
                red = Util::fromString<int>(opt[1]);
            else if (opt[0] == "g" || opt[0] == "green")
                green = Util::fromString<int>(opt[1]);
            else if (opt[0] == "b" || opt[0] == "blue")
                blue = Util::fromString<int>(opt[1]);
            else if (opt[0] == "a" || opt[0] == "alpha")
                alpha = Util::fromString<int>(opt[1]);
            else if (opt[0] == "d" || opt[0] == "depth")
                depth = Util::fromString<int>(opt[1]);
            else if (opt[0] == "buf" || opt[0] == "buffer")
                buffer = Util::fromString<int>(opt[1]);
        }
        else
            Log::info("Warning: ignoring invalid option string '%s' "
                      "in GLVisualConfig description\n",
                      iter->c_str());
    }
}

int
GLVisualConfig::match_score(const GLVisualConfig &target) const
{
    int score(0);

    /* 
     * R,G,B,A integer values are at most 8 bits wide (for current widespread
     * hardware), so we need to scale them by 4 to get them in the [0,32] range.
     */
    score += score_component(red, target.red, 4);
    score += score_component(green, target.green, 4);
    score += score_component(blue, target.blue, 4);
    score += score_component(alpha, target.alpha, 4);
    score += score_component(depth, target.depth, 1);
    score += score_component(buffer, target.buffer, 1);

    return score;
}

int
GLVisualConfig::score_component(int component, int target, int scale) const
{
    /* 
     * The maximum (positive) score that can be returned is based
     * on the maximum bit width of the components. We assume this to
     * be 32 bits, which is a reasonable assumption for current platforms.
     */
    static const int MAXIMUM_COMPONENT_SCORE = 32;
    static const int UNACCEPTABLE_COMPONENT_PENALTY = -1000;
    int score(0);

    if ((component > 0 && target == 0) ||
        (component == 0 && target > 0))
    {
        /* 
         * Penalize components that are not present but have been requested,
         * and components that have been excluded but are present.
         */
        score = UNACCEPTABLE_COMPONENT_PENALTY;
    }
    else if (component == target)
    {
        /* Reward exact matches with the maximum per component score */
        score = MAXIMUM_COMPONENT_SCORE;
    }
    else
    {
        /* 
         * Reward deeper than requested component values, penalize shallower
         * than requested component values. Because the ranges of component
         * values vary we use a scaling factor to even them out, so that the
         * score for all components ranges from [0,MAXIMUM_COMPONENT_SCORE).
         */
        score = scale * (component - target);
    }

    return score;
}
