package com.jan.scene;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.jan.Collision.Collision;
import com.jan.Collision.CollisionEvent;
import com.jan.entity.Renderable;
import com.jan.game.Display;
import com.jan.game.Game;

public class Scene{
    private World map;
    private Collision collision;
    
    private ArrayList<Entity> entities;
    private Game currState;

    private OrthographicCamera sceneCamera;
    
    public Scene(String mapData){
        super();
        entities = new ArrayList<>();
        TiledMap world = new TmxMapLoader().load(mapData);
        this.map = new World(world);
        sceneCamera = new OrthographicCamera((float)world.getProperties().get("TilesViewportWidth"), (float)world.getProperties().get("TilesViewportHeight"));
        Display.useCamera(sceneCamera);
        setScale((int)world.getProperties().get("tilewidth"), (int)world.getProperties().get("tileheight"));
        this.collision = new Collision(world);
        collision.loadColiders(map.getEntities());
        populate();
        currState = new GameLoader().loadState((String)world.getProperties().get("State"));
        currState.create(this);
        currState.start();
        
    }
    private void populate(){
        ArrayList<Renderable> renderables = map.getRenderables();
        for(int i = 0; i < renderables.size(); i++)
            entities.add(renderables.get(i));
    }
    private void setScale(int tilesWidth, int tileHeight){
        if(tilesWidth == tileHeight){
            Display.setScale(tileHeight);
            return;
        }
        System.out.println("Tile Width & Height must be equal");
    }
    

    public void render(){
        currState.update();
        collision.update(Gdx.graphics.getDeltaTime());
        map.render();
    }

    public Entity getEntity(String name){
        for(int i = 0; i < entities.size(); i++){
            if(entities.get(i).getEntityName().equals(name))
                return entities.get(i);
        }
        return null;
    }

    public void fireEvent(CollisionEvent event){ currState.catchEvent(event); }
}

class GameLoader{

    public Game loadState(String stateClass){
        try {
            Class gameClass = Class.forName(stateClass);
            Class[] types = {};
            Constructor constructor = gameClass.getConstructor(types);
            Object gamObject = constructor.newInstance();
            return (Game)gamObject;
        } 
        catch (ClassNotFoundException e) { e.printStackTrace();} 
        catch (NoSuchMethodException e) { e.printStackTrace();} 
        catch (SecurityException e) { e.printStackTrace();} 
        catch (InstantiationException e) { e.printStackTrace();} 
        catch (IllegalAccessException e) { e.printStackTrace();} 
        catch (IllegalArgumentException e) { e.printStackTrace();} 
        catch (InvocationTargetException e) { e.printStackTrace();}
        return null;
    }
}
