package zero1hd.rhythmbullet.stages;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Pixmap.Format;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;

import zero1hd.rhythmbullet.RhythmBullet;
import zero1hd.rhythmbullet.ui.components.HealthBar;
import zero1hd.rhythmbullet.ui.windows.FPSWindow;
import zero1hd.rhythmbullet.ui.windows.PauseMenu;
import zero1hd.rhythmbullet.util.ScoreManager;

public class GameHUD extends Stage {
	private Screen returnScreen;
	private Label scoreLabel;
	private ImageButton pause;
	private boolean paused;
	private FPSWindow fpsWindow;
	private PauseMenu pauseMenu;
	private HealthBar healthBar;
	private Pixmap pixmap;
	private Texture leftStatTexture;
	private Texture rightStatTexture;
	private Image leftStatusBar;
	private Image rightStatusBar;
	private GamePlayArea gpa;
	private Music music;
	private ScoreManager sm;
	
	private Color original, bass, um;
	public GameHUD(Skin skin, float maxHealth, GamePlayArea gpa, Screen rs, final RhythmBullet core) {
		super();
		scoreLabel = new Label("Score: 0", skin, "default-font", Color.WHITE);
		scoreLabel.setPosition(10f, Gdx.graphics.getHeight()-scoreLabel.getHeight() - 10f);
		addActor(scoreLabel);
		this.sm = gpa.score;
		this.gpa = gpa;
		this.returnScreen = rs;
		
		pause = new ImageButton(skin.getDrawable("pause"),
				skin.getDrawable("pause-down"));
		pause.setPosition(Gdx.graphics.getWidth() - pause.getWidth() - 15f,
				Gdx.graphics.getHeight() - pause.getHeight() - 15f);
		pause.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				setPaused(true);
			}
		});
		addActor(pause);
		
		fpsWindow = new FPSWindow("FPS", skin);
		fpsWindow.setPosition(15f, 15f);
		
		pauseMenu = new PauseMenu(skin);
		pauseMenu.getResumeButton().addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				setPaused(false);
			}
		});
		
		pauseMenu.getQuitButton().addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				core.setScreen(returnScreen);
			}
		});
		pauseMenu.setPosition((Gdx.graphics.getWidth()-pauseMenu.getWidth())/2f, (Gdx.graphics.getHeight()-pauseMenu.getHeight())/2f);
		
		healthBar = new HealthBar(skin, maxHealth);
		healthBar.setSize(30f, Gdx.graphics.getHeight()/3);
		healthBar.setHealth(maxHealth);
		healthBar.setPosition(Gdx.graphics.getWidth() -(gpa.getViewport().getRightGutterWidth()/4f), (Gdx.graphics.getHeight()-healthBar.getHeight())/2f);
		addActor(healthBar);
		healthBar.setPolyjetEntity(gpa.getPolyjetEntity());
		pixmap = new Pixmap(3, 3, Format.RGBA8888);
		int excess = 2*gpa.getViewport().getLeftGutterWidth()/pixmap.getWidth();
		Gdx.app.debug("GHUD", "offset on size: " + excess);
		pixmap.setColor(Color.WHITE);
		pixmap.drawLine(0, 0, 0, 2);
		pixmap.setColor(1f, 1f, 1f, 0.5f);
		pixmap.drawLine(1, 0, 1, 2);
		leftStatTexture = new Texture(pixmap);
		leftStatTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
		leftStatusBar = new Image(leftStatTexture);
		leftStatusBar.setSize(gpa.getViewport().getLeftGutterWidth()+excess, getHeight());
		leftStatusBar.setPosition(0, 0);
		addActor(leftStatusBar);
		leftStatusBar.toBack();
		
		pixmap.dispose();
		pixmap = new Pixmap(3, 3, Format.RGBA8888);
		pixmap.setColor(Color.WHITE);
		pixmap.drawLine(2, 0, 2, 2);
		pixmap.setColor(1f, 1f, 1f, 0.5f);
		pixmap.drawLine(1, 0, 1, 2);
		rightStatTexture = new Texture(pixmap);
		rightStatTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
		rightStatusBar = new Image(rightStatTexture);
		rightStatusBar.setSize(gpa.getViewport().getRightGutterWidth()+excess, getHeight());
		rightStatusBar.setPosition(getWidth()-gpa.getViewport().getRightGutterWidth()-excess, 0f);
		addActor(rightStatusBar);
		rightStatusBar.toBack();
		pixmap.dispose();
		
		original = new Color(0.6f, 0.8f, 255f, 0.55f);
		bass = new Color(0.8f, 0, 1, 0.9f);
		um = new Color(1f, 0.6f, 0.4f, 0.9f);
		setStatusColor(original);
	}
	
	@Override
	public void act(float delta) {
		if (sm.checkDifferent()) {
			setScore(sm.getScore());
		}
		
		if (gpa.getAudioMap() != null && gpa.getAudioMap().getHudType().length > gpa.getAudioMap().getIndex()) {
			if (gpa.getAudioMap() != null && gpa.getAudioMap().getHudType()[gpa.getAudioMap().getIndex()] != 0) {
				switch (gpa.getAudioMap().getHudType()[gpa.getAudioMap().getIndex()]) {
				case 1:
					changeStatusColor(bass, 0.2f, original);
					break;
				case 2:
					changeStatusColor(um, 0.2f, original);
				}
			}
		}
		super.act(delta);
	}
	
	/**
	 * sets the label for scoring to the designated score
	 * @param score designated score
	 */
	public void setScore(int score) {
		this.scoreLabel.setText("Score: " + score);
	}
	
	public void setPaused(boolean paused) {
		if (paused) {
			addActor(pauseMenu);
			if (music != null) {
				music.pause();
			}
		} else {
			pauseMenu.remove();
			if (music != null) {
				music.play();
			}
		}
		this.paused = paused;
	}
	
	/**
	 * toggle's between the two states of paused and unpaused
	 * @return whatever the new game state is (true for paused)
	 */
	public boolean togglePause() {
		if (isPaused()) {
			setPaused(false);
		} else {
			setPaused(true);
		}
		return isPaused();
	}
	
	public boolean isPaused() {
		return paused;
	}
	
	@Override
	public boolean keyUp(int keycode) {
		switch (keycode) {
		case Keys.F3:
			if (fpsWindow.hasParent()) {
				fpsWindow.remove();
			} else {
				addActor(fpsWindow);
			}
			break;
		case Keys.ESCAPE:
			togglePause();
			break;
		default:
			break;
		}
		return false;
	}
	
	public void setMusic(Music music) {
		this.music = music;
	}
	
	public void setStatusColor(Color color) {
		leftStatusBar.setColor(color);
		rightStatusBar.setColor(color);
	}
	
	public void setLeftStatusColor(Color color) {
		leftStatusBar.setColor(color);
	}
	
	public void setRightStatusColor(Color color) {
		rightStatusBar.setColor(color);
	}
	
	public void changeStatusColor(Color color, float duration, Color endColor) {
		leftStatusBar.clearActions();
		rightStatusBar.clearActions();
		
		leftStatusBar.addAction(Actions.sequence(Actions.color(color, duration*0.8f), Actions.color(endColor, duration)));
		rightStatusBar.addAction(Actions.sequence(Actions.color(color, duration*0.8f), Actions.color(endColor, duration)));
	}
	
	public HealthBar getHealthBar() {
		return healthBar;
	}
	
	@Override
	public void dispose() {
		leftStatTexture.dispose();
		rightStatTexture.dispose();
		super.dispose();
	}
}
