package com.cardshifter.gdx.screens;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.cardshifter.api.both.ChatMessage;
import com.cardshifter.api.both.InviteRequest;
import com.cardshifter.api.both.InviteResponse;
import com.cardshifter.api.both.PlayerConfigMessage;
import com.cardshifter.api.config.DeckConfig;
import com.cardshifter.api.incoming.LoginMessage;
import com.cardshifter.api.incoming.ServerQueryMessage;
import com.cardshifter.api.messages.Message;
import com.cardshifter.api.outgoing.AvailableModsMessage;
import com.cardshifter.api.outgoing.NewGameMessage;
import com.cardshifter.api.outgoing.UserStatusMessage;
import com.cardshifter.gdx.*;
import com.cardshifter.gdx.ui.UsersList;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Zomis on 2014-11-11.
*/
public class ClientScreen implements Screen, CardshifterMessageHandler {
private final CardshifterClient client;
private final Map<Class<? extends Message>, SpecificHandler<?>> handlerMap = new HashMap<Class<? extends Message>, SpecificHandler<?>>();
private final Table table;
private final CardshifterGame game;
private final TextArea chatMessages;
private final TextField messageField;
private final UsersList usersList;
private String[] availableMods;
private GameScreen gameScreen;
private String currentModName;
private ScrollPane chatScrollPane;
public ClientScreen(final CardshifterGame game, String host, int port, final String username) {
this.game = game;
client = game.getPlatform().createClient(host, port, this, new LoginMessage(username));
table = new Table(game.skin);
table.setFillParent(true);
Label titleLabel = new Label("Welcome to Cardshifter", game.skin);
table.add(titleLabel);
Label usersListLabel = new Label("Users Online:", game.skin);
table.add(usersListLabel).colspan(2);
table.row();
this.chatMessages = new TextArea("", game.skin);
this.chatMessages.setDisabled(true);
this.chatScrollPane = new ScrollPane(this.chatMessages);
this.chatScrollPane.setScrollingDisabled(true, false);
table.add(this.chatScrollPane).expand().fill();
usersList = new UsersList(game.skin, new Callback<String>() {
@Override
public void callback(String object) {
currentModName = object;
}
});
ScrollPane userScrollPane = new ScrollPane(usersList.getTable());
table.add(userScrollPane).top().colspan(2);
//table.add(usersList.getGroup()).right().expandY().fill().colspan(2);
table.row();
this.messageField = new TextField("", game.skin);
this.messageField.addListener(new InputListener() {
public boolean keyTyped(InputEvent event, char character) {
if (character == '\r' || character == '\n') {
ClientScreen.this.sendChatMessage();
return true;
} else {
return false;
}
}
});
table.add(this.messageField).bottom().expandX().fill();
TextButton sendMessageButton = new TextButton("Send", game.skin);
sendMessageButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
ClientScreen.this.sendChatMessage();
}
});
table.add(sendMessageButton).fill();
TextButton inviteButton = new TextButton("Invite", game.skin);
inviteButton.addListener(new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
usersList.inviteSelected(availableMods, game.stage, client);
}
});
table.add(inviteButton).fill();
this.configureHandler();
/* Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
client.send(new LoginMessage(username));
}
});*/
}
private void configureHandler() {
handlerMap.put(AvailableModsMessage.class, new SpecificHandler<AvailableModsMessage>() {
@Override
public void handle(AvailableModsMessage message) {
availableMods = message.getMods();
client.send(new ServerQueryMessage(ServerQueryMessage.Request.USERS));
}
});
handlerMap.put(ChatMessage.class, new SpecificHandler<ChatMessage>() {
@Override
public void handle(ChatMessage message) {
String time = game.getPlatform().getTimeString();
String append = "\n" + "[" + time + "] " + message.getFrom() + ": " + message.getMessage();
chatMessages.setText(chatMessages.getText() + append);
int numberOfScrollLines = chatMessages.getText().split("\n").length;
chatMessages.setPrefRows(numberOfScrollLines);
ClientScreen.this.chatScrollPane.layout();
ClientScreen.this.chatScrollPane.setScrollY(ClientScreen.this.chatMessages.getHeight());
}
});
handlerMap.put(UserStatusMessage.class, new SpecificHandler<UserStatusMessage>() {
@Override
public void handle(UserStatusMessage message) {
usersList.handleUserStatus(message);
}
});
handlerMap.put(NewGameMessage.class, new SpecificHandler<NewGameMessage>() {
@Override
public void handle(NewGameMessage message) {
gameScreen = new GameScreen(game, client, message, ClientScreen.this);
handlerMap.putAll(gameScreen.getHandlers());
game.setScreen(gameScreen);
}
});
handlerMap.put(PlayerConfigMessage.class, new SpecificHandler<PlayerConfigMessage>() {
@Override
public void handle(final PlayerConfigMessage message) {
DeckConfig deckConfig = (DeckConfig) message.getConfigs().get("Deck");
if (deckConfig != null) {
game.setScreen(new DeckBuilderScreen(ClientScreen.this, game, currentModName, message.getGameId(), deckConfig, new Callback<DeckConfig>() {
@Override
public void callback(DeckConfig object) {
game.setScreen(gameScreen);
client.send(message);
}
}));
}
}
});
handlerMap.put(InviteRequest.class, new SpecificHandler<InviteRequest>() {
@Override
public void handle(final InviteRequest message) {
Dialog dialog = new Dialog("Invite", game.skin) {
@Override
protected void result(Object object) {
boolean response = (Boolean) object;
client.send(new InviteResponse(message.getId(), response));
}
};
currentModName = message.getGameType();
dialog.text(message.getName() + " invites you to play " + message.getGameType());
dialog.button("Accept", true);
dialog.button("Decline", false);
dialog.show(game.stage);
}
});
}
private void sendChatMessage() {
String message = this.messageField.getText();
if (message != null) {
this.client.send(new ChatMessage(1, "unused", message));
this.messageField.setText("");
}
}
@Override
public void render(float delta) {
}
@Override
public void resize(int width, int height) {
}
@Override
public void show() {
game.stage.addActor(table);
}
@Override
public void hide() {
table.remove();
}
@Override
public void pause() {
}
@Override
public void resume() {
}
@Override
public void dispose() {
}
@Override
public void handle(final Message message) {
Gdx.app.postRunnable(new Runnable() {
@Override
public void run() {
final SpecificHandler<Message> handler = (SpecificHandler<Message>) handlerMap.get(message.getClass());
if (handler != null) {
handler.handle(message);
}
else {
Gdx.app.log("Client", "WARNING: Unable to handle " + message + " of type " + message.getClass());
}
}
});
}
}