
#ifndef WFOBJ_H
#define WFOBJ_H

#include "FileLoader/FileLoader.h"
#include "TextureLoader/TextureLoader.h"
#include <GL/gl.h>
#include <vector>
#include <string>
#include <map>

class WFObj
{
public:
    WFObj();
    WFObj(FileLoader & fileLoader);
    WFObj(TextureLoader & textureLoader);
    WFObj(FileLoader & fileLoader, TextureLoader & textureLoader);
    ~WFObj();

    class WFMtl
    {
    public:
        WFMtl(WFObj * obj) { m_obj = obj; }
        bool load(const FileLoader::Path & path);
        void renderBegin(const std::string & mtlname,
                bool doTextureInfo = true,
                bool enableBlending = false);
        void renderEnd(const std::string & mtlname,
                bool doTextureInfo = true,
                bool enableBlending = false);

    protected:
        /* methods */
        void clear();
        void processInputLine(const std::string & input);
        void pushAttributes();
        bool load(std::istream & istr, unsigned int size);

        /* variables */
        std::map< std::string, std::vector< std::vector<std::string> > > m_data;
        std::string m_currentMaterialName;
        bool m_attributesPushed;
        FileLoader::Path m_path;
        WFObj * m_obj;
    };

    class WFFileLoader : public FileLoader
    {
        public:
            virtual int getSize(const Path & path);
            virtual Buffer load(const Path & path);
    };

    bool load(const FileLoader::Path & path);
    GLuint render(bool doTextureInfo = true,
            bool enableBlending = false);
    const float * const getAABB() { return m_aabb; }

protected:
    /* types */
    class Vertex
    {
    public:
        float operator[](int idx) const { return data[idx]; }
        float & operator[](int idx) { return data[idx]; }
        float * getData() { return data; }
    private:
        float data[4];
    };

    /* methods */
    void init(FileLoader * fileLoader = NULL,
            TextureLoader * textureLoader = NULL);
    void clear();
    void processInputLine(const std::string & input);
    Vertex readVertex(const std::vector<std::string> & parts);
    void parseVertexIndices(const std::string & vtxref, int * ret);
    void updateAABB(const float * const vertex);
    bool load(std::istream & istr, unsigned int size);

    /* variables */
    std::vector< std::vector<std::string> > m_data;
    FileLoader::Path m_path;
    float m_aabb[6];
    bool m_loadedVertex;
    FileLoader * m_fileLoader;
    TextureLoader * m_textureLoader;
    bool m_iCreatedFileLoader;
};

#endif
