package zero1hd.polyjet.ui.pages;

import java.io.File;
import java.io.FilenameFilter;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Preferences;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane;
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.polyjet.Polyjet;
import zero1hd.polyjet.audio.AudioInfo;
import zero1hd.polyjet.screens.MainMenu;
import zero1hd.polyjet.ui.builders.MusicSelectable;
import zero1hd.polyjet.ui.windows.LoadingWindow;
import zero1hd.polyjet.ui.windows.NoticeWindow;
import zero1hd.polyjet.util.MiniEvents;

public class MusicSelectionPage extends Page {
	private volatile Table musicChoices;
	Preferences musicFileAnnotation;
	private Polyjet core;
	private volatile ScrollPane musicChoiceScroller;
	
	private volatile LoadingWindow loadingWindow;
	protected volatile boolean cancel;
	private TextButton back;
	
	private FileHandle selectedMusic;
	private AudioInfo selectedMusicInfo;
	
	public MusicSelectionPage(final Polyjet core, final MainMenu mainMenu) {
		super("Select music", core.getDefaultSkin());
		this.core = core;
		
		musicFileAnnotation = Gdx.app.getPreferences("music_file_annotation");
		
		back = new TextButton("Back", core.getDefaultSkin());
		back.setPosition(getWidth()-back.getWidth()-15f, getHeightBelowTitle());
		back.addListener(new ChangeListener() {
			@Override
			public void changed(ChangeEvent event, Actor actor) {
				core.setScreen(mainMenu);
				cancel = true;
			}
		});
		addActor(back);
		
		loadingWindow = new LoadingWindow(core.getDefaultSkin(), "tinted", true, core.getAssetManager(), core.prefs.getFloat("fx vol"));
		loadingWindow.setPosition((getWidth()-loadingWindow.getWidth())/2f, (getHeight()-loadingWindow.getHeight())/2f);
		addActor(loadingWindow);
		loadingWindow.playOpenSound();
		loadingWindow.setMovable(false);
		loadingWindow.setModal(true);
		
		musicChoices = new Table();
		musicChoices.defaults().pad(10f);
		musicChoiceScroller = new ScrollPane(musicChoices);
		musicChoiceScroller.setScrollingDisabled(false, true);
		musicChoiceScroller.setSize(getWidth(), getHeight()-(getHeight()-back.getY()));
		
		addActor(musicChoiceScroller);
		
		loadingWindow.toFront();
		back.toFront();
		
	}
	
	@Override
	public void act(float delta) {
		
		super.act(delta);
	}
	
	public void beginMusicSearch() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				Logger.getLogger("org.jaudiotagger").setLevel(Level.SEVERE);
				
				FileHandle[] musicFiles = new FileHandle(core.prefs.getString("music dir")).list(new FilenameFilter() {
					@Override
					public boolean accept(File dir, String name) {
						if (name.endsWith("mp3") || name.endsWith("wav")) {
							return true;
						}
						return false;
					}
				});
				
				if (musicFiles.length > 0) {
					for (int music = 0; music < musicFiles.length && !cancel; music++) {
						final MusicSelectable selectable = new MusicSelectable(musicFiles[music], musicFileAnnotation, core.getDefaultSkin(), core.getAssetManager().get("defaultCover.png", Texture.class));
						Gdx.app.postRunnable(new Runnable() {
							@Override
							public void run() {
								Gdx.app.debug("Music Search Thread", "Finished loading: " + selectable.getName());
								musicChoices.add(selectable).prefSize(panelWidthCalc(getWidth()), musicChoiceScroller.getHeight());
								selectable.addInfoToPanel(musicChoiceScroller, panelWidthCalc(getWidth()) - 20f);
								
								selectable.addListener(new ChangeListener() {
									@Override
									public void changed(ChangeEvent event, Actor actor) {
										
										if (!selectable.isMusicInvalid()) {
											selectedMusic = selectable.getMusicFile();
											selectedMusicInfo = selectable.getAudioInfo();
											send(MiniEvents.MUSIC_SELECTED);
										} else {
											//Play "no" sound
										}
									}
								});
							}
						});
						
						Gdx.app.debug("Music Search Thread", "Completed: " + music);
						int prog = (int) (100f*music/(musicFiles.length-1f));
						loadingWindow.setProgress(prog);
					}
					
					loadingWindow.remove();
					
				} else {
					NoticeWindow notice = new NoticeWindow(core.getDefaultSkin(), "default", "No song's found in:\n\"" + core.prefs.getString("music dir") + "\"\nTo change the search directory, go to game options.");
					notice.setSize(0.6f*getWidth(), 0.6f*getHeight());
					notice.setPosition((getWidth()-notice.getWidth())/2f, (getHeight()-notice.getHeight())/2f);
					notice.setModal(true);
					notice.setMovable(false);
					loadingWindow.remove();
					addActor(notice);
					back.toFront();
				}
			}
		}).start();
	}
	
	public float panelWidthCalc(float origWidth) {
		return (float) (Math.sqrt(getWidth()*35f)+80f);
	}
	
	public FileHandle getSelectedMusic() {
		return selectedMusic;
	}
	
	public AudioInfo getSelectedMusicInfo() {
		return selectedMusicInfo;
	}
}
