
#include <WFX/scene/TextureManager.h>

#include <WFX/lang/WFXException.h>

using namespace WFX;
using namespace WFX::scene;
using namespace WFX::lang;

Texture::Texture(const WFX::io::File& f, UInt h) : File(f), 
                                                   Handle(h), 
                                                   UserCount(0),
                                                   Loaded(false) {
    Name = f.toString();
}

Texture::Texture(const WFX::io::File& f, UInt h, const std::string& name) : File(f), 
                                                                            Handle(h), 
                                                                            Name(name),
                                                                            UserCount(0),
                                                                            Loaded(false) {
}

Texture::Texture() : File("/dev/null"), Handle(0), UserCount(0), Loaded(false) {
}

Texture::~Texture() {
}

void Texture::incUsers() {
    UserCount++;
}

///////////////////////////////////// Manager

const UInt TextureManager::MaxTextures = 1024;

TextureManager::TextureManager() : Textures(MaxTextures) {
    TexCount = 0;
}

TextureManager::~TextureManager() {
}

//UInt TextureManager::regTexture(const WFX::io::File& f) {
UInt TextureManager::regTexture(const std::string& name) {
    WFX::io::File f(name);
    UInt th = findTexture(f);
    if (th == 0) {
        th = nextHandle();

        //create Texture
        Texture tx(f, th, name);
        
        //insert Texture
        Textures[th] = tx; 

    }
    //inc user count
    Textures[th].incUsers();
    //inc texcount
    TexCount++;
    
    LOG("register " << f.toString() << " to " << th);
    return th;
}

UInt TextureManager::findTexture(const WFX::io::File& f) {
    std::vector<Texture>::iterator it;
    for (it = Textures.begin(); it != Textures.end(); it++) {
        if ((*it).getFile() == f)
            return (*it).getHandle();
    }
    return 0;
}

void TextureManager::bindTexture(UInt h) {
    if (h == 0)
        return;
    //check if loaded
    if (!Textures[h].isLoaded()) {
        try {
            loadTexture(Textures[h]);
            Textures[h].setLoaded(true);
        } catch (WFXException& e) {
            RETHROW(e, "unable to load Texture " << h);
        }
    }
}

UInt TextureManager::nextHandle() {
    static UInt handle = 0;
    return ++handle;
}

bool TextureManager::loadTexture(const WFX::scene::Texture& t) {
    THROW("texture loading not implemented...");
}

