package electrosphere.engine.loadingthreads;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

import electrosphere.client.terrain.cells.VoxelTextureAtlas;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.queue.QueuedTexture;
import electrosphere.game.data.voxel.VoxelData;
import electrosphere.game.data.voxel.VoxelType;
import electrosphere.logger.LoggerInterface;
import electrosphere.util.FileUtils;

/**
 * The intention of this thread is to load basic assets that the engine should generally have available from the start.
 * Examples:
 *  - Texture Atlas for terrain
 *  - Icons for items
 */
public class InitialAssetLoading implements Runnable {
    
    //tracks whether this thread is still doing work or not
    boolean loading = true;

    /**
     * Loads basic data
     */
    public void LoadData(){

    
        loadTextureAtlas();
        LoggerInterface.loggerEngine.INFO("Finished loading texture atlas");
        
        loading = false;
    }

    /**
 * Gets whether the thread is still loading or not
     * @return true if loading, false otherwise
     */
    public boolean isLoading(){
        return loading;
    }

    /**
     * Loads the texture atlas
     */
    private void loadTextureAtlas(){
        //terrain texture atlas
        Globals.profiler.beginCpuSample("createVoxelTextureAtlas");
        VoxelData data = Globals.gameConfigCurrent.getVoxelData();
        int iterator = 0;
        BufferedImage image = new BufferedImage(VoxelTextureAtlas.ATLAS_DIM, VoxelTextureAtlas.ATLAS_DIM, BufferedImage.TYPE_4BYTE_ABGR);
        Graphics graphics = image.getGraphics();
        for(VoxelType type : data.getTypes()){
            if(type.getTexture() != null){
                int offX = iterator % VoxelTextureAtlas.ELEMENTS_PER_ROW;
                int offY = iterator / VoxelTextureAtlas.ELEMENTS_PER_ROW;
                try {
                    BufferedImage newType = ImageIO.read(FileUtils.getAssetFile(type.getTexture()));
                    int drawX = VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offX;
                    int drawY = VoxelTextureAtlas.ATLAS_DIM - VoxelTextureAtlas.ATLAS_ELEMENT_DIM - VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offY;
                    graphics.drawImage(newType, drawX, drawY, null);
                } catch (IOException e) {
                    LoggerInterface.loggerRenderer.ERROR("Texture atlas failed to find texture " + type.getTexture(), e);
                }
                //put coords in map
                Globals.voxelTextureAtlas.putTypeCoord(type.getId(),iterator);

                //iterate
                iterator++;
            }
        }
        Globals.profiler.endCpuSample();
        
        //queue to asset manager
        QueuedTexture atlasQueuedTexture = new QueuedTexture(image);
        Globals.assetManager.queuedAsset(atlasQueuedTexture);


        //wait the texture to be loaded
        while(!atlasQueuedTexture.hasLoaded()){
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException e) {
                LoggerInterface.loggerEngine.ERROR("failed to sleep", e);
            }
        }

        
        //construct texture atlas from buffered image
        Globals.voxelTextureAtlas.setSpecular(atlasQueuedTexture.getTexture());
        Globals.voxelTextureAtlas.setNormal(atlasQueuedTexture.getTexture());
    }

    @Override
    public void run(){
        this.LoadData();
    }
    

}
