/* eslint-disable no-restricted-globals */
import React from "react";
import pako from "pako";

import * as helpers from "../helpers";
import MetadataDialog from "./MetadataDialog";
import gtag from "ga-gtag";
import {
	Divider,
	Snackbar,
	Button,
	FormControlLabel,
	FormControl,
	Box,
	Select,
	Tab,
	Tabs,
	Badge,
	AppBar,
	MenuItem,
	Toolbar,
	IconButton,
	Menu,
	SvgIcon,
	Typography,
	Switch,
} from "@material-ui/core";

import DipMap from "./DipMap";
import ChatMenu from "./ChatMenu";

import {
	ChatIcon,
	CloseIcon,
	DownloadIcon,
	EventIcon,
	FastForwardIcon,
	MapIcon,
	NextIcon,
	NumMembersIcon,
	PreviousIcon,
	ShareIcon,
	SettingsIcon,
} from "../icons";
import OrderList from "./OrderList";
import GamePlayers from "./GamePlayers";
import GameResults from "./GameResults";
import PreliminaryScores from "./PreliminaryScores";
import MusteringPopup from "./MusteringPopup";
import NationPreferencesDialog from "./NationPreferencesDialog";
import Globals from "../Globals";

export default class Game extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			readyReminder: false,
			phaseMessages: [],
			activeTab: "map",
			activePhase: null,
			phases: [],
			corroboration: { Properties: {} },
			variant: null,
			member: null,
			marginTop: 105,
			unreadMessages: 0,
			laboratoryMode: false,
			labEditMode: false,
			labPlayAs: "",
			gameStates: [],
			game: null,
		};
		this.renderedPhaseOrdinal = null;
		this.debugCounters = {};
		this.options = null;
		this.gamePlayersDialog = null;
		this.gameResults = null;
		this.preliminaryScores = null;
		this.nationPreferencesDialog = null;
		this.metadataDialog = null;
		this.changeTab = this.changeTab.bind(this);
		this.debugCount = this.debugCount.bind(this);
		this.changePhase = this.changePhase.bind(this);
		this.loadGame = this.loadGame.bind(this);
		this.receiveCorroboration = this.receiveCorroboration.bind(this);
		this.phaseJumper = this.phaseJumper.bind(this);
		this.phaseMessageHandler = this.phaseMessageHandler.bind(this);
		this.setUnreadMessages = this.setUnreadMessages.bind(this);
		this.labPhaseResolve = this.labPhaseResolve.bind(this);
		this.serializePhaseState = this.serializePhaseState.bind(this);
		this.onNewGameState = this.onNewGameState.bind(this);
		this.join = this.join.bind(this);
		this.joinWithPreferences = this.joinWithPreferences.bind(this);
		this.leave = this.leave.bind(this);
		this.refinePhaseMessage = this.refinePhaseMessage.bind(this);
		this.shareNative = this.shareNative.bind(this);
		// Dead means "unmounted", and is used to stop the chat channel from setting the URL
		// when it gets closed, if the parent game is unmounted.
		this.dead = false;
		this.dip_map = null;
		this.countdownInterval = null;
	}

	debugCount(tag) {
		if (!this.debugCounters[tag]) {
			this.debugCounters[tag] = 0;
		}
		this.debugCounters[tag] += 1;
	}
	refinePhaseMessage(msg) {
		const parts = msg.split(":");
		switch (parts[0]) {
			case "MustDisband":
				return "You must disband " + parts[1] + " units this phase.";
			case "MayBuild":
				return "You may build " + parts[1] + " units this phase.";
			default:
				return "";
		}
	}
	shareNative() {
		const hrefURL = new URL(location.href);

		if (navigator.share && !this.state.game.Properties.Started) {
		
			navigator
				.share({
					url:
						hrefURL.protocol +
						"//" +
						hrefURL.host +
						"/Game/" +
						this.state.game.Properties.ID,
					title: "Join my game at Diplicity!",
					text: "Hi! Please join my game of Diplomacy. Follow the link and click 'Join'.", //If you want to understand the rules, visit http://rules.diplicity.com
				})
				.then(() => {
						})
				.catch(() => {
					helpers
						.copyToClipboard(
							hrefURL.protocol +
								"//" +
								hrefURL.host +
								"/Game/" +
								this.state.game.Properties.ID
						)
						.then(
							(_) => {
								this.setState({
									moreMenuAnchorEl: null,
								});

								helpers.snackbar(
									"Game URL copied to clipboard. Share it to invite other players."
								);
							},
							(err) => {
								console.log(err);
							}
						);
					gtag("event", "game_share");
				});
		} else if (navigator.share && this.state.game.Properties.Started) {
			navigator
				.share({
					url:
						hrefURL.protocol +
						"//" +
						hrefURL.host +
						"/Game/" +
						this.state.game.Properties.ID,
					title: "View my game at Diplicity!",
					text: "Hi. Please check out my game of Diplomacy!", //If you want to understand the rules, visit http://rules.diplicity.com
				})
				.then(() => {
				})
				.catch(() => {

					helpers
						.copyToClipboard(
							hrefURL.protocol +
								"//" +
								hrefURL.host +
								"/Game/" +
								this.state.game.Properties.ID
						)
						.then(
							(_) => {
								this.setState({
									moreMenuAnchorEl: null,
								});

								helpers.snackbar(
									"Game URL copied to clipboard. Share it to show the game."
								);
							},
							(err) => {
								console.log(err);
							}
						);
					gtag("event", "game_share");
				});
		} else {
			console.log("No support for WebAPI, using snackbar");
			helpers
				.copyToClipboard(
					hrefURL.protocol +
						"//" +
						hrefURL.host +
						"/Game/" +
						this.state.game.Properties.ID
				)
				.then(
					(_) => {
						helpers.snackbar(
							"Game URL copied to clipboard. Share it to other players."
						);
					},
					(err) => {
						console.log(err);
					}
				);
			gtag("event", "game_share");
		}
	}
	leave() {
		const link = this.state.game.Links.find((l) => {
			return l.Rel === "leave";
		});
		helpers.incProgress();
		helpers
			.safeFetch(
				helpers.createRequest(link.URL, {
					method: link.Method,
				})
			)
			.then((resp) => resp.json())
			.then((_) => {
				helpers.decProgress();
				gtag("event", "game_leave");
				if (this.props.onLeaveGame) {
					this.props.onLeaveGame();
				}
				this.setState(
					(state, props) => {
						state = Object.assign({}, state);
						state.game.Links = state.game.Links.filter((l) => {
							return l.Rel !== "leave";
						});
						return state;
					},
					(_) => {
						if (this.state.game.Properties.Members.length > 1) {
							this.loadGame();
						}
					}
				);
			});
	}
	join() {
		if (this.state.game.Properties.NationAllocation === 1) {
			this.nationPreferencesDialog.setState({
				open: true,
				nations: this.state.variant.Properties.Nations,
				onSelected: (preferences) => {
					this.joinWithPreferences(preferences);
				},
			});
		} else {
			this.joinWithPreferences([]);
		}
	}
	joinWithPreferences(preferences) {
		const link = this.state.game.Links.find((l) => {
			return l.Rel === "join";
		});
		helpers.incProgress();
		helpers
			.safeFetch(
				helpers.createRequest(link.URL, {
					method: link.Method,
					headers: {
						"Content-Type": "application/json",
					},
					body: JSON.stringify({
						NationPreferences: preferences.join(","),
					}),
				})
			)
			.then((_) => {
				helpers.decProgress();
				gtag("event", "game_join");
				Globals.messaging.start();
				this.setState(
					(state, props) => {
						state = Object.assign({}, state);
						state.game.Links = state.game.Links.filter((l) => {
							return l.Rel !== "join";
						});
						return state;
					},
					(_) => {
						this.loadGame();
					}
				);
				if (this.props.onJoinGame) {
					this.props.onJoinGame();
				}
			});
	}
	onNewGameState(gameState) {
		this.setState((state, props) => {
			state = Object.assign({}, state);
			state.gameStates = state.gameStates.map((gs) => {
				if (gs.Properties.Nation === gameState.Properties.Nation) {
					gs.Properties = gameState.Properties;
				}
				return gs;
			});
			return state;
		});
	}
	serializePhaseState(phase) {
		return encodeURIComponent(
			encodeURIComponent(
				btoa(
					pako.deflate(
						JSON.stringify({
							activePhase: phase.Properties.PhaseOrdinal,
							phases: this.state.phases
								.map((p) => {
									if (
										p.Properties.PhaseOrdinal === phase.Properties.PhaseOrdinal
									) {
										return phase;
									} else {
										return p;
									}
								})
								.filter((p) => {
									return (
										!p.Properties.GameID ||
										p.Properties.PhaseOrdinal === phase.Properties.PhaseOrdinal
									);
								}),
						}),
						{ to: "string" }
					)
				)
			)
		);
	}
	labPhaseResolve(resolvedPhase, newPhase) {
		this.setState({
			phases: this.state.phases
				.map((oldPhase) => {
					if (
						oldPhase.Properties.PhaseOrdinal ===
						resolvedPhase.Properties.PhaseOrdinal
					) {
						return resolvedPhase;
					} else {
						return oldPhase;
					}
				})
				.filter((oldPhase) => {
					return (
						oldPhase.Properties.PhaseOrdinal < newPhase.Properties.PhaseOrdinal
					);
				})
				.concat([newPhase]),
			activePhase: newPhase,
		});
	}
	setUnreadMessages(n) {
		this.setState({ unreadMessages: n });
		if (this.props.unreadMessagesUpdate) {
			this.props.unreadMessagesUpdate();
		}
	}
	phaseJumper(steps) {
		return (_) => {
			let newPhase = this.state.phases.find((p) => {
				return (
					p.Properties.PhaseOrdinal ===
					this.state.activePhase.Properties.PhaseOrdinal + steps
				);
			});
			this.setState({ activePhase: newPhase });
		};
	}
	receiveCorroboration(corr) {
		this.setState({ corroboration: corr });
	}
	componentWillUnmount() {
		if (this.countdownInterval) {
			clearInterval(this.countdownInterval);
		}
		helpers.unback(this.props.close);
		this.dead = true;
		history.pushState("", "", "/");
		if (Globals.messaging.unsubscribe("phase", this.phaseMessageHandler)) {
			console.log("Game unsubscribing from `phase` notifications.");
		}
	}
	componentDidMount() {
		if (this.countdownInterval) {
			clearInterval(this.countdownInterval);
		}
		this.countdownInterval = setInterval((_) => {
			const els = document.getElementsByClassName("minute-countdown");
			for (let i = 0; i < els.length; i++) {
				const el = els[i];
				const deadline = new Date(parseFloat(el.getAttribute("dataat")));
				const deltaMinutes =
					((deadline.getTime() - new Date().getTime()) * 1e-3) / 60.0;
				el.innerText = helpers.minutesToDuration(deltaMinutes, true);
			}
		}, 30000);
		this.loadGame().then((_) => {
			helpers.urlMatch(
				[
					[
						/^\/Game\/([^/]+)\/Channel\/([^/]+)\/Messages$/,
						(match) => {
							this.setState({ activeTab: "chat" });
						},
					],
					[
						/^\/Game\/([^/]+)\/Lab\/(.+)$/,
						(match) => {
							const serializedState = JSON.parse(
								pako.inflate(
									atob(decodeURIComponent(decodeURIComponent(match[2]))),
									{
										to: "string",
									}
								)
							);
							const newPhases = this.state.phases.slice();
							serializedState.phases.forEach((phase) => {
								newPhases[phase.Properties.PhaseOrdinal - 1] = phase;
							});
							this.setState({
								laboratoryMode: true,
								activePhase: newPhases.find((phase) => {
									return (
										phase.Properties.PhaseOrdinal ===
										serializedState.activePhase
									);
								}),
								phases: newPhases,
							});
							gtag("set", {
								page_title: "Game",
								page_location: location.href,
							});
							gtag("event", "page_view");
						},
					],
				],
				(_) => {
					history.pushState("", "", "/Game/" + this.state.game.Properties.ID);
				}
			);
			if (Globals.messaging.subscribe("phase", this.phaseMessageHandler)) {
				console.log("Game subscribing to `phase` notifications.");
			}
		});
		helpers.onback(this.props.close);
	}
	phaseMessageHandler(payload) {
		if (payload.data.gameID !== this.state.game.Properties.ID) {
			return false;
		}
		this.loadGame().then((_) => {
			helpers.snackbar("New phase");
		});
		return true;
	}
	loadGame() {
		return this.props.gamePromise(!!this.state.game).then((game) => {
			const promises = [];
			const gameStatesLink = game.Links.find((l) => {
				return l.Rel === "game-states";
			});
			if (gameStatesLink) {
				promises.push(
					helpers
						.safeFetch(helpers.createRequest(gameStatesLink.URL))
						.then((res) => res.json())
				);
			}
			if (game.Properties.Started) {
				promises.push(
					helpers
						.safeFetch(
							helpers.createRequest(
								game.Links.find((l) => {
									return l.Rel === "phases";
								}).URL
							)
						)
						.then((resp) => resp.json())
						.then((js) => {
							return Promise.resolve(js.Properties);
						})
				);
			} else {
				const variantStartPhase =
					"/Variant/" + game.Properties.Variant + "/Start";
				promises.push(
					helpers.memoize(variantStartPhase, (_) => {
						return helpers
							.safeFetch(helpers.createRequest(variantStartPhase))
							.then((resp) => resp.json())
							.then((js) => {
								js.Properties.PhaseOrdinal = 1;
								return Promise.resolve([js]);
							});
					})
				);
			}
			return Promise.all(promises).then((values) => {
				const gameStates = gameStatesLink ? values[0].Properties : null;
				const phases = gameStatesLink ? values[1] : values[0];
				const member = (game.Properties.Members || []).find((e) => {
					return e.User.Email === Globals.user.Email;
				});
				const variant = Globals.variants.find((v) => {
					return v.Properties.Name === game.Properties.Variant;
				});
				this.setState(
					{
						gameStates: gameStates,
						variant: variant,
						member: member,
						labPlayAs: this.state.labPlayAs
							? this.state.labPlayAs
							: member && member.Nation
							? member.Nation
							: variant.Properties.Nations[0],
						phaseMessages: member
							? (member.NewestPhaseState.Messages || "")
									.split(",")
									.map(this.refinePhaseMessage)
									.filter((m) => {
										return !!m;
									})
							: [],
						readyReminder:
							member &&
							game.Properties.Started &&
							!game.Properties.Finished &&
							(!member.NewestPhaseState.NoOrders ||
								!game.Properties.Mustered) &&
							!member.NewestPhaseState.ReadyToResolve,
						game: game,
						marginTop: this.state.laboratoryMode
							? 56
							: game.Properties.Started
							? 105
							: 157,
						phases: phases,
						activePhase: phases[phases.length - 1],
					},
					(_) => {
						if (this.state.game.Properties.Finished) {
							this.gameResults.setState({
								open: true,
							});
						}
					}
				);
				return Promise.resolve({});
			});
		});
	}
	changeTab(ev, newValue) {
		this.setState({ activeTab: newValue });
	}
	changePhase(ev) {
		this.setState({
			activePhase: this.state.phases.find((phase) => {
				return phase.Properties.PhaseOrdinal === ev.target.value;
			}),
		});
	}
	render() {
		if (this.state.game) {
			return (
				<React.Fragment>
					<AppBar
						key="app-bar"
						position="fixed"
						color={this.state.laboratoryMode ? "secondary" : "primary"}
					>
						<Toolbar>
							{!this.state.laboratoryMode ? (
								<IconButton
									onClick={this.props.close}
									key="close"
									edge="start"
									color="secondary"
								>
									<CloseIcon />
								</IconButton>
							) : (
								<IconButton
									onClick={(_) => {
										this.setState(
											{
												moreMenuAnchorEl: null,
												laboratoryMode: !this.state.laboratoryMode,
											},
											(_) => {
												if (!this.state.laboratoryMode) {
													this.loadGame();
												} else {
													gtag("event", "enable_lab_mode");
												}
											}
										);
									}}
									key="close"
									edge="start"
									color="primary"
								>
									<CloseIcon />
								</IconButton>
							)}
							{!this.state.laboratoryMode &&
							this.state.activePhase &&
							this.state.activePhase.Properties.PhaseOrdinal > 1 ? (
								<IconButton
									onClick={this.phaseJumper(-1)}
									key="previous"
									edge="start"
									color="secondary"
								>
									<PreviousIcon />
								</IconButton>
							) : !this.state.laboratoryMode ? (
								<Box key="prev-spacer"></Box>
							) : (
								""
							)}

							{this.state.laboratoryMode ? (
								<Typography variant="h6" style={{ marginRight: "8px" }}>
									Sandbox
								</Typography>
							) : (
								""
							)}
							{this.state.activePhase ? (
								<Select
									/* TODO: This might be a stretch, but Laboratory mode has SOME "real" and some "fake" turns. E.g. in spring 1902 I can move back to Spring 1901 and create an "alternative" 1901 and commit that. 
                  Is it possible to make all the "hypothetical" phases to change color? Maybe let me know in the Discord chat and we can discuss more. */
									/*
									 * Yes it is - 'real' phases have .Properties.ID, while fake phases don't (IIRC).
									 */
									style={
										this.state.laboratoryMode
											? {
													width: "100%",
													minWidth: "0",
													borderBottom: "1px solid rgba(253, 226, 181, 0.7)",
													color: "rgb(40, 26, 26)",
											  }
											: {
													width: "100%",
													minWidth: "0",
													borderBottom: "1px solid rgba(253, 226, 181, 0.7)",
													color: "#FDE2B5",
											  }
									}
									key="phase-select"
									value={this.state.activePhase.Properties.PhaseOrdinal}
									onChange={this.changePhase}
									label={helpers.phaseName(this.state.activePhase)}
								>
									{this.state.phases.map((phase) => {
										return (
											<MenuItem
												key={phase.Properties.PhaseOrdinal}
												style={{
													textOverflow: "ellipsis",
												}}
												value={phase.Properties.PhaseOrdinal}
											>
												{helpers.phaseName(phase)}
												{!this.state.game.Properties.Started ||
												phase.Properties.Resolved ? (
													""
												) : (
													<span
														dataat={
															new Date().getTime() +
															phase.Properties.NextDeadlineIn * 1e-6
														}
														style={{
															position: "relative",
															top: "-6px",
															fontSize: "xx-small",
															left: "-5px",
															zIndex: "1",
															backgroundColor: "red",
															borderRadius: "7px",
															padding: "0 2px 1px 2px",
														}}
													>
														{helpers.minutesToDuration(
															(phase.Properties.NextDeadlineIn * 1e-9) / 60.0,
															true
														)}
													</span>
												)}
											</MenuItem>
										);
									})}
								</Select>
							) : !this.state.laboratoryMode ? (
								<Box key="curr-spacer" width="100%"></Box>
							) : (
								""
							)}
							{this.state.activePhase &&
							this.state.activePhase.Properties.PhaseOrdinal <
								this.state.phases[this.state.phases.length - 1].Properties
									.PhaseOrdinal ? (
								<IconButton
									onClick={this.phaseJumper(1)}
									edge="end"
									key="next"
									color="secondary"
								>
									<NextIcon />
								</IconButton>
							) : !this.state.laboratoryMode ? (
								<Box key="next-spacer"></Box>
							) : (
								""
							)}

							{!this.state.laboratoryMode ? (
								<IconButton
									edge="end"
									key="more-icon"
									color="secondary"
									onClick={(ev) => {
										this.setState({
											moreMenuAnchorEl: ev.currentTarget,
										});
									}}
								>
									<SettingsIcon />
								</IconButton>
							) : (
								""
							)}
							<Menu
								anchorEl={this.state.moreMenuAnchorEl}
								anchorOrigin={{
									vertical: "top",
									horizontal: "right",
								}}
								transformOrigin={{
									vertical: "top",
									horizontal: "right",
								}}
								onClose={(_) => {
									this.setState({ moreMenuAnchorEl: null });
								}}
								open={!!this.state.moreMenuAnchorEl}
							>
								<MenuItem
									key="game-metadata"
									onClick={(_) => {
										this.setState({
											moreMenuAnchorEl: null,
										});
										if (this.state.game.Properties.Started) {
											this.gamePlayersDialog.setState({
												open: true,
											});
										} else {
											this.metadataDialog.setState({
												open: true,
											});
										}
									}}
								>
									Game & player info
								</MenuItem>
								{this.state.game.Properties.Started
									? [
											<MenuItem
												key="scores"
												onClick={(_) => {
													this.setState({
														moreMenuAnchorEl: null,
													});
													this.preliminaryScores.setState({
														open: true,
													});
												}}
											>
												Scores
											</MenuItem>,
											this.state.game.Properties.Finished ? (
												<MenuItem
													key="results"
													onClick={(_) => {
														this.setState({
															moreMenuAnchorEl: null,
														});
														this.gameResults.setState({
															open: true,
														});
													}}
												>
													Results
												</MenuItem>
											) : (
												""
											),
									  ]
									: ""}
								<Divider />
								<MenuItem key="game-id" onClick={this.shareNative}>
									{this.state.game.Properties.Started
										? "Share game"
										: "Invite players"}
								</MenuItem>

								<MenuItem
									key="download-map"
									onClick={(_) => {
										this.setState({
											moreMenuAnchorEl: null,
										});
										this.dip_map.downloadMap();
										gtag("event", "download_map");
									}}
								>
									Download map
								</MenuItem>
								<MenuItem
									key="laboratory-mode"
									onClick={(_) => {
										this.setState(
											{
												moreMenuAnchorEl: null,
												laboratoryMode: !this.state.laboratoryMode,
											},
											(_) => {
												if (!this.state.laboratoryMode) {
													this.loadGame();
												} else {
													gtag("event", "enable_lab_mode");
												}
											}
										);
									}}
								>
									{this.state.laboratoryMode
										? "Turn off sandbox mode"
										: "Sandbox mode"}
								</MenuItem>
								<Divider />
								<MenuItem
									key="How to play"
									onClick={(_) => {
										window.open(
											"https://diplicity.notion.site/How-to-play-39fbc4d1f1924c928c3953095062a983",
											"_blank"
										);
									}}
								>
									How to play
								</MenuItem>
								<MenuItem
									key="debug-data"
									onClick={(_) => {
										helpers
											.copyToClipboard(JSON.stringify(this.debugCounters))
											.then((_) => {
												this.setState({
													moreMenuAnchorEl: null,
												});
												helpers.snackbar("Debug data copied to clipboard");
											});
									}}
								>
									Debug
								</MenuItem>
							</Menu>
							{this.state.laboratoryMode ? (
								<React.Fragment>
									<IconButton
										onClick={(_) => {
											this.dip_map.downloadMap();
											gtag("event", "download_map");
										}}
										color="primary"
										edge="end"
										style={{ marginLeft: "auto" }}
									>
										<DownloadIcon />
									</IconButton>
									<IconButton
										onClick={(_) => {
											this.dip_map.labShare();
										}}
										color="primary"
										edge="end"
										style={{ marginLeft: "auto" }}
									>
										<ShareIcon />
									</IconButton>
								</React.Fragment>
							) : (
								""
							)}
						</Toolbar>
						{!this.state.laboratoryMode ? (
							<React.Fragment>
								{!this.state.game.Properties.Started ||
								this.state.game.Links.find((l) => {
									return l.Rel === "join";
								}) ? (
									<Toolbar
										style={{
											display: "flex",
											justifyContent: "space-between",
											minHeight: "53px",
										}}
									>
										<div>
											{this.state.game.Links.find((l) => {
												return l.Rel === "join";
											}) ? (
												<Button
													variant="outlined"
													color="secondary"
													key="join"
													onClick={this.join}
												>
													Join
												</Button>
											) : (
												""
											)}
											{this.state.game.Links.find((l) => {
												return l.Rel === "leave";
											}) ? (
												<Button
													variant="outlined"
													color="secondary"
													key="leave"
													onClick={this.leave}
												>
													Leave
												</Button>
											) : (
												""
											)}
										</div>
										<div
											style={{
												display: "flex",
												alignItems: "center",
											}}
										>
											<NumMembersIcon />{" "}
											<Typography
											//TODO: Change this to not NMembers but Nmembers - replaceable.
												variant="body2"
												style={{ paddingLeft: "2px" }}
											>
												{this.state.game.Properties.NMembers}/
												{this.state.variant.Properties.Nations.length}{" "}
											</Typography>
										</div>
									</Toolbar>
								) : (
									""
								)}
								<Tabs
									key="tabs"
									value={this.state.activeTab}
									onChange={this.changeTab}
									display="flex"
									variant="fullWidth"
								>
									<Tab value="map" icon={<MapIcon />} />
									<Tab
										value="chat"
										icon={
											this.state.member && this.state.unreadMessages > 0 ? (
												<Badge badgeContent={this.state.unreadMessages}>
													<ChatIcon />
												</Badge>
											) : (
												<ChatIcon />
											)
										}
									/>
									{this.state.game.Properties.Started ? (
										this.state.member &&
										!this.state.activePhase.Properties.Resolved ? (
											this.state.member.NewestPhaseState.OnProbation ||
											!this.state.member.NewestPhaseState.ReadyToResolve ? (
												<Tab
													value="orders"
													icon={
														<SvgIcon>
															<path
																d="M9,0 C10.3,0 11.4,0.84 11.82,2 L11.82,2 L16,2 C17.1045695,2 18,2.8954305 18,4 L18,4 L18,18 C18,19.1045695 17.1045695,20 16,20 L16,20 L2,20 C0.8954305,20 0,19.1045695 0,18 L0,18 L0,4 C0,2.8954305 0.8954305,2 2,2 L2,2 L6.18,2 C6.6,0.84 7.7,0 9,0 Z M5,14 L3,14 L3,16 L5,16 L5,14 Z M15,14 L7,14 L7,16 L15,16 L15,14 Z M5,6 L3,6 L3,12 L5,12 L5,6 Z M15,10 L7,10 L7,12 L15,12 L15,10 Z M15,6 L7,6 L7,8 L15,8 L15,6 Z M9,2 C8.44771525,2 8,2.44771525 8,3 C8,3.55228475 8.44771525,4 9,4 C9.55228475,4 10,3.55228475 10,3 C10,2.44771525 9.55228475,2 9,2 Z"
																id="order_open"
															></path>
														</SvgIcon>
													}
												/>
											) : (
												<Tab
													value="orders"
													icon={
														<SvgIcon>
															<path
																d="M9,0 C10.3,0 11.4,0.84 11.82,2 L11.82,2 L16,2 C17.1045695,2 18,2.8954305 18,4 L18,4 L18,18 C18,19.1045695 17.1045695,20 16,20 L16,20 L2,20 C0.8954305,20 0,19.1045695 0,18 L0,18 L0,4 C0,2.8954305 0.8954305,2 2,2 L2,2 L6.18,2 C6.6,0.84 7.7,0 9,0 Z M13.4347826,7 L7.70608696,12.7391304 L4.56521739,9.60869565 L3,11.173913 L7.70608696,15.8695652 L15,8.56521739 L13.4347826,7 Z M9,2 C8.44771525,2 8,2.44771525 8,3 C8,3.55228475 8.44771525,4 9,4 C9.55228475,4 10,3.55228475 10,3 C10,2.44771525 9.55228475,2 9,2 Z"
																id="order_confirmed"
															></path>
														</SvgIcon>
													}
												/>
											)
										) : (
											<Tab value="orders" icon={<EventIcon />} />
										)
									) : (
										""
									)}
								</Tabs>
							</React.Fragment>
						) : (
							<Toolbar>
								<Typography variant="body1" style={{ marginRight: "8px" }}>
									Edit
								</Typography>
								<FormControlLabel
									key="edit-mode"
									control={
										<Switch
											onChange={(ev) => {
												this.setState({
													labEditMode: !ev.target.checked,
												});
												this.dip_map.setState({
													labEditMode: !ev.target.checked,
												});
											}}
											color="primary"
											checked={!this.state.labEditMode}
										/>
									}
									label="Play as"
								/>
								{!this.state.labEditMode ? (
									<FormControl
										key="play-as"
										style={{
											flexGrow: 1,
										}}
									>
										<Select
											value={this.state.labPlayAs}
											onChange={(ev) => {
												this.setState({
													labPlayAs: ev.target.value,
												});
												this.dip_map.setState({
													labPlayAs: ev.target.value,
												});
											}}
											style={{
												width: "100%",
												minWidth: "0",
												borderBottom: "1px solid rgba(253, 226, 181, 0.7)",
												color: "rgb(40, 26, 26)",
											}}
										>
											{this.state.variant.Properties.Nations.map((nation) => {
												return (
													<MenuItem key={nation} value={nation}>
														{nation}
													</MenuItem>
												);
											})}
										</Select>
									</FormControl>
								) : (
									""
								)}

								<IconButton
									edge="end"
									onClick={(ev) => {
										this.dip_map.labResolve();
									}}
									style={{
										marginLeft: "auto",
										color: "rgb(40, 26, 26)",
									}}
								>
									<FastForwardIcon />
								</IconButton>
							</Toolbar>
						)}
					</AppBar>

					<div
						key="map-container"
						style={
							this.state.laboratoryMode
								? {
										marginTop: "" + this.state.marginTop + "px",
										height: "calc(100% - " + this.state.marginTop + "px)",
										backgroundColor: "black",
										display: this.state.activeTab === "map" ? "block" : "none",
								  }
								: {
										marginTop: "" + this.state.marginTop + "px",
										height: "calc(100% - " + this.state.marginTop + "px)",
										backgroundColor: "black",
										display: this.state.activeTab === "map" ? "block" : "none",
								  }
						}
					>
						<DipMap
							parentCB={(c) => {
								this.dip_map = c;
							}}
							onLeaveProbation={(_) => {
								this.loadGame();
							}}
							debugCount={this.debugCount}
							labPhaseResolve={this.labPhaseResolve}
							serializePhaseState={this.serializePhaseState}
							laboratoryMode={this.state.laboratoryMode}
							isActive={this.state.activeTab === "map"}
							game={this.state.game}
							phase={this.state.activePhase}
							corroborateSubscriber={this.receiveCorroboration}
							variant={this.state.variant}
						/>
					</div>
					<React.Fragment>
						<div
							key="chat-container"
							style={{
								marginTop: "" + this.state.marginTop + "px",
								height: "calc(100% - " + this.state.marginTop + "px)",
								display: this.state.activeTab === "chat" ? "block" : "none",
							}}
						>
							<ChatMenu
								onNewGameState={this.onNewGameState}
								gameState={
									this.state.member && this.state.gameStates
										? this.state.gameStates.find((gs) => {
												return (
													gs.Properties.Nation === this.state.member.Nation
												);
										  })
										: null
								}
								isActive={this.state.activeTab === "chat"}
								unreadMessages={this.setUnreadMessages}
								phases={this.state.phases}
								game={this.state.game}
								parent={this}
							/>
						</div>
						{this.state.game.Properties.Started ? (
							<div
								key="orders-container"
								style={{
									marginTop: "" + this.state.marginTop + "px",
									height: "calc(100% - " + this.state.marginTop + "px)",
									display: this.state.activeTab === "orders" ? "flex" : "none",
									flexDirection: "column",
									justifyContent: "space-between",
								}}
							>
								<OrderList
									isActive={this.state.activeTab === "orders"}
									member={this.state.member}
									phase={this.state.activePhase}
									corroboration={this.state.corroboration}
									newPhaseStateHandler={(phaseState) => {
										this.setState((state, props) => {
											state = Object.assign({}, state);
											state.member.NewestPhaseState = phaseState.Properties;
											return state;
										});
										if (this.props.onChangeReady) {
											this.props.onChangeReady();
										}
									}}
									variant={this.state.variant}
								/>
							</div>
						) : (
							""
						)}
						<GamePlayers
							gameStates={this.state.gameStates}
							game={this.state.game}
							variant={this.state.variant}
							onNewGameState={this.onNewGameState}
							parentCB={(c) => {
								this.gamePlayersDialog = c;
							}}
						/>
						<PreliminaryScores
							phases={this.state.phases}
							variant={this.state.variant}
							parentCB={(c) => {
								this.preliminaryScores = c;
							}}
						/>
					</React.Fragment>
					{!this.state.game.Properties.Started ? (
						<React.Fragment>
							<NationPreferencesDialog
								parentCB={(c) => {
									this.nationPreferencesDialog = c;
								}}
								onSelected={null}
							/>
							<MetadataDialog
								game={this.state.game}
								parentCB={(c) => {
									this.metadataDialog = c;
								}}
							/>
						</React.Fragment>
					) : (
						""
					)}
					{!this.state.member ||
					!this.state.game.Properties.Started ||
					this.state.game.Properties.Mustered ? (
						""
					) : (
						<MusteringPopup
							viewOrders={(_) => {
								this.setState({
									activeTab: "orders",
									readyReminder: false,
								});
							}}
						/>
					)}
					<GameResults
						onNewGameState={this.onNewGameState}
						gameState={
							this.state.member && this.state.gameStates
								? this.state.gameStates.find((gs) => {
										return gs.Properties.Nation === this.state.member.Nation;
								  })
								: null
						}
						game={this.state.game}
						variant={this.state.variant}
						parentCB={(c) => {
							this.gameResults = c;
						}}
					/>
					<Snackbar
						anchorOrigin={{
							vertical: "bottom",
							horizontal: "center",
						}}
						open={this.state.readyReminder}
						autoHideDuration={30000}
						onClose={(_) => {
							this.setState({ readyReminder: false });
						}}
						message={[
							<Typography key="ready-warning">
								You haven't confirmed your orders yet.
								{this.state.game.Properties.Mustered
									? ""
									: " For the game to start, all players have to confirm as ready to play."}
							</Typography>,
						].concat(
							this.state.phaseMessages.map((m) => {
								return <Typography key={m}>{m}</Typography>;
							})
						)}
						action={
							<React.Fragment>
								<Button
									color="secondary"
									size="small"
									onClick={(_) => {
										this.setState({
											activeTab: "orders",
											readyReminder: false,
										});
									}}
								>
									View orders
								</Button>
								<IconButton
									size="small"
									aria-label="close"
									color="inherit"
									onClick={(_) => {
										this.setState({ readyReminder: false });
									}}
								>
									<CloseIcon />
								</IconButton>
							</React.Fragment>
						}
					/>
				</React.Fragment>
			);
		} else {
			return "";
		}
	}
}