/*
 * Copyright © 2008 Ben Smith
 * Copyright © 2010-2011 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:
 *  Ben Smith (original glmark benchmark)
 *  Alexandros Frantzis (glmark2)
 *  Jesse Barker (glmark2)
 */
#include "scene.h"
#include "mat.h"
#include "stack.h"
#include "vec.h"
#include "log.h"
#include "util.h"
#include "shader-source.h"
#include "model.h"

#include <cmath>
#include <sstream>

using LibMatrix::vec3;
using std::string;
using std::endl;

SceneShading::SceneShading(Canvas &pCanvas) :
    Scene(pCanvas, "shading"),
    orientModel_(false)
{
    const ModelMap& modelMap = Model::find_models();
    std::string optionValues;
    for (ModelMap::const_iterator modelIt = modelMap.begin();
         modelIt != modelMap.end();
         modelIt++)
    {
        static bool doSeparator(false);
        if (doSeparator)
        {
            optionValues += ",";
        }
        const std::string& curName = modelIt->first;
        optionValues += curName;
        doSeparator = true;
    }
    options_["shading"] = Scene::Option("shading", "gouraud",
                                        "Which shading method to use",
                                        "gouraud,blinn-phong-inf,phong");
    options_["num-lights"] = Scene::Option("num-lights", "1",
            "The number of lights applied to the scene (phong only)");
    options_["model"] = Scene::Option("model", "cat", "Which model to use",
                                      optionValues);
}

SceneShading::~SceneShading()
{
}

bool
SceneShading::load()
{
    rotationSpeed_ = 36.0f;

    running_ = false;

    return true;
}

void
SceneShading::unload()
{
    mesh_.reset();
}

static string
get_fragment_shader_source(const string& frg_file, unsigned int lights)
{
    ShaderSource source(frg_file);

    static const string lightPositionName("LightSourcePosition");
    static const string lightColorName("LightColor");
    static const string callCompute("    gl_FragColor += compute_color(");
    static const string commaString(", ");
    static const string rParenString(");");
    std::stringstream doLightSS;
    doLightSS << string("    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
    doLightSS << endl;
    float theta(2.0 * M_PI / lights);
    float phi(theta / 2.0);
    float intensity(0.8 / lights);
    LibMatrix::vec4 lightCol(intensity, intensity, intensity, 1.0);
    for (unsigned int l = 0; l < lights; l++)
    {
        // Construct constant names for the light position and color and add it
        // to the list of constants for the shader.
        string indexString(Util::toString(l));
        string curLightPosition(lightPositionName + indexString);
        string curLightColor(lightColorName + indexString);
        float sin_theta(sin(theta * l));
        float cos_theta(cos(theta * l));
        float sin_phi(sin(phi * l));
        float cos_phi(cos(phi * l));
        LibMatrix::vec4 lightPos(cos_phi * sin_theta, cos_phi * cos_theta, sin_phi, 1.0);
        source.add_const(curLightPosition, lightPos);
        source.add_const(curLightColor, lightCol);

        // Add the section of source to the substantive...
        doLightSS << callCompute;
        doLightSS << curLightPosition;
        doLightSS << commaString;
        doLightSS << curLightColor;
        doLightSS << rParenString;
        doLightSS << endl;
    }

    source.replace("$DO_LIGHTS$", doLightSS.str());

    return source.str();
}

bool
SceneShading::setup()
{
    if (!Scene::setup())
        return false;

    static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
    static const LibMatrix::vec4 materialDiffuse(0.0f, 0.0f, 1.0f, 1.0f);

    // Calculate half vector for blinn-phong shading model
    LibMatrix::vec3 halfVector(lightPosition[0], lightPosition[1], lightPosition[2]);
    halfVector.normalize();
    halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
    halfVector.normalize();

    // Load and add constants to shaders
    std::string vtx_shader_filename;
    std::string frg_shader_filename;
    const std::string &shading = options_["shading"].value;
    ShaderSource vtx_source;
    ShaderSource frg_source;
    if (shading == "gouraud") {
        vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.vert";
        frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag";
        frg_source.append_file(frg_shader_filename);
        vtx_source.append_file(vtx_shader_filename);
        vtx_source.add_const("LightSourcePosition", lightPosition);
        vtx_source.add_const("MaterialDiffuse", materialDiffuse);
    }
    else if (shading == "blinn-phong-inf") {
        vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.vert";
        frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.frag";
        frg_source.append_file(frg_shader_filename);
        frg_source.add_const("LightSourcePosition", lightPosition);
        frg_source.add_const("LightSourceHalfVector", halfVector);
        vtx_source.append_file(vtx_shader_filename);
    }
    else if (shading == "phong") {
        vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.vert";
        frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.frag";
        unsigned int num_lights = Util::fromString<unsigned int>(options_["num-lights"].value);
        string fragsource = get_fragment_shader_source(frg_shader_filename, num_lights);
        frg_source.append(fragsource);
        frg_source.add_const("MaterialDiffuse", materialDiffuse);
        vtx_source.append_file(vtx_shader_filename);
    }

    if (!Scene::load_shaders_from_strings(program_, vtx_source.str(),
                                          frg_source.str()))
    {
        return false;
    }

    Model model;
    const std::string& whichModel(options_["model"].value);
    bool modelLoaded = model.load(whichModel);

    if(!modelLoaded)
        return false;

    // Now that we're successfully loaded, there are a few quirks about
    // some of the known models that we need to account for.  The draw
    // logic for the scene wants to rotate the model around the Y axis.
    // Most of our models are described this way.  Some need adjustment
    // (an additional rotation that gets the model into the correct
    // orientation).
    //
    // Here's a summary:
    //
    // Angel rotates around the Y axis
    // Armadillo rotates around the Y axis
    // Buddha rotates around the X axis
    // Bunny rotates around the Y axis
    // Dragon rotates around the X axis
    // Horse rotates around the Y axis
    if (whichModel == "buddha" || whichModel == "dragon")
    {
        orientModel_ = true;
        orientationAngle_ = -90.0;
        orientationVec_ = vec3(1.0, 0.0, 0.0);
    }
    else if (whichModel == "armadillo")
    {
        orientModel_ = true;
        orientationAngle_ = 180.0; 
        orientationVec_ = vec3(0.0, 1.0, 0.0);
    }

    model.calculate_normals();

    /* Tell the converter that we only care about position and normal attributes */
    std::vector<std::pair<Model::AttribType, int> > attribs;
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
    attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));

    model.convert_to_mesh(mesh_, attribs);

    mesh_.build_vbo();

    /* Calculate a projection matrix that is a good fit for the model */
    vec3 maxVec = model.maxVec();
    vec3 minVec = model.minVec();
    vec3 diffVec = maxVec - minVec;
    centerVec_ = maxVec + minVec;
    centerVec_ /= 2.0;
    float diameter = diffVec.length();
    radius_ = diameter / 2;
    float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
    fovy /= M_PI;
    fovy *= 180.0;
    float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
    perspective_.setIdentity();
    perspective_ *= LibMatrix::Mat4::perspective(fovy, aspect, 2.0, 2.0 + diameter);

    program_.start();

    std::vector<GLint> attrib_locations;
    attrib_locations.push_back(program_["position"].location());
    attrib_locations.push_back(program_["normal"].location());
    mesh_.set_attrib_locations(attrib_locations);

    currentFrame_ = 0;
    rotation_ = 0.0f;
    running_ = true;
    startTime_ = Util::get_timestamp_us() / 1000000.0;
    lastUpdateTime_ = startTime_;

    return true;
}

void
SceneShading::teardown()
{
    program_.stop();
    program_.release();

    Scene::teardown();
}

void
SceneShading::update()
{
    Scene::update();

    double elapsed_time = lastUpdateTime_ - startTime_;

    rotation_ = rotationSpeed_ * elapsed_time;
}

void
SceneShading::draw()
{
    // Load the ModelViewProjectionMatrix uniform in the shader
    LibMatrix::Stack4 model_view;
    model_view.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_));
    model_view.rotate(rotation_, 0.0f, 1.0f, 0.0f);
    if (orientModel_)
    {
        model_view.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
    }
    LibMatrix::mat4 model_view_proj(perspective_);
    model_view_proj *= model_view.getCurrent();

    program_["ModelViewProjectionMatrix"] = model_view_proj;

    // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
    // inverse transpose of the model view matrix.
    LibMatrix::mat4 normal_matrix(model_view.getCurrent());
    normal_matrix.inverse().transpose();
    program_["NormalMatrix"] = normal_matrix;

    // Load the modelview matrix itself
    program_["ModelViewMatrix"] = model_view.getCurrent();

    mesh_.render_vbo();
}

Scene::ValidationResult
SceneShading::validate()
{
    static const double radius_3d(std::sqrt(3.0));

    if (rotation_ != 0)
        return Scene::ValidationUnknown;

    Canvas::Pixel ref;

    Canvas::Pixel pixel = canvas_.read_pixel(canvas_.width() / 3,
                                             canvas_.height() / 3);

    const std::string &filter = options_["shading"].value;

    if (filter == "gouraud")
        ref = Canvas::Pixel(0x00, 0x00, 0x2d, 0xff);
    else if (filter == "blinn-phong-inf")
        ref = Canvas::Pixel(0x1a, 0x1a, 0x3e, 0xff);
    else if (filter == "phong" && options_["num-lights"].value == "1")
        ref = Canvas::Pixel(0x05, 0x05, 0xad, 0xff);
    else
        return Scene::ValidationUnknown;

    double dist = pixel.distance_rgb(ref);

    if (dist < radius_3d + 0.01) {
        return Scene::ValidationSuccess;
    }
    else {
        Log::debug("Validation failed! Expected: 0x%x Actual: 0x%x Distance: %f\n",
                    ref.to_le32(), pixel.to_le32(), dist);
        return Scene::ValidationFailure;
    }
}
