package zero1hd.rhythmbullet.desktop.screens.main;

import java.text.NumberFormat;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar;
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.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;

import zero1hd.rhythmbullet.audio.MusicController;
import zero1hd.rhythmbullet.graphics.ui.Page;

public class OptionsPage extends Page {
	Table optionsTable;
	private ProgressBar musicVolSlider;
	private ProgressBar fxVolSlider;
	private TextField directoryField;
	private float musicSearchTimer;
	private Preferences prefs;
	private NumberFormat percentFormat;
	
	public OptionsPage(MusicController musicController, Skin skin, Preferences preferences, ChangeListener backButtonListener, ChangeListener graphicsButtonListener, ChangeListener controlsButtonListener) {
		super(-1, 0, "General", skin);
		this.prefs = preferences;
		percentFormat = NumberFormat.getPercentInstance();
		percentFormat.setMaximumFractionDigits(1);
		
		//Back button
		TextButton backButton = new TextButton("Back", skin);
		backButton.addListener(backButtonListener);
		backButton.setWidth(backButton.getWidth() + 20);
		backButton.setPosition(getWidth() - backButton.getWidth() - 10, getHeightBelowTitle() + 5);
		addActor(backButton);

		optionsTable = new Table();
		optionsTable.defaults().space(10f);

		addActor(optionsTable);
		
		Label musicVolSliderLabel = new Label("Music Volume: ", skin);
		optionsTable.add(musicVolSliderLabel);
		musicVolSlider = new Slider(0, 100, 1f, false, skin);
		musicVolSlider.setValue(preferences.getFloat("music vol", 100f));
		optionsTable.add(musicVolSlider).minWidth(0.3f*getWidth());
		final Label musicVolPercentage = new Label(percentFormat.format(musicVolSlider.getPercent()), skin);
		musicVolSlider.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				musicVolPercentage.setText(percentFormat.format(musicVolSlider.getPercent()));
				musicController.getCurrentMusic().setVolume(musicVolSlider.getPercent());
				preferences.putFloat("music vol", musicVolSlider.getValue());
			}
		});
		optionsTable.add(musicVolPercentage).expandX().left();
		
		optionsTable.row();
		
		Label fxVolSliderLabel = new Label("FX Volume: ", skin);
		optionsTable.add(fxVolSliderLabel);
		fxVolSlider = new Slider(0, 100, 1f, false, skin);
		fxVolSlider.setValue(preferences.getFloat("fx vol", 100f));
		optionsTable.add(fxVolSlider).fillX();
		final Label fxVolPercentage = new Label(percentFormat.format(fxVolSlider.getPercent()), skin);
		fxVolSlider.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				fxVolPercentage.setText(percentFormat.format(fxVolSlider.getPercent()));
				preferences.putFloat("fx vol", fxVolSlider.getValue());
			}
		});
		
		optionsTable.add(fxVolPercentage).left();
		
		optionsTable.row();
		
		Label musicDirectoryLabel = new Label("Music Directory: ", skin);
		optionsTable.add(musicDirectoryLabel);
		directoryField = new TextField(null, skin ) {
			@Override
			public void act(float delta) {
				if (musicSearchTimer > 0) {
					musicSearchTimer -= delta;
					if (musicSearchTimer <= 0) {
						musicController.getMusicList().setSearchPath(directoryField.getText());
						musicController.getMusicList().attemptAsyncSearch(false);
					}
				}
				super.act(delta);
			}
		};
		directoryField.setText(preferences.getString("music dir", System.getProperty("user.home")+System.getProperty("file.separator")+"Music"));
		directoryField.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				musicSearchTimer = 2;
			}
		});
		optionsTable.add(directoryField).fillX();
		
		optionsTable.row();
		
		TextButton keybindSettings = new TextButton("Set Controls",  skin);
		keybindSettings.addListener(controlsButtonListener);
		optionsTable.add(keybindSettings).colspan(2).fillX();
		
		optionsTable.row();
		
		TextButton graphicsSettings = new TextButton("Graphics",  skin);
		graphicsSettings.addListener(graphicsButtonListener);
		optionsTable.add(graphicsSettings).colspan(2).fillX();
		
		optionsTable.row();
		
		Label fpsLabel = new Label("", skin) {
			@Override
			public void act(float delta) {
				setText("Current FPS: " + Gdx.graphics.getFramesPerSecond());
				super.act(delta);
			}
		};
		optionsTable.add(fpsLabel).colspan(2);
		
		optionsTable.row();
		
		Label usageLabel = new Label("Current Usage (JVM): ", skin) {
			float refreshTime = 20;
			@Override
			public void act(float delta) {
				refreshTime -= delta;
				if (refreshTime <= 0) {
					refreshTime = 4;
					String formatted = percentFormat.format(((float)(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/(float)Runtime.getRuntime().totalMemory()));
					setText("Current usage (JVM): " + formatted);
				}
				super.act(delta);
			}
		};
		
		optionsTable.add(usageLabel).colspan(2);
		
		optionsTable.pack();
		optionsTable.setX((getWidth()-optionsTable.getWidth())/2f);
		optionsTable.setSize(getWidth() - optionsTable.getX(), backButton.getY());
	}
	
	public void saveOptions() {
		prefs.putString("music dir", directoryField.getText());
		Gdx.app.debug("Preferences", "Saved all basic options page values.");
	}
	
	@Override
	public void dispose() {
		saveOptions();
		super.dispose();
	}
}
