/*
 * Kangaroo Punch MultiPlayer Game Server Mark II
 * Copyright (C) 2020-2021  Scott Duensing
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */


#include "textbox.h"
#include "button.h"
#include "msgbox.h"
#include "timer.h"

#include "runtime.h"
#include "config.h"
#include "comport.h"
#include "network.h"
#include "taglist.h"

#include "login.h"
#include "signup.h"
#include "welcome.h"
#include "menu.h"
#include "hangup.h"


typedef enum LoginStateE {
	S_START_LOGIN = 0,
	S_WAIT_LOGIN
} LoginStateT;


static WindowT     *_winLogin     = NULL;
static TextboxT    *_txtUser      = NULL;
static TextboxT    *_txtPass      = NULL;
static ButtonT     *_btnCancel    = NULL;
static ButtonT     *_btnSignUp    = NULL;
static ButtonT     *_btnLogin     = NULL;
static TimerT      *_timProgress  = NULL;
static LoginStateT  _state        = S_START_LOGIN;
static uint8_t      _channel      = 0;


static void btnCancelClick(WidgetT *widget);
static void btnLoginClick(WidgetT *widget);
static void btnSignUpClick(WidgetT *widget);
static void btnMsgBoxCancel(MsgBoxButtonT button);
static void btnMsgBoxContinue(MsgBoxButtonT button);
static void packetHandler(PacketDecodeDataT *packet);
static void setButtons(uint8_t enabled);
static void timLoginProgress(WidgetT *widget);


static void btnCancelClick(WidgetT *widget) {
	(void)widget;

	setButtons(0);
	msgBoxTwo("Cancel?", MSGBOX_ICON_QUESTION, "Cancel login?\n \nThis will disconnect you from the server.", "Okay", btnMsgBoxCancel, "Cancel", btnMsgBoxCancel);
}


static void btnLoginClick(WidgetT *widget) {
	(void)widget;

	setButtons(0);

	_state = S_START_LOGIN;
	timerQuarterSecondsSet(_timProgress, 0);
	timerStart(_timProgress);
}


static void btnSignUpClick(WidgetT *widget) {
	(void)widget;

	netChannelRelease(_channel);
	guiDelete(D(_winLogin));
	signupShow();
}


static void btnMsgBoxCancel(MsgBoxButtonT button) {

	if (button == MSGBOX_BUTTON_ONE) {
		netChannelRelease(_channel);
		guiDelete(D(_winLogin));
		hangupShow(welcomeShow);
	} else {
		setButtons(1);
	}
}


static void btnMsgBoxContinue(MsgBoxButtonT button) {
	(void)button;

	setButtons(1);
}


void loginShow() {

	// ***TODO*** We used to have a FORGOT PASSWORD link here, too.

	TagItemT uiLogin[] = {
		T_START,
			T_WINDOW, O(_winLogin),
				T_TITLE, P("Login"),
				T_WIDTH, 300, T_HEIGHT, 155,

				T_TEXTBOX, O(_txtUser),
					T_TITLE, P("User Name:"),
					T_X, 42, T_Y, 10,
					T_WIDTH, 200,
					T_LENGTH, shget(__runtimeData.integers, "maxUser"),
				T_TEXTBOX, T_DONE,

				T_TEXTBOX, O(_txtPass),
					T_TITLE, P(" Password:"),
					T_X, 42, T_Y, 40,
					T_WIDTH, 200,
					T_LENGTH, shget(__runtimeData.integers, "maxPass"),
					T_MASK, '*',
				T_TEXTBOX, T_DONE,

				T_BUTTON, O(_btnCancel),
					T_TITLE, P("Cancel"),
					T_X, 25, T_Y, 85,
					T_CLICK, P(btnCancelClick),
				T_BUTTON, T_DONE,
				T_BUTTON, O(_btnSignUp),
					T_TITLE, P("Sign Up"),
					T_X, 110, T_Y, 85,
					T_CLICK, P(btnSignUpClick),
				T_BUTTON, T_DONE,
				T_BUTTON, O(_btnLogin),
					T_TITLE, P("Login"),
					T_X, 199, T_Y, 85,
					T_CLICK, P(btnLoginClick),
				T_BUTTON, T_DONE,
				T_TIMER, O(_timProgress),
					T_EVENT, P(timLoginProgress),
					T_VALUE, 0,
					T_ENABLED, 0,
				T_TIMER, T_DONE,

			T_WINDOW, T_DONE,
		T_END
	};

	tagListRun(uiLogin);
	_channel = netChannelGet(packetHandler);

	textboxValueSet(_txtUser, "test");
	textboxValueSet(_txtPass, "test");
}


static void packetHandler(PacketDecodeDataT *packet) {
	char   *packetData;
	int8_t  success;

	switch (packet->packetType) {
		case PACKET_TYPE_LOGIN_RESULT:
			packetContentUnpack(packet->data, "is", &success, &packetData);
			if (success) {
				netChannelRelease(_channel);
				guiDelete(D(_winLogin));
				menuShow();
			} else {
				msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
			}
			DEL(packetData);
			timerStop(_timProgress);
			break;

		default:
			timerStop(_timProgress);
			msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "Unexpected packet received.", "Okay", btnMsgBoxContinue);
			break;
	}

	packetDecodeDataDestroy(&packet);
}


static void setButtons(uint8_t enabled) {
	// ***TODO*** This should disable the entire dialog instead of just the buttons.  Need to finish the Enable GUI code first.

	widgetEnableSet(W(_btnCancel), enabled);
	widgetEnableSet(W(_btnSignUp), enabled);
	widgetEnableSet(W(_btnLogin), enabled);
}


static void timLoginProgress(WidgetT *widget) {
	char              *packetData;
	uint16_t           length;
	PacketEncodeDataT  encoded;
	TimerT            *t           = (TimerT *)widget;

	switch (_state) {
		case S_START_LOGIN:
			setButtons(0);
			packetData = packetContentPack(&length, "ss", textboxValueGet(_txtUser), textboxValueGet(_txtPass));
			// Send login request.
			encoded.packetType = PACKET_TYPE_LOGIN;
			encoded.control    = PACKET_CONTROL_DAT;
			encoded.channel    = _channel;
			encoded.encrypt    = 1;
			packetEncode(__packetThreadData, &encoded, packetData, length);
			packetSend(__packetThreadData, &encoded);
			DEL(packetData);
			// Wait for response.
			timerQuarterSecondsSet(t, 10 * 4);
			_state = S_WAIT_LOGIN;
			break;

		case S_WAIT_LOGIN:
			timerStop(t);
			msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "No response received.", "Okay", btnMsgBoxContinue);
			break;
	}
}

