package zero1hd.rhythmbullet.ui.components;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.utils.FloatArray;

import zero1hd.rhythmbullet.audio.MusicDataPack;

public class AudioGraphRelation extends Actor {
	private MusicDataPack audioData;
	ShapeRenderer shapeRender;
	FloatArray mainGraph;
	FloatArray overlayGraph;
	int dataIndex;
	int displayMode;
	public float normalDataG1 = 1f, normalDataG2 = 1f, avgG1 = 1f, avgG2 = 1f;
	float scale;
	public AudioGraphRelation(int graphSizeW, int graphSizeH) {
		shapeRender = new ShapeRenderer();		
		setSize(graphSizeW, graphSizeH);
		scale = graphSizeH;
	}
	
	public void setAudioDataIndex(int audioDataIndex) {
		this.dataIndex = audioDataIndex;
	}
	
	@Override
	public void draw(Batch batch, float parentAlpha) {
		batch.end();
		shapeRender.begin(ShapeType.Line);
		shapeRender.setColor(0f, 0f, 0f, 0.35f);
		shapeRender.rect(getX(), getY(), getWidth(), getHeight());
		if (overlayGraph != null) {
			if (Gdx.input.isKeyPressed(Keys.COMMA)) {
				if (scale > 0.05f) {
					scale -= 0.25f;
				}
			} else if (Gdx.input.isKeyPressed(Keys.PERIOD)) {
				if (scale < getHeight()*2) {
					scale += 0.4f;
				}
			}
			if (Gdx.input.isKeyJustPressed(Keys.M)) {
				Gdx.app.debug("Graph", "Switching to another graph.");
				displayMode++;
				if (displayMode == 3) {
					displayMode = 0;
				}
			}
		}
		
		switch (displayMode) {
		case 0:
			shapeRender.setColor(1f, 0f, 0f, 1f);
			for (int x = 0; x < getHeight() -1; x++) {
				try {
					shapeRender.line(
							getX()+x,
							getY(), 
							getX()+x+1,
							(int) ((mainGraph.get((int) (dataIndex+x +1 -getWidth()/2))/normalDataG1)*scale)+getY());
				} catch (NullPointerException | IndexOutOfBoundsException e) {
				}
				shapeRender.line(
						getX(), 
						MathUtils.round(scale*(avgG1/normalDataG1))+getY(),
						getWidth() + getX(),
						MathUtils.round(scale*(avgG1/normalDataG1))+getY());
			}

		case 1:
			shapeRender.setColor(0f, 0f, 1f, 0.75f);
			for (int x = 0; x < getHeight() -1; x++) {
				try {
					shapeRender.line(
							getX()+x,
							getY(),
							getX()+x+1,
							(int) ((overlayGraph.get((int) (dataIndex+x +1 -getWidth()/2))/normalDataG2)*scale)+getY());
				} catch (NullPointerException | IndexOutOfBoundsException e) {
				}
				shapeRender.line(
						getX(), 
						MathUtils.round(scale*(avgG2/normalDataG2)) + getY(),
						getWidth() + getX(), 
						MathUtils.round(scale*(avgG2/normalDataG2))+getY());
			}
			break;
		case 2:
			shapeRender.setColor(1f, 0f, 0f, 0.75f);
			for (int x = 0; x < getWidth(); x++) {
				try {
					shapeRender.line(
							getX()+x,
							getY(), 
							getX()+x+1,
							(int) ((mainGraph.get((int) (dataIndex+x +1 -getWidth()/2))/normalDataG1)*scale)+getY());
				} catch (NullPointerException | IndexOutOfBoundsException e) {
				}
				shapeRender.line(
						getX(), 
						MathUtils.round(scale*(avgG1/normalDataG1))+getY(),
						getWidth() + getX(),
						MathUtils.round(scale*(avgG1/normalDataG1))+getY());
			}
			break;
		}

		shapeRender.setColor(0f, 1f, 0f, 1f);
		shapeRender.line(getX()+getWidth()/2, 0, getX()+getWidth()/2, getHeight()+getY());
		shapeRender.end();
		
		batch.begin();
		super.draw(batch, parentAlpha);
	}
	
	@Override
	public void act(float delta) {
		if (audioData != null) {
			setAudioDataIndex(audioData.getPlaybackIndexPosition());
		}
		super.act(delta);
	}
	
	/**
	 * Set what arrays to graph
	 * @param dataSet1 first audio data set
	 * @param dataSet2 overlay graph. This one can be null.
	 * @param audioData actual basic audio information for index position
	 */
	public void setGraphingData(FloatArray dataSet1, FloatArray dataSet2, MusicDataPack audioData) {
		this.mainGraph = dataSet1;
		this.overlayGraph = dataSet2;
		if (dataSet2 == null) {
			displayMode = 2;
		} else {
			displayMode = 0;
		}
		this.audioData =  audioData;
	}
	
}
