package zero1hd.rhythmbullet.desktop.screens.main;

import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;

import zero1hd.rhythmbullet.audio.AudioMetadataController;
import zero1hd.rhythmbullet.audio.MusicController;
import zero1hd.rhythmbullet.audio.analyzer.AudioAnalyzerSection;
import zero1hd.rhythmbullet.audio.analyzer.DynamicAudioAnalyzer;
import zero1hd.rhythmbullet.audio.metadata.AudioMetadata;
import zero1hd.rhythmbullet.graphics.ui.Page;

public class AnalysisPage extends Page {
	private TextButton backButton;
	private DynamicAudioAnalyzer audioAnalyzer;
	private Table table;
	private Table adjustment;
	private Label difficultyModLabel, healthModLabel, speedModLabel;
	private Slider difficultyModifierSlider, healthModifierSlider, speedModifierSlider;
	private Label diffModPercentLabel, heltModPercentLabel, speeModPercentLabel;
	private Label progressLabel;
	private TextButton confirmButton;
	private Image albumImage;
	private AudioMetadataController amc;
	private MusicController mc;
	
	public AnalysisPage(MusicController mc, AudioMetadataController amc, Skin skin, ChangeListener backButtonListener, ChangeListener confirmedButtonListener) {
		super(2, 0);
		table = new Table();
		table.setFillParent(true);
		table.defaults().space(10f);
		addActor(table);
		adjustment = new Table();
		this.mc = mc;
		this.amc = amc;
		
		difficultyModLabel = new Label("Difficulty Modifier: ", skin, "sub-font", skin.getColor("default"));
		difficultyModifierSlider = new Slider(1, 3, 0.5f, false, skin);
		diffModPercentLabel = new Label(String.valueOf(difficultyModifierSlider.getValue()) + "x", skin);
		difficultyModifierSlider.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				diffModPercentLabel.setText(String.valueOf(difficultyModifierSlider.getValue()) + "x");
			}
		});
		
		adjustment.add(difficultyModLabel);
		adjustment.add(difficultyModifierSlider).minWidth(0.5f*getWidth());
		adjustment.add(diffModPercentLabel).spaceLeft(10f).center().expandX().fill();
		adjustment.row();
		healthModLabel = new Label("Health Modifier: ", skin, "sub-font", skin.getColor("default"));
		healthModifierSlider = new Slider(1f, 3f, 0.5f, false, skin);
		heltModPercentLabel = new Label(String.valueOf(healthModifierSlider.getValue()) + "x", skin);
		healthModifierSlider.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				heltModPercentLabel.setText(String.valueOf(healthModifierSlider.getValue()) + "x");
			}
		});
		adjustment.add(healthModLabel);
		adjustment.add(healthModifierSlider).fillX();
		adjustment.add(heltModPercentLabel).spaceLeft(10f);
		adjustment.row();
		speedModLabel = new Label("Speed Modifier: ", skin, "sub-font", skin.getColor("default"));
		speedModifierSlider = new Slider(1, 3, 0.5f, false, skin);
		speeModPercentLabel = new Label(String.valueOf(speedModifierSlider.getValue()) + "x", skin);
		speedModifierSlider.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				speeModPercentLabel.setText(String.valueOf(speedModifierSlider.getValue()) + "x");
			}
		});
		adjustment.add(speedModLabel);
		adjustment.add(speedModifierSlider).fillX();
		adjustment.add(speeModPercentLabel).spaceLeft(10f);
		adjustment.row();
		
		confirmButton = new TextButton("Confirm", skin);
		confirmButton.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				confirmButton.setDisabled(true);
				speedModifierSlider.setDisabled(true);
				healthModifierSlider.setDisabled(true);
				difficultyModifierSlider.setDisabled(true);
				
				progressLabel.setText("Loading...");
			}
		});
		confirmButton.addListener(confirmedButtonListener);
		
		adjustment.add(confirmButton).colspan(3).fillX();
		adjustment.row();
		progressLabel = new Label("Please confirm... ", skin);
		adjustment.add(progressLabel).colspan(2).left().spaceTop(20f);
		
		backButton = new TextButton("Cancel", skin);
		backButton.setWidth(backButton.getWidth() + 20);
		backButton.addListener(backButtonListener);
		backButton.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				if (audioAnalyzer != null) {
					audioAnalyzer.stop();
					audioAnalyzer = null;
					albumImage.setDrawable(null);
					mc.setLoop(false);
					
				}
			}
		});
		backButton.setPosition(15, getHeight()-backButton.getHeight()-25);
		addActor(backButton);
		
	}
	
	public void processSong() {
		mc.setLoop(true);
		AudioMetadata metadata = amc.getAudioMetadata(mc.getCurrentMusicFileHandle());
		metadata.loadAlbumCover();
		albumImage = new Image(metadata.getAlbumCover());
		table.clear();
		table.add(albumImage).size(adjustment.getMinHeight());
		table.row();
		table.add(adjustment);
		
		AudioAnalyzerSection bass = new AudioAnalyzerSection(1, 5, 1.7f, 3);
		AudioAnalyzerSection midSection = new AudioAnalyzerSection(7, 25, 1.5f, 3);
		
		audioAnalyzer = new DynamicAudioAnalyzer(mc.getMusicList().newAudioProcessor(mc.getCurrentMusicFileHandle()), bass, midSection);
		audioAnalyzer.start();
	}
	
	@Override
	public void dispose() {
		super.dispose();
	}
	
	@Override
	public void setCameraPositionToPage(Vector3 cameraPosition) {
		confirmButton.setDisabled(false);
		speedModifierSlider.setDisabled(false);
		healthModifierSlider.setDisabled(false);
		difficultyModifierSlider.setDisabled(false);
		
		processSong();
		
		super.setCameraPositionToPage(cameraPosition);
	}
}
