package de.frajul.endlessroll.entities.tileLists;

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

import de.frajul.endlessroll.data.SynchronizedArrayList;
import de.frajul.endlessroll.entities.textures.Texture;
import de.frajul.endlessroll.levels.TileData;
import de.frajul.endlessroll.levels.worlds.World;
import de.frajul.endlessroll.main.GameLog;

@SuppressWarnings("serial")
public class TileList extends SynchronizedArrayList<Tile> {

    public enum Type {
        TERRAIN,
        CEILING;

        public float calculateTileHeightFromEdge(float edge) {
            switch (this) {
                case TERRAIN:
                    if (edge <= -0.6f)
                        return 0.4f;
                    return 1 + edge;
                case CEILING:
                    if (edge >= 0.6f)
                        return 0.4f;
                    return 1 - edge;
            }
            return 0;
        }

    }

    private Type type;
    private Texture texture;
    private float edge;
    private boolean endless;

    public TileList(Type type, Texture texture) {
        this.type = type;
        this.texture = texture;
    }

    public void loadData(World world, float edge, List<TileData> tileData) {
        this.texture = world.getTerrainTexture();
        if (type == Type.CEILING)
            this.texture = world.getCeilingTexture();
        this.endless = false;
        super.clear();
        float lastRightEdge = -10;
        for (TileData data : tileData) {
            float leftEdge = data.getX() - data.getWidth() / 2;
            float rightEdge = data.getX() + data.getWidth() / 2;
            if (Math.abs(lastRightEdge - leftEdge) < 0.1f)
                GameLog.i("!!! Too small gap found !!! " + toMeters(lastRightEdge) + "m; " + lastRightEdge + "-"+leftEdge+"; iRight="+tileData.indexOf(data));
            lastRightEdge = rightEdge;
            super.add(new Tile(type, texture, edge, data));
        }
        this.edge = edge;
        if (edge >= 1 || edge <= -1)
            super.clear();
    }

    private float toMeters(float value) {
        return ((int) (value * 20)) / 10f;
    }

    public void createEndless(World world, float edge) {
        loadData(world, edge, new ArrayList<TileData>());
        super.add(createEndlessTile(0));
        this.endless = true;
    }

    public void update(float cameraX) {
        if (!super.isEmpty()) {
            if (endless) {
                Tile last = super.get(super.size() - 1);
                if (last.getRightEdge() - cameraX < 3)
                    super.add(createEndlessTile(last.getRightEdge() + 2.5f));
            }
            if (super.get(0).getRightEdge() - cameraX < -3) {
                super.remove(0);
            }
        }
    }

    private Tile createEndlessTile(float x) {
        return new Tile(type, texture, edge, x, 5);
    }

    public float getEdge() {
        return edge;
    }

    public boolean isEndless() {
        return endless;
    }
}
