//The texture loader
function TextureLoader(){

    var imageFiles = TDEMO.SYNC.getConfig().getImageFiles();
    var imagePath = TDEMO.SYNC.getConfig().getImagePath();

    var textures = {};
    var loader = new THREE.TextureLoader();
    var cubeLoader = new THREE.CubeTextureLoader();

    var loadReady = function(callback){
        for(var i = 0; i < imageFiles.length; ++i){
            if(!imageFiles[i].loaded){
                return false;
            }
        }
        callback(textures);
    };

    var textureOnLoad = function(index, one, callback){
        var info = imageFiles[index];
        if(info.loaded){
            if(one){
                callback(textures[info.id.toString()]);
            }
            else{
                loadReady(callback);
            }
        }
        else{
            if(info.cube === true){
                cubeLoader.load([imagePath+info.name, imagePath+info.name,
                    imagePath+info.name, imagePath+info.name,
                    imagePath+info.name, imagePath+info.name],
                function(texture){
                    texture.mapping = THREE.CubeReflectionMapping;
                    textures[info.id.toString()] = texture;
                    info.loaded = true;
                    
                    if(one){
                        callback(texture);
                    }
                    else{
                        loadReady(callback);
                    }
                },
                function(xhr){
                    console.log( (xhr.loaded / xhr.total * 100) + "% loaded");
                },
                function ( xhr ) {
                    console.log("An error happened when loading texture: ", info.id);
                    //Should we just stop or continue or what to do?
                });
            }
            else{
                loader.load(imagePath+info.name,
                function(texture){
                    texture.mapping = info.mapping !== undefined ? info.mapping : THREE.UVMapping;
                    texture.wrapS = info.wrapS !== undefined ? info.wrapS : THREE.ClampToEdgeWrapping;
                    texture.wrapT = info.wrapT !== undefined ? info.wrapT : THREE.ClampToEdgeWrapping;
                    texture.magFilter = info.magFilter !== undefined ? info.magFilter : THREE.LinearFilter;
                    texture.minFilter = info.minFilter !== undefined ? info.minFilter : THREE.LinearMipMapLinearFilter;
                    texture.format = info.format !== undefined ? info.format : THREE.RGBAFormat;
                    texture.flipY = info.flipY !== undefined ? info.flipY : true;

                    var repeat = info.repeat !== undefined ? info.repeat : [1, 1];
                    var offset = info.offset !== undefined ? info.offset : [0, 0];

                    texture.repeat.set(repeat[0], repeat[1]);
                    texture.offset.set(offset[0], offset[1]);

                    textures[info.id.toString()] = texture;
                    info.loaded = true;

                    if(one){
                        callback(texture);
                    }
                    else{
                        loadReady(callback);
                    }
                },
                function(xhr){
                    console.log( (xhr.loaded / xhr.total * 100) + "% loaded");
                },
                function ( xhr ) {
                    console.log("An error happened when loading texture: ", info.id);
                    //Should we just stop or continue or what to do?
                });
            }

        }
    };

    var customLoad = function(path, callback){
        loader.load(path,
        function(texture){
            callback(texture);
        },
        function(xhr){
            console.log( (xhr.loaded / xhr.total * 100) + "% loaded");
        },
        function(xhr){
            console.log("An error happened when loading texture: ", path);
            callback(false);
        });
    };

    var t = {
        loader : loader,

        //Loads all textures in the list and then calls the function given as parameter
        loadAll : function(cb){
            if(imageFiles.length < 1){
                loadReady(cb);
            }
            else{
                for(var i = 0; i < imageFiles.length; ++i){
                    textureOnLoad(i, false, cb);
                }
            }

        },

        //Loads one texture and then calls the function given as parameter
        loadOne : function(index, cb){
            textureOnLoad(index, true, cb);
        },

        loadOther : function(path, cb){
            customLoad(path, cb);
        },

        getTextures : function(){
            return textures;
        }
    }

    return t;
};
