package com.xikka.client;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.json.JSONObject;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.request.GetRequest;
import com.mashape.unirest.request.HttpRequestWithBody;

public class GameClientMain {
	// Windows
	private final JFrame mainFrame = new JFrame();
	
	// Panels
	private JPanel current;
	private final ServerSelectPanel serverSelectPanel;
	private final LoginPanel loginPanel;
	private final GamesPanel gamesPanel;
	private final RoomsPanel roomsPanel;
	
	// State
	private static GameClientMain self;
	private String server;
	private int userId;
	private String authToken;
	private String game;
	
	public static void main(String args[]) {
		new GameClientMain();
	}
	
	private GameClientMain() {
		self = this;
		
		mainFrame.setTitle("Game Client");
		mainFrame.setSize(400, 400);
		mainFrame.setResizable(true);
		mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		mainFrame.addWindowListener(new WindowAdapter() {
	        public void windowClosing(WindowEvent winEvt) {
	        	System.out.println("Shutting down.");
	        	if (current instanceof StoppablePanel) {
					((StoppablePanel) current).onStop();
					setCurrentPanel(roomsPanel);
				} else {
					try {
						Unirest.shutdown();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.exit(0);
				}
	        }
	    });
		
		roomsPanel = new RoomsPanel(session -> {
			if ("noughts".equals(game)) {
				// Go to it!
				NoughtsSessionPanel noughtsSessionPanel = new NoughtsSessionPanel(session);
				setCurrentPanel(noughtsSessionPanel);
			} else {
				// Go to something else?
				System.err.println("This game is not supported.");
			}
			return null;
		});
		gamesPanel = new GamesPanel(game -> {
			this.game = game;
			setCurrentPanel(roomsPanel);
			return null;
		});
		loginPanel = new LoginPanel((userId, token)-> {
			this.authToken = token;
			this.userId = userId;
			setCurrentPanel(gamesPanel);
			return null;
		});
		serverSelectPanel = new ServerSelectPanel(server -> {
			this.server = server;
			setCurrentPanel(loginPanel);
			return null;
		});
		
		setCurrentPanel(serverSelectPanel);
		centreWindow();
	}
	
	public static HttpRequestWithBody post(String url) {
		HttpRequestWithBody req = Unirest
				.post(self.server + "/" + url);
		if (url.contains("{game}") && self.game != null)
			req.routeParam("game", self.game);
		if (self.authToken != null)
			req.header("Authorization", "Bearer " + self.authToken);
		return req;
	}
	public static HttpRequestWithBody delete(String url) {
		HttpRequestWithBody req = Unirest
				.delete(self.server + "/" + url);
		if (url.contains("{game}") && self.game != null)
			req.routeParam("game", self.game);
		if (self.authToken != null)
			req.header("Authorization", "Bearer " + self.authToken);
		return req;
	}
	public static GetRequest get(String url) {
		GetRequest req = Unirest
				.get(self.server + "/" + url);
		if (url.contains("{game}") && self.game != null)
			req.routeParam("game", self.game);
		if (self.authToken != null)
			req.header("Authorization", "Bearer " + self.authToken);
		return req;
	}
	public static void handleErrorResponses(HttpResponse<JsonNode> response) {
		int status = response.getStatus();
		if (status == 400) {
			JSONObject o = response.getBody().getObject();
			JOptionPane.showMessageDialog(null,
				    o.has("description") ? o.getString("description") : response.getBody(),
				    "Error",
				    JOptionPane.ERROR_MESSAGE);
		} else if (status >= 500 && status <= 599) {
			JOptionPane.showMessageDialog(null,
				    "Error " + status + ": Check server logs",
				    "Server Error",
				    JOptionPane.ERROR_MESSAGE);
		}
	}
	public static boolean isSuccessfulResponse(HttpResponse<?> response) {
		int status = response.getStatus();
		return status >= 200 && status <= 299;
	}
	
	void setCurrentPanel(JPanel panel) {
		if (current != null)
			mainFrame.remove(current);
		current = panel;
		if (panel instanceof SelectablePanel) {
			((SelectablePanel) panel).onSelect();
		}
		mainFrame.add(panel);
		mainFrame.pack();
		//centreWindow();
		mainFrame.setVisible(true);
		
		//mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	void centreWindow() {
		Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
	    int x = (int) ((dimension.getWidth() - mainFrame.getWidth()) / 2);
	    int y = (int) ((dimension.getHeight() - mainFrame.getHeight()) / 2);
	    mainFrame.setLocation(x, y);
	}
}
