package zero1hd.polyjet.audio.map;

import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.utils.Array;

import zero1hd.polyjet.audio.AudioData;
import zero1hd.polyjet.entity.Entities;

public class GamePlayMap {
	private AudioData musicData;
	private float playTime;
	private Array<MapWindowData> spawnList;
	private boolean building;
	private int index;
	private int absoluteIndex;
	/**
	 * GamePlayMap is what the game area will use to generate entities and judge current audio data
	 * @param audioData audio data
	 */
	public GamePlayMap(AudioData audioData) {
		this.musicData = audioData;
		spawnList = new Array<>();
	}
	
	/**
	 * returns audio data
	 * @return
	 */
	public Music getPlayableClip() {
		return musicData.getPlaybackMusic();
	}
	
	/**
	 * returns the runtime time of the overall song
	 * @return
	 */
	public float getPlayTime() {
		return playTime;
	}

	/**
	 * call this when beginning to build map
	 */
	public void beginBuild() {
		building = true;
		spawnList.clear();
		spawnList.add(new MapWindowData());
		index = 0;
		absoluteIndex = 0;
	}

	/**
	 * call this when finishing building map
	 */
	public void endBuild() {
		building = false;
		index = 0;
		absoluteIndex = 0;
	}

	
	/**
	 * used to add data types for what entity to spawn at that index position
	 * cannot be null.
	 * @param entityType what type of entity to spawn
	 * @param parameters the arguments for the entity. It is important to have the same amount of parameters the entity requires to spawn
	 */
	
	public void addToMap(Entities entityType, float... parameters) {
		if (building && entityType != null && parameters != null) {
			spawnList.get(index).addEntity(new EntitySpawnInfo(entityType, parameters));
		}
	}
	
	/**
	 * Moves onto the next window of the map for the song
	 */
	public void nextWindow() {
		absoluteIndex++;
		resetIndex();
		if (building) {
			spawnList.add(new MapWindowData());
		}
	}
	
	/**
	 * moves to the previous window to make edits to that frame.
	 */
	public void previousWindow() {
		absoluteIndex--;
		resetIndex();
	}
	/**
	 * use this to add rest for current index position
	 */
	public void addNullToMap() {
		if (building) {
			spawnList.set(index, null);
		}
	}
	
	public MapWindowData nextWindowData() {
		if (index != musicData.getReadIndex()) {
			absoluteIndex = musicData.getReadIndex();
			resetIndex();
			return spawnList.get(index);
		}
		return null;
	}
	
	/**
	 * set retrieve entity index position.
	 * @param index
	 */
	public void setIndex(int index) {
		this.index = index;
	}
	
	public boolean isCurrentNull() {
		return spawnList.get(index) == null ? true : false;
	}
	
	public void resetIndex() {
		index = absoluteIndex;
	}
}
