package net.fourbytes.shadow;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.IntMap;
import com.badlogic.gdx.utils.ObjectIntMap;
import net.fourbytes.shadow.entities.Cursor;
public class Input {
public static class TouchPoint {
public static enum TouchMode {
KeyInput,
Cursor
}
public TouchMode touchmode;
public int id = -1;
public int button = -1;
public Vector2 pos = new Vector2(-1f, -1f);
public TouchPoint(int x, int y, int id, int button, TouchMode touchmode) {
this.id = id;
this.button = button;
this.pos.set(x, y);
this.touchmode = touchmode;
if (touchmode == TouchMode.Cursor && Shadow.level != null && Shadow.level.player != null && Input.isAndroid && !Input.isOuya) {
this.button = -1; //Special button id for Android
Shadow.level.fillLayer(0);
Cursor c = new Cursor(new Vector2(0f, 0f), Shadow.level.layers.get(0), id);
c.pos.set(c.calcPos(pos));
Shadow.level.cursors.add(c);
}
}
}
public static interface KeyListener {
public void keyDown(Key key);
public void keyUp(Key key);
}
static OrthographicCamera cam;
public static boolean isAndroid = false;
public static boolean isOuya = false;
public static boolean isInMenu = false;
public static class Key {
public static final class Triggerer {
public static final int KEYBOARD = 0;
public static final int SCREEN = 0;//Screen simulates keyboard presses and as for now shares same ID.
public static final int CONTROLLER_BUTTON = 1;
public static final int CONTROLLER_AXIS = 2;
}
public String name;
public int[] keyid;
Rectangle drawrec;
Rectangle origrec;
Rectangle rec;
int pointer = -1;
int triggerer = 0;
public boolean wasDown = false;
public boolean isDown = false;
public boolean nextState = false;
public Key(String name, int[] keyid) {
this.name = name;
this.keyid = keyid;
this.origrec = new Rectangle(-1f, -1f, 1f, 1f);
this.rec = new Rectangle(-1f, -1f, 1f, 1f);
this.drawrec = new Rectangle(-1f, -1f, 1f, 1f);
all.add(this);
}
public void down() {
//System.out.println("N: "+name+"; M: D; X: "+rec.x+"; Y:"+rec.y+"; W: "+rec.width+"; H: "+rec.height);
tmpkeylisteners.clear();
tmpkeylisteners.addAll(keylisteners);
for (KeyListener l : tmpkeylisteners) {
if (l instanceof Level && l != Shadow.level) {
continue;
}
if (l instanceof GameObject && ((GameObject)l).layer.level != Shadow.level) {
continue;
}
l.keyDown(this);
}
}
public void up() {
//System.out.println("N: "+name+"; M: U; X: "+rec.x+"; Y:"+rec.y+"; W: "+rec.width+"; H: "+rec.height);
tmpkeylisteners.clear();
tmpkeylisteners.addAll(keylisteners);
for (KeyListener l : tmpkeylisteners) {
if (l instanceof Level && l != Shadow.level) {
continue;
}
if (l instanceof GameObject && ((GameObject)l).layer.level != Shadow.level) {
continue;
}
l.keyUp(this);
}
}
public void tick() {
wasDown = isDown;
isDown = nextState;
rec.width = Shadow.dispw/Shadow.touchw;
rec.x = origrec.x*Shadow.dispw/Shadow.touchw;
rec.height = Shadow.disph/Shadow.touchh;
rec.y = origrec.y*Shadow.disph/Shadow.touchh;
if (wasPressed()) up();
if (wasReleased()) down();
}
public void render() {
if (isDown) {
Shadow.spriteBatch.setColor(1f, 0.5f, 0.5f, 0.575f);
} else {
Shadow.spriteBatch.setColor(1f, 1f, 1f, 0.575f);
}
Shadow.spriteBatch.draw(Images.getTextureRegion("white"), drawrec.x, drawrec.y, 1f, 1f);
}
public boolean wasPressed() {
return wasDown && !isDown;
}
public boolean wasReleased() {
return !wasDown && isDown;
}
public void setRect(float x, float y, float width, float height, boolean draw) {
origrec.set(x, y, width, height);
if (draw) {
drawrec.set(x, y, width, height);
}
}
}
public static Array<Key> all = new Array<Key>(Key.class);
public static Key up = new Key("Up", new int[] {Keys.UP, Keys.W});
public static Key jump = new Key("Jump", new int[] {Keys.UP, Keys.W});
public static Key down = new Key("Down", new int[] {Keys.DOWN, Keys.S});
public static Key left = new Key("Left", new int[] {Keys.LEFT, Keys.A});
public static Key right = new Key("Right", new int[] {Keys.RIGHT, Keys.D});
public static Key dash = new Key("Dash", new int[] {Keys.SHIFT_RIGHT, Keys.Q, Keys.E});
public static Key pause = new Key("Pause", new int[] {Keys.ESCAPE});
public static Key enter = new Key("Confirm", new int[] {Keys.ENTER});
public static Key screenshot = new Key("Screenshot", new int[] {Keys.F12});
public static Key record = new Key("Record", new int[] {Keys.F11});
public static Key androidBack = new Key("Back", new int[] {Keys.BACK});
public static Key androidMenu = new Key("Menu", new int[] {Keys.MENU});
public static IntMap<TouchPoint> touches = new IntMap<TouchPoint>();
public static Array<KeyListener> keylisteners = new Array<KeyListener>(KeyListener.class);
static Array<KeyListener> tmpkeylisteners = new Array<KeyListener>(KeyListener.class);
public static Key getKey(String name) {
for (Key key : all) {
if (key.name.equals(name)) {
return key;
}
}
return null;
}
public static void setUp() {
for (int i = 0; i < all.size; i++) {
Key k = all.items[i];
if (k.rec.x < 0) {
k.rec.x = -k.rec.x;
}
if (k.rec.y < 0) {
k.rec.y = -k.rec.y;
}
}
resize();
}
public static void resize() {
if (cam == null) {
cam = new OrthographicCamera(Shadow.touchw, -Shadow.touchh);
} else {
cam.viewportWidth = Shadow.touchw;
cam.viewportHeight = -Shadow.touchh;
}
cam.position.set(Shadow.touchw/2, Shadow.touchh/2, 0);
cam.update();
jump.setRect(Shadow.touchw-2, Shadow.touchh-3, 1, 1, true);
up.setRect(Shadow.touchw-2, Shadow.touchh-3, 1, 1, false);
down.setRect(Shadow.touchw-2, Shadow.touchh-2, 1, 1, true);
left.setRect(1, Shadow.touchh-2, 1, 1, true);
right.setRect(3, Shadow.touchh-2, 1, 1, true);
}
public static void tick() {
for (int i = 0; i < all.size; i++) {
Key k = all.items[i];
k.tick();
}
for (int i = 0; i < keylisteners.size; i++) {
KeyListener kl = keylisteners.items[i];
if (kl == null) {
keylisteners.removeValue(null, true);
i--;
continue;
}
check(kl);
}
}
public static ObjectIntMap<KeyListener> timemap = new ObjectIntMap<KeyListener>();
public static void check(KeyListener kl) {
if (Shadow.level instanceof LoadingLevel) {
return;
}
if (kl instanceof Level) {
Level sl = Shadow.level;
if (sl instanceof MenuLevel) {
//in menu
MenuLevel ml = (MenuLevel) sl;
boolean isInChain = false;
for (MenuLevel level = ml; level != null; level = level.parent) {
if (level == kl || level.bglevel == kl) {
isInChain = true;
break;
}
}
if (!isInChain) {
keylisteners.removeValue(kl, true);
}
} else {
//in-game
if (kl instanceof MenuLevel) {
keylisteners.removeValue(kl, true);
} else if (kl != sl) {
keylisteners.removeValue(kl, true);
}
}
}
if (kl instanceof GameObject) {
GameObject go = (GameObject) kl;
Level clevel = Shadow.level;
if (clevel instanceof MenuLevel) {
clevel = ((MenuLevel)clevel).bglevel;
}
if (go instanceof Entity) {
Entity e = (Entity) go;
if (e.layer == null || !e.layer.entities.contains(e, true) || clevel != e.layer.level) {
keylisteners.removeValue(kl, true);
}
}
if (go instanceof Block) {
Block b = (Block) go;
if (b.layer == null || !b.layer.blocks.contains(b, true) || clevel != b.layer.level) {
keylisteners.removeValue(kl, true);
}
}
}
}
public static void render() {
if (isAndroid && !isOuya && !isInMenu) {
for (int i = 0; i < all.size; i++) {
Key k = all.items[i];
k.render();
}
}
}
}