/*
 * Copyright (C) 2013 Darth Affe <http://wyrez.org> and contributors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.wyrez.shootingstars.states;

import com.jme3.app.state.AbstractAppState;
import com.jme3.app.state.AppStateManager;
import java.io.File;
import org.wyrez.shootingstars.data.AudioDataManager;
import org.wyrez.shootingstars.data.OggConverter;
import org.wyrez.shootingstars.game.GameSettings;
import org.wyrez.shootingstars.gui.LoadingGui;
import org.wyrez.shootingstars.helper.ChecksumHelper;
import org.wyrez.shootingstars.helper.PathHelper;
import org.wyrez.shootingstars.states.util.LoadingProgress;
import tonegod.gui.core.Screen;

/**
 *
 * @author Darth Affe
 */
public class LoadingState extends AbstractAppState {

    private StateManager stateManager;
    private LoadingGui gui;
    private AudioDataManager audioDataManager;
    private LoadingProgress currentProgress;
    private GameSettings settings;

    public LoadingState(Screen screen, StateManager stateManager,
            AudioDataManager audioDataManager, GameSettings settings) {
        this.stateManager = stateManager;
        this.gui = new LoadingGui(screen);
        this.audioDataManager = audioDataManager;
        this.settings = settings;
    }

    @Override
    public void stateAttached(AppStateManager stateManager) {
        currentProgress = LoadingProgress.START;
        gui.attach();
    }

    @Override
    public void stateDetached(AppStateManager stateManager) {
        gui.detach();
    }

    @Override
    public void update(float tpf) {
        try {
            switch (currentProgress) {
                case START:
                    currentProgress = LoadingProgress.LOADING_CINEMA;
                    break;
                case LOADING_CINEMA:
                    loadingCinema();
                    currentProgress = LoadingProgress.INIT_AUDIO_PLAYER;
                    break;
                case INIT_AUDIO_PLAYER:
                    initAudioPlayer();
                    currentProgress = LoadingProgress.INIT_AUDIO_ANALYSIS;
                    break;
                case INIT_AUDIO_ANALYSIS:
                    if (initAudioAnalysis()) {
                        currentProgress = LoadingProgress.ANALYSE_LOW_BAND;
                    } else {
                        currentProgress = LoadingProgress.CONVERT_AUDIO;
                    }
                    break;
                case CONVERT_AUDIO:
                    convertAudio();
                    currentProgress = LoadingProgress.INIT_AUDIO_ANALYSIS;
                    break;
                case ANALYSE_LOW_BAND:
                    analyseLowBand();
                    currentProgress = LoadingProgress.ANALYSE_MID_BAND;
                    break;
                case ANALYSE_MID_BAND:
                    analyseMidBand();
                    currentProgress = LoadingProgress.ANALYSE_HIGH_BAND;
                    break;
                case ANALYSE_HIGH_BAND:
                    analyseHighBand();
                    currentProgress = LoadingProgress.GENERATING_SCENE;
                    break;
                case GENERATING_SCENE:
                    generateScene();
                    currentProgress = LoadingProgress.LOADING_PLAYER;
                    break;
                case LOADING_PLAYER:
                    loadPlayer();
                    currentProgress = LoadingProgress.DONE;
                    break;
                case DONE:
                    done();
                    break;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            stateManager.setState(State.MENU);
        }
        gui.updateProgress(currentProgress);
    }

    private boolean initAudioAnalysis() {
        GameState gs = stateManager.getState(State.GAME);
        return audioDataManager.initialize(settings, gs.getMediaPlayer());
    }

    private void convertAudio() throws Exception {
        String sourceChecksum = ChecksumHelper.createMD5(settings.getVideoFile());
        String audioPath = PathHelper.getCacheFolder() + sourceChecksum + ".ogg";
        if (!new File(audioPath).exists()) {
            new OggConverter().convert(settings.getVideoFile(), audioPath, 192);
        }
        settings.setAudioFile(audioPath);
    }

    private void analyseLowBand() {
        audioDataManager.analyseLowBand();
    }

    private void analyseMidBand() {
        audioDataManager.analyseMidBand();
    }

    private void analyseHighBand() {
        audioDataManager.analyseHighBand();
    }

    private void initAudioPlayer() throws Exception {
        GameState gs = stateManager.getState(State.GAME);
        gs.initMediaPlayer();
    }

    private void loadingCinema() {
        GameState gs = stateManager.getState(State.GAME);
        gs.loadCinema();
    }

    private void generateScene() {
        GameState gs = stateManager.getState(State.GAME);
        gs.loadGround();
    }

    private void loadPlayer() {
        GameState gs = stateManager.getState(State.GAME);
        gs.loadPlayer();
    }

    public void done() {
        stateManager.setState(State.GAME);
    }
}
