package de.samdev.colorrunner.game.world.map.provider;

import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import de.samdev.colorrunner.game.renderer.AbstractGameRenderer;
import de.samdev.colorrunner.game.world.CRGameWorld;
import de.samdev.colorrunner.game.world.entities.CRGameEntity;
import de.samdev.colorrunner.game.world.entities.gameentities.floor.FloorTileEntity;
import de.samdev.colorrunner.game.world.map.CRMapStorage;
import de.samdev.colorrunner.game.world.map.CRTiledMap;
import de.samdev.colorrunner.game.world.map.MapSection;

public class EndlessMapProvider extends MapProvider {
    private final Random random;

    public List<MapSection> sections;
    private float mapRightBoundary = 0;

    public EndlessMapProvider(long seed) {
        random = new Random(seed);
    }

    @Override
    public void init(CRGameWorld world) {
        sections = new ArrayList<MapSection>();
        mapRightBoundary = appendMap(world, CRMapStorage.map_start, new Vector2(0, 0));
    }

    @Override
    public boolean isNextEndlessMenu(){
        return true;
    }

    @Override
    public MapProvider createNew() {
        EndlessMapProvider endlessMapProvider = new EndlessMapProvider(System.currentTimeMillis());
        return endlessMapProvider;
    }

    @Override
    public void update(CRGameWorld world, Rectangle player)
    {
        while (player.x + AbstractGameRenderer.MAX_GAME_WIDTH*2 > mapRightBoundary) {
            float width = appendMap(world, CRMapStorage.getMap(random), new Vector2(mapRightBoundary, 0));
            mapRightBoundary += width;
        }
    }

    private float appendMap(CRGameWorld world, CRTiledMap map, Vector2 pos) {
        int height = map.getHeight();
        int width = map.getWidth();

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                float px = pos.x + x * FloorTileEntity.FLOORTILE_WIDTH;
                float py =  pos.y + (height - y) * FloorTileEntity.FLOORTILE_WIDTH;

                CRGameEntity e = CRTiledMap.CreateTile(world, map.getGID(x, y), px, py);
                if (e != null) world.addEntity(e);
            }
        }

        sections.add(new MapSection(pos.x, width * FloorTileEntity.FLOORTILE_WIDTH, map.name));

        return width * FloorTileEntity.FLOORTILE_WIDTH;
    }

    public MapSection getCurrentSection(Rectangle player) {
        for (MapSection sec : sections) {
            if (sec.start <= player.x && sec.end >= player.x)
                return sec;
        }

        return new MapSection(0, 0, "NULL");
    }
}
