/*
 * 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)
 */
#ifndef GLMARK2_MODEL_H_
#define GLMARK2_MODEL_H_

#include <stdint.h>
#include <string>
#include <vector>
#include <map>
#include "vec.h"

// Forward declare the mesh object.  We don't need the whole header here.
class Mesh;

enum ModelFormat
{
    MODEL_INVALID,
    MODEL_3DS,
    MODEL_OBJ
};

/**
 * A descriptor for a model file.
 */
class ModelDescriptor
{
    std::string name_;
    std::string pathname_;
    ModelFormat format_;
    ModelDescriptor();
public:
    ModelDescriptor(const std::string& name, ModelFormat format,
                    const std::string& pathname) :
        name_(name),
        pathname_(pathname),
        format_(format) {}
    ~ModelDescriptor() {}
    const std::string& pathname() const { return pathname_; }
    ModelFormat format() const { return format_; }
};

typedef std::map<std::string, ModelDescriptor*> ModelMap;

/**
 * A model as loaded from a 3D object data file.
 */
class Model
{
public:

    typedef enum {
        AttribTypePosition = 1,
        AttribTypeNormal,
        AttribTypeTexcoord,
        AttribTypeTangent,
        AttribTypeBitangent,
        AttribTypeCustom
    } AttribType;

    Model() : gotTexcoords_(false) {}
    ~Model() {}

    bool load(const std::string& name);

    bool needTexcoords() const { return !gotTexcoords_; }
    void calculate_texcoords();
    void calculate_normals();
    void convert_to_mesh(Mesh &mesh);
    void convert_to_mesh(Mesh &mesh,
                         const std::vector<std::pair<AttribType, int> > &attribs);
    const LibMatrix::vec3& minVec() const { return minVec_; }
    const LibMatrix::vec3& maxVec() const { return maxVec_; }
    static const ModelMap& find_models();
private:
    // If the model we loaded contained texcoord data...
    bool gotTexcoords_;
    struct Face {
        uint32_t a, b, c;
        uint16_t face_flags;
    };

    struct Vertex {
        LibMatrix::vec3 v;
        LibMatrix::vec3 n;
        LibMatrix::vec2 t;
        LibMatrix::vec3 nt;
        LibMatrix::vec3 nb;
    };

    struct Object {
        Object(const std::string &name) : name(name) {}
        std::string name;
        std::vector<Vertex> vertices;
        std::vector<Face> faces;
    };

    void append_object_to_mesh(const Object &object, Mesh &mesh,
                               int p_pos, int n_pos, int t_pos,
                               int nt_pos, int nb_pos);
    bool load_3ds(const std::string &filename);
    bool load_obj(const std::string &filename);

    // For vertices of the bounding box for this model.
    void compute_bounding_box(const Object& object);
    LibMatrix::vec3 minVec_;
    LibMatrix::vec3 maxVec_;
    std::vector<Object> objects_;
};

#endif
