package org.terasology.logic.manager;
import com.google.common.collect.Lists;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.terasology.rendering.gui.components.UIMessageBox;
import org.terasology.rendering.gui.framework.UIDisplayElement;
import org.terasology.rendering.gui.framework.UIDisplayRenderer;
import org.terasology.rendering.gui.framework.UIDisplayWindow;
import javax.vecmath.Vector2f;
import java.util.HashMap;
import java.util.List;
/**
* First version of simple GUI manager.
* ToDo Init styles here
* ToDo Add GUI manager to single player
*
* @author Kireev Anton <adeon.k87@gmail.com>
*/
public class GUIManager {
private static GUIManager _instance;
private UIDisplayRenderer _renderer;
private UIDisplayWindow _focusedWindow;
private UIDisplayWindow _lastFocused;
private HashMap<String, UIDisplayWindow> _windowsById = new HashMap<String, UIDisplayWindow>();
public GUIManager() {
_renderer = new UIDisplayRenderer();
_renderer.setVisible(true);
}
public static GUIManager getInstance() {
if (_instance == null) {
_instance = new GUIManager();
}
return _instance;
}
public void render() {
_renderer.render();
}
public void update() {
if (_focusedWindow == null) {
int size = _renderer.getDisplayElements().size();
if (size > 0) {
//added this check to prevent the manager from ungrabbing the mouse when the minion behaviour menu pops up
// TODO : better way to handle this? not link focus with grabbing / ungrabbing?
UIDisplayWindow tempwindow = (UIDisplayWindow) _renderer.getDisplayElements().get(size - 1);
}
}
_renderer.update();
}
public <T extends UIDisplayWindow> T addWindow(T window, String windowId) {
if (window.isMaximized()) {
_renderer.addtDisplayElementToPosition(0, window);
} else {
_renderer.addDisplayElement(window);
}
_windowsById.put(windowId, window);
return window;
}
public void closeWindows() {
List<String> windowIds = Lists.newArrayList(_windowsById.keySet());
for (String windowId : windowIds) {
removeWindow(windowId);
}
}
public void removeWindow(UIDisplayWindow window) {
_renderer.removeDisplayElement(window);
if (_windowsById.containsValue(window)) {
for (String key : _windowsById.keySet()) {
if (_windowsById.get(key).equals(window)) {
_windowsById.remove(key);
break;
}
}
}
if (_focusedWindow == window) {
_focusedWindow = null;
}
if (_lastFocused == window) {
_lastFocused = null;
} else {
_focusedWindow = _lastFocused;
}
}
public void removeWindow(String windowId) {
UIDisplayWindow window = getWindowById(windowId);
if (window == null) {
return;
}
_renderer.removeDisplayElement(window);
if (_windowsById.containsValue(window)) {
for (String key : _windowsById.keySet()) {
if (_windowsById.get(key).equals(window)) {
_windowsById.remove(key);
break;
}
}
}
if (_focusedWindow == window) {
_focusedWindow = null;
}
if (_lastFocused == window) {
_lastFocused = null;
} else {
_focusedWindow = _lastFocused;
}
}
public UIDisplayWindow getWindowById(String windowId) {
if (_windowsById.containsKey(windowId)) {
return _windowsById.get(windowId);
} else {
return null;
}
}
public UIDisplayWindow getFocusedWindow() {
checkTopWindow();
return _focusedWindow;
}
public boolean isConsumingInput() {
checkTopWindow();
return _focusedWindow != null && _focusedWindow.isModal() && _focusedWindow.isVisible();
}
/**
* Process keyboard input - first look for "system" like events, then otherwise pass to the Player object
*/
public void processKeyboardInput(int key) {
checkTopWindow();
if (key == Keyboard.KEY_ESCAPE) {
if (_focusedWindow != null && _focusedWindow.isModal()) {
_focusedWindow.setVisible(false);
}
}
if (_focusedWindow != null && _focusedWindow.isModal() && _focusedWindow.isVisible()) {
_focusedWindow.processKeyboardInput(key);
return;
}
List<UIDisplayElement> screens = Lists.newArrayList(_renderer.getDisplayElements());
for (UIDisplayElement screen : screens) {
if (!((UIDisplayWindow) screen).isModal()) {
screen.processKeyboardInput(key);
}
}
}
public void processMouseInput(int button, boolean state, int wheelMoved) {
if (button == 0 && state) {
checkTopWindow();
}
if (_focusedWindow != null) {
_focusedWindow.processMouseInput(button, state, wheelMoved);
}
}
public boolean processBindButton(String id, boolean pressed) {
checkTopWindow();
if (_focusedWindow != null && _focusedWindow.isModal() && _focusedWindow.isVisible()) {
return _focusedWindow.processBindButton(id, pressed);
}
return false;
}
public void setFocusedWindow(UIDisplayWindow window) {
int size = _renderer.getDisplayElements().size();
for (int i = 0; i < size; i++) {
if (window.equals(_renderer.getDisplayElements().get(i))) {
setTopWindow(i);
return;
}
}
_focusedWindow = null;
}
public void setFocusedFromLast() {
if (_lastFocused == null || _lastFocused.equals(_focusedWindow)) {
return;
}
if (_focusedWindow.isMaximized() && _lastFocused.isMaximized()) {
_focusedWindow.setVisible(false);
}
_focusedWindow = _lastFocused;
if (!_focusedWindow.isVisible()) {
_focusedWindow.setVisible(true);
}
}
public void setFocusedWindow(String windowId) {
if (_windowsById == null || _windowsById.size() < 1 || !_windowsById.containsKey(windowId)) {
return;
}
setFocusedWindow(_windowsById.get(windowId));
}
private void setTopWindow(int windowPosition) {
if (_renderer.getDisplayElements().size() - 1 < windowPosition || windowPosition < 0) {
return;
}
UIDisplayWindow setTopWindow = (UIDisplayWindow) _renderer.getDisplayElements().get(windowPosition);
if (setTopWindow == null) {
return;
}
if (_focusedWindow != null && _focusedWindow.isVisible()) {
_lastFocused = _focusedWindow;
if (_lastFocused != null && _lastFocused.isMaximized() && setTopWindow.isMaximized()) {
_lastFocused.setVisible(false);
}
}
_focusedWindow = setTopWindow;
if (!_focusedWindow.isMaximized()) {
_renderer.changeElementDepth(windowPosition, _renderer.getDisplayElements().size() - 1);
}
if (!_focusedWindow.isVisible()) {
_focusedWindow.setVisible(true);
}
}
private void checkTopWindow() {
if (_focusedWindow != null && _focusedWindow.isModal() && _focusedWindow.isVisible()) {
return;
}
Vector2f mousePos = new Vector2f(Mouse.getX(), Display.getHeight() - Mouse.getY());
int size = _renderer.getDisplayElements().size();
for (int i = size - 1; i >= 0; i--) {
UIDisplayWindow window = (UIDisplayWindow) _renderer.getDisplayElements().get(i);
if (window.isVisible() && window.intersects(mousePos) && window.isModal()) {
setTopWindow(i);
break;
}
;
}
}
public void showMessage(String title, String text) {
UIDisplayWindow messageWindow = new UIMessageBox(title, text);
messageWindow.setVisible(true);
messageWindow.center();
addWindow(messageWindow, "messageBox");
setFocusedWindow(messageWindow);
}
public void setLastFocused() {
_focusedWindow = _lastFocused;
}
public boolean toggleWindow(String windowId) {
UIDisplayWindow window = getWindowById(windowId);
if (window == null) {
return false;
}
if (_focusedWindow != null && _focusedWindow.isModal() && _focusedWindow.isVisible()) {
if (window == _focusedWindow) {
window.setVisible(false);
return true;
}
} else {
setFocusedWindow(window);
return true;
}
return false;
}
}