/*
 * Copyright (C) 2013 Snowsun <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.gui;

import com.jme3.input.event.MouseButtonEvent;
import com.jme3.math.Vector2f;
import org.wyrez.shootingstars.gui.controls.ButtonBase;
import org.wyrez.shootingstars.gui.listener.OptionsListener;
import org.wyrez.shootingstars.helper.DisplayHelper;
import org.wyrez.shootingstars.states.util.OptionSettings;
import tonegod.gui.controls.buttons.Button;
import tonegod.gui.controls.buttons.CheckBox;
import tonegod.gui.controls.lists.ComboBox;
import tonegod.gui.controls.lists.Slider;
import tonegod.gui.controls.text.Label;
import tonegod.gui.controls.text.TextField;
import tonegod.gui.controls.windows.Panel;
import tonegod.gui.controls.windows.TabControl;
import tonegod.gui.core.Screen;

/**
 *
 * @author Snowsun
 */
public class OptionsGUI extends Panel implements Gui {

    private OptionsListener listener;
    private OptionSettings settings;
    //General Controls
    private TextField txtPlayerName;
    
    //Video Controls
    private ComboBox cboResolution;
    private ComboBox cboFrequency;
    private ComboBox cboDepthBits;
    private CheckBox chkFullscreen;
    private CheckBox chkVSync;
    private CheckBox chkPostProcessing;
    private Slider sldParticleDensity;
    //Audio Controls
    private Slider sldMasterVolume;
    private Slider sldFXVolume;
    private Slider sldSoundVolume;

    public OptionsGUI(Screen screen, OptionsListener listener, OptionSettings settings) {
        super(screen, new Vector2f(0f, 0f), new Vector2f(1280f, 720f)); //create for full hd
        this.listener = listener;
        this.settings = settings;
        this.setIgnoreMouse(true);
        this.setIsVisible(false);
        create();
        readControlValues();
    }

    public void attach() {
        screen.addElement(this);
    }

    public void detach() {
        screen.removeElement(this);
    }

    private void create() {
        float tabControlStartPointx = 32f;
        float tabControlStartPointy = 18f;
        float witdhTabControl = 1216f;
        float heightTabControl = 612f;

        float buttonWidth = 153.6f;

        TabControl tcOptions = new TabControl(screen, "tcOptions", new Vector2f(tabControlStartPointx, tabControlStartPointy), new Vector2f(witdhTabControl, heightTabControl));
        tcOptions.setUseSlideEffect(true);
        tcOptions.addTab("General");
        tcOptions.addTab("Video");
        tcOptions.addTab("Audio");

        createGeneralTab(tcOptions);
        createVideoTab(tcOptions);
        createAudioTab(tcOptions);

        float differnceTabControlButtons = 622.8f;

        Button btnSave = new ButtonBase(screen, new Vector2f(tabControlStartPointx + 877f, tabControlStartPointy + differnceTabControlButtons), new Vector2f(buttonWidth, 40)) {
            @Override
            public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
                saveControlValues();
                listener.save();
            }
        };
        btnSave.setText("Save");

        Button btnCancel = new ButtonBase(screen, new Vector2f(tabControlStartPointx + 1060f, tabControlStartPointy + differnceTabControlButtons), new Vector2f(buttonWidth, 40)) {
            @Override
            public void onButtonMouseLeftUp(MouseButtonEvent evt, boolean toggled) {
                listener.cancel();
            }
        };
        btnCancel.setText("Cancel");

        this.addChild(tcOptions);
        this.addChild(btnSave);
        this.addChild(btnCancel);
    }

    private void createGeneralTab(TabControl tcOptions) {
        float startPointx = 64f;
        float startPointy = 36f;
        float marginLeftControls = 115.8f;

        Label lblPlayerName = new Label(screen, new Vector2f(startPointx, startPointy), new Vector2f(120f, 40f));
        lblPlayerName.setText("PlayerName");
        
        txtPlayerName = new TextField(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 7f), new Vector2f(200f, 30f));
        
        tcOptions.addTabChild(0, lblPlayerName);
        tcOptions.addTabChild(0, txtPlayerName);
    }

    private void createVideoTab(TabControl tcOptions) {

        float startPointx = 64f;
        float startPointy = 36f;
        float marginLeftControls = 115.8f;

        Label lblResolution = new Label(screen, "lblResolution", new Vector2f(startPointx, startPointy), new Vector2f(100f, 40f));
        lblResolution.setText("Resolution");

        cboResolution = new ComboBox(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 7f), new Vector2f(200f, 30f)) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        for (String s : DisplayHelper.getResolutions()) {
            cboResolution.addListItem(s, s);
        }

        Label lblFrequency = new Label(screen, "lblFrequency", new Vector2f(startPointx, startPointy + 40f), new Vector2f(100f, 40f));
        lblFrequency.setText("Frequency");

        cboFrequency = new ComboBox(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 47f), new Vector2f(200f, 30f)) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        for (String s : DisplayHelper.getFrequencys()) {
            cboFrequency.addListItem(s, s);
        }

        Label lblDepthBits = new Label(screen, "lblDepthBits", new Vector2f(startPointx, startPointy + 80f), new Vector2f(100f, 40f));
        lblDepthBits.setText("DepthBits");

        cboDepthBits = new ComboBox(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 87f), new Vector2f(200f, 30f)) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        for (String s : DisplayHelper.getDepthBits()) {
            cboDepthBits.addListItem(s, s);
        }

        Label lblFullscreen = new Label(screen, "lblFullscreen", new Vector2f(startPointx, startPointy + 120f), new Vector2f(100f, 40f));
        lblFullscreen.setText("Fullscreen");

        chkFullscreen = new CheckBox(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 132f), new Vector2f(20f, 20f));

        Label lblVSync = new Label(screen, "lblVSync", new Vector2f(startPointx, startPointy + 160f), new Vector2f(100f, 40f));
        lblVSync.setText("VSync");

        chkVSync = new CheckBox(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 172f), new Vector2f(20f, 20f));

        Label lblPostProcessing = new Label(screen, "lblPostProcessing", new Vector2f(startPointx, startPointy + 200f), new Vector2f(120f, 40f));
        lblPostProcessing.setText("PostProcessing");

        chkPostProcessing = new CheckBox(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 212f), new Vector2f(20f, 20f));

        Label lblParticleDensity = new Label(screen, "lblParticleDensity", new Vector2f(startPointx, startPointy + 240f), new Vector2f(120f, 40f));
        lblParticleDensity.setText("ParticleDensity");

        sldParticleDensity = new Slider(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 247f), new Vector2f(200f, 30f), Slider.Orientation.HORIZONTAL, false) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        sldParticleDensity.setStepIntegerRange(0, 3, 1);

        tcOptions.addTabChild(1, lblResolution);
        tcOptions.addTabChild(1, cboResolution);
        tcOptions.addTabChild(1, lblFrequency);
        tcOptions.addTabChild(1, cboFrequency);
        tcOptions.addTabChild(1, lblDepthBits);
        tcOptions.addTabChild(1, cboDepthBits);
        tcOptions.addTabChild(1, lblFullscreen);
        tcOptions.addTabChild(1, chkFullscreen);
        tcOptions.addTabChild(1, lblVSync);
        tcOptions.addTabChild(1, chkVSync);
        tcOptions.addTabChild(1, lblPostProcessing);
        tcOptions.addTabChild(1, chkPostProcessing);
        tcOptions.addTabChild(1, lblParticleDensity);
        tcOptions.addTabChild(1, sldParticleDensity);
    }

    private void createAudioTab(TabControl tcOptions) {
        float startPointx = 64f;
        float startPointy = 36f;
        float marginLeftControls = 115.8f;

        Label lblMasterVolume = new Label(screen, "lblMasterVolume", new Vector2f(startPointx, startPointy), new Vector2f(120f, 40f));
        lblMasterVolume.setText("MasterVolume");

        sldMasterVolume = new Slider(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 7f), new Vector2f(200f, 30f), Slider.Orientation.HORIZONTAL, false) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        sldMasterVolume.setStepIntegerRange(0, 100, 1);

        Label lblFXVolume = new Label(screen, "lblFXVolume", new Vector2f(startPointx, startPointy + 40f), new Vector2f(100f, 40f));
        lblFXVolume.setText("FXVolume");

        sldFXVolume = new Slider(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 47f), new Vector2f(200f, 30f), Slider.Orientation.HORIZONTAL, false) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        sldFXVolume.setStepIntegerRange(0, 100, 1);

        Label lblSoundVolume = new Label(screen, "lblSoundVolume", new Vector2f(startPointx, startPointy + 80f), new Vector2f(120f, 40f));
        lblSoundVolume.setText("SoundVolume");

        sldSoundVolume = new Slider(screen, new Vector2f(startPointx + marginLeftControls, startPointy + 87f), new Vector2f(200f, 30f), Slider.Orientation.HORIZONTAL, false) {
            @Override
            public void onChange(int selectedIndex, Object value) {
            }
        };
        sldSoundVolume.setStepIntegerRange(0, 100, 1);

        tcOptions.addTabChild(2, lblMasterVolume);
        tcOptions.addTabChild(2, sldMasterVolume);
        tcOptions.addTabChild(2, lblFXVolume);
        tcOptions.addTabChild(2, sldFXVolume);
        tcOptions.addTabChild(2, lblSoundVolume);
        tcOptions.addTabChild(2, sldSoundVolume);
    }

    private void readControlValues() {
        String resolution = String.valueOf(settings.getWidth()) + " x " + String.valueOf(settings.getHeight());

        //General
        txtPlayerName.setText(settings.getUsername());
        
        //Video
        setComboBoxValue(cboResolution, resolution);
        setComboBoxValue(cboFrequency, String.valueOf(settings.getFrequency()));
        setComboBoxValue(cboDepthBits, String.valueOf(settings.getDepthBits()));
        chkFullscreen.setIsChecked(settings.isFullscreenEnabled());
        chkVSync.setIsChecked(settings.isVSyncEnabled());
        chkPostProcessing.setIsChecked(settings.isPostprocessingEnabled());
        sldParticleDensity.setSelectedIndex(settings.getParticleDensity());

        //Audio
        sldMasterVolume.setSelectedIndex(settings.getMasterVolume());
        sldFXVolume.setSelectedIndex(settings.getFXVolume());
        sldSoundVolume.setSelectedIndex(settings.getSoundVolume());
    }

    private void setComboBoxValue(ComboBox comboBox, String value) {
        for (int i = 0; i < comboBox.getListItems().size(); i++) {
            if (comboBox.getListItems().get(i).getValue().equals(value)) {
                comboBox.setSelectedIndex(i);
            }
        }
    }

    private void saveControlValues() {
        //General
        settings.setUsername(txtPlayerName.getText());
        
        //Video
        String resolution[] = cboResolution.getSelectedListItem().getValue().toString().split(" x ");
        settings.setWidth(Integer.parseInt(resolution[0]));
        settings.setHeight(Integer.parseInt(resolution[1]));
        settings.setFrequency(Integer.parseInt(cboFrequency.getSelectedListItem().getValue().toString()));
        settings.setDepthBits(Integer.parseInt(cboDepthBits.getSelectedListItem().getValue().toString()));
        settings.setFullscreen(chkFullscreen.getIsChecked());
        settings.setVSync(chkVSync.getIsChecked());
        settings.setPostProcessing(chkPostProcessing.getIsChecked());
        settings.setParticleDensity(sldParticleDensity.getSelectedIndex());

        //Audio
        settings.setMasterVolume(sldMasterVolume.getSelectedIndex());
        settings.setFXVolume(sldFXVolume.getSelectedIndex());
        settings.setSoundVolume(sldSoundVolume.getSelectedIndex());

        settings.save();
    }
}
