////////////////////////////////////////////////////////////////////////////////
//    Scorched3D (c) 2000-2011, 2026
//
//    This file is part of Scorched3D.
//
//    Scorched3D 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 2 of the License, or
//    (at your option) any later version.
//
//    Scorched3D 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, write to the Free Software Foundation, Inc.,
//    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
////////////////////////////////////////////////////////////////////////////////

#include <GLW/GLWWindowManager.hpp>
#include <GLW/GLWWindowSkinManager.hpp>
#include <GLW/GLWSelector.hpp>
#include <common/Keyboard.hpp>
#include <common/OptionsScorched.hpp>
#include <client/ClientParams.hpp>
#include <client/ClientState.hpp>
#include <client/ClientWindowSetup.hpp>
#include <client/ScorchedClient.hpp>
#include <dialogs/AnimatedBackdropDialog.hpp>
#include <dialogs/AutoDefenseDialog.hpp>
#include <dialogs/MainMenuDialog.hpp>
#include <dialogs/CameraDialog.hpp>
#include <dialogs/ProfileDialog.hpp>
#include <dialogs/PlayerInGameDialog.hpp>
#include <dialogs/QuitDialog.hpp>
#include <dialogs/LogDialog.hpp>
#include <dialogs/ConnectDialog.hpp>
#include <dialogs/AuthDialog.hpp>
#include <dialogs/BackdropDialog.hpp>
#include <dialogs/ProgressDialog.hpp>
#include <dialogs/GiftMoneyDialog.hpp>
#include <dialogs/BuyAccessoryDialog.hpp>
#include <dialogs/ScoreDialog.hpp>
#include <dialogs/SaveDialog.hpp>
#include <dialogs/KibitzingDialog.hpp>
#include <dialogs/InventoryDialog.hpp>
#include <dialogs/SkipDialog.hpp>
#include <dialogs/SkipAllDialog.hpp>
#include <dialogs/HUDDialog.hpp>
#include <dialogs/TipDialog.hpp>
#include <dialogs/SoundDialog.hpp>
#include <dialogs/HelpButtonDialog.hpp>
#include <dialogs/TutorialDialog.hpp>
#include <dialogs/MessageDialog.hpp>
#include <dialogs/StartDialog.hpp>
#include <dialogs/ModSelectDialog.hpp>
#include <dialogs/ModSubSelectDialog.hpp>
#include <dialogs/SaveSelectDialog.hpp>
#include <dialogs/NetworkSelectDialog.hpp>
#include <dialogs/NetworkChatDialog.hpp>
#include <dialogs/MsgBoxDialog.hpp>
#include <dialogs/SettingsSelectDialog.hpp>
#include <dialogs/SettingsSubSelectDialog.hpp>
#include <dialogs/AdminCheckDialog.hpp>
#include <dialogs/AdminAuthDialog.hpp>
#include <dialogs/AdminDialog.hpp>
#include <dialogs/PlayerInitialDialog.hpp>

void ClientWindowSetup::addStateWindows(GLWWindowSkinManager *skinManager,
	unsigned int state, const char *windowState)
{
	std::list<GLWWindowSkin *> allStateWindows = 
		skinManager->getStateWindows(windowState);
	std::list<GLWWindowSkin *>::iterator itor;
	for (itor = allStateWindows.begin();
		itor != allStateWindows.end();
		++itor)
	{
		GLWWindowSkin *window = *itor;
		KeyboardKey* key = nullptr;
		if (window->getKey()[0]) key = 
			Keyboard::instance()->getKey(window->getKey());
		GLWWindowManager::instance()->addWindow(state, 
			window, key, window->getVisible());
	}
}

void ClientWindowSetup::addCommonComponents(GLWWindowSkinManager *skinManager, 
	unsigned state)
{
	addStateWindows(skinManager, state, "all");

	KEYBOARDKEY("HUD_ITEMS", hudItemsKey);
	GLWWindowManager::instance()->addWindow(state, 
 		HUDDialog::instance(), hudItemsKey, false);

	KEYBOARDKEY("TIP_ITEMS", tipItemsKey);
	GLWWindowManager::instance()->addWindow(state, 
 		TipDialog::instance(), tipItemsKey, false);

	KEYBOARDKEY("SHOW_SOUND_DIALOG", showSoundKey);
	GLWWindowManager::instance()->addWindow(state, 
 		SoundDialog::instance(), showSoundKey, false);

	KEYBOARDKEY("SHOW_INVENTORY_DIALOG", showInvKey);
	GLWWindowManager::instance()->addWindow(state, 
 		InventoryDialog::instance(), showInvKey, false);

	KEYBOARDKEY("SHOW_KIBITZ_DIALOG", kibitzKey);
	GLWWindowManager::instance()->addWindow(state, 
		KibitzingDialog::instance(), kibitzKey, false);

	if (!ClientParams::instance()->getConnectedToServer())
	{
		KEYBOARDKEY("SHOW_KILL_DIALOG", killKey);
		GLWWindowManager::instance()->addWindow(state, 
 			QuitDialog::instance(), killKey, false);
		KEYBOARDKEY("SHOW_SAVE_DIALOG", saveKey);
		GLWWindowManager::instance()->addWindow(state, 
 			SaveDialog::instance(), saveKey, false);
	}

	KEYBOARDKEY("SHOW_CAMERA_DIALOG", cameraKey);
	GLWWindowManager::instance()->addWindow(state, 
		CameraDialog::instance(), cameraKey, false);

	if (state != ClientState::StateScore)
	{
		KEYBOARDKEY("SHOW_SCORE_DIALOG", scoreKey);
		GLWWindowManager::instance()->addWindow(state, 
			ScoreDialog::instance(), scoreKey, false);
	}
	GLWWindowManager::instance()->addWindow( state, MessageDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( state, MainMenuDialog::instance(), nullptr, true );

	addMessageComponents(skinManager, state);

	if (state != ClientState::StateBuyWeapons &&
		state != ClientState::StateAutoDefense)
	{
		KEYBOARDKEY("SHOW_TEAM_DIALOG", teamKey);
		GLWWindowManager::instance()->addWindow(state,
			PlayerInGameDialog::instance(), teamKey, false);
	}

	GLWWindowManager::instance()->addWindow( state, AdminCheckDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( state, AdminDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( state, AdminAuthDialog::instance(), nullptr, false );

	if (ScorchedClient::instance()->getOptionsGame().getTutorial()[0])
	{
		GLWWindowManager::instance()->addWindow( state, TutorialDialog::instance(), nullptr, true );
	}
}

void ClientWindowSetup::addMessageComponents(GLWWindowSkinManager *skinManager, unsigned state)
{
	KEYBOARDKEY("SHOW_QUIT_DIALOG", quitKey);
	GLWWindowManager::instance()->addWindow( state, QuitDialog::instance(), quitKey, false );

	GLWWindowManager::instance()->addWindow( state, GLWSelector::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( state, MsgBoxDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( state, TextBoxDialog::instance(), nullptr, false );
}

// This is called before any mod has been loaded
void ClientWindowSetup::setupStartWindows(GLWWindowSkinManager *skinManager)
{
	
	KEYBOARDKEY("SHOW_SOUND_DIALOG", showSoundKey);

	// StateOptions
	GLWWindowManager::instance()->removeState(ClientState::StateOptions);
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, AnimatedBackdropDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, SoundDialog::instance(), showSoundKey, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, StartDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, ModSelectDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, ModSubSelectDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, SaveSelectDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, NetworkSelectDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, NetworkChatDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, SettingsSelectDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow(
		ClientState::StateOptions,
		SettingsSubSelectDialog::instance(),
		nullptr,
		false
	);
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, MainMenuDialog::instance(), nullptr, true );
	addMessageComponents(skinManager, ClientState::StateOptions);

	// StateConnect
	GLWWindowManager::instance()->removeState(ClientState::StateConnect);
	GLWWindowManager::instance()->addWindow( ClientState::StateConnect, BackdropDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateConnect, SoundDialog::instance(), showSoundKey, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateConnect, ProgressDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateConnect, ConnectDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateConnect, AuthDialog::instance(), nullptr, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateConnect, MainMenuDialog::instance(), nullptr, true );
	addMessageComponents(skinManager, ClientState::StateConnect);

	// StateDisconnected
	GLWWindowManager::instance()->removeState(ClientState::StateDisconnected);
	GLWWindowManager::instance()->addWindow( ClientState::StateDisconnected, BackdropDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateDisconnected, SoundDialog::instance(), showSoundKey, false );
	GLWWindowManager::instance()->addWindow( ClientState::StateDisconnected, LogDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateDisconnected, MainMenuDialog::instance(), nullptr, true );
	addMessageComponents(skinManager, ClientState::StateDisconnected);

	// StateLoadFiles
	GLWWindowManager::instance()->removeState(ClientState::StateLoadFiles);
	GLWWindowManager::instance()->addWindow( ClientState::StateLoadFiles, BackdropDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateOptions, SoundDialog::instance(), showSoundKey, false );
	addStateWindows( skinManager, ClientState::StateLoadFiles, "start" );
	GLWWindowManager::instance()->addWindow( ClientState::StateLoadFiles, ProgressDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateLoadFiles, MainMenuDialog::instance(), nullptr, true );
	addMessageComponents(skinManager, ClientState::StateLoadFiles);
}

// This is called after the correct mod has been loaded
void ClientWindowSetup::setupGameWindows(GLWWindowSkinManager *skinManager)
{
	KEYBOARDKEY("SHOW_SKIP_DIALOG", skipKey);
	KEYBOARDKEY("SHOW_SOUND_DIALOG", showSoundKey);

	// StateWaitNoLandscape
	GLWWindowManager::instance()->removeState(ClientState::StateWaitNoLandscape);
	GLWWindowManager::instance()->addWindow( ClientState::StateWaitNoLandscape, BackdropDialog::instance(), nullptr, true );
	addStateWindows( skinManager, ClientState::StateWaitNoLandscape, "start" );
	GLWWindowManager::instance()->addWindow( ClientState::StateWaitNoLandscape, ScoreDialog::instance2(), nullptr, true );
	GLWWindowManager::instance()->addWindow(
		ClientState::StateWaitNoLandscape,
		PlayerInGameDialog::instance(),
		nullptr,
		false
	);
	GLWWindowManager::instance()->addWindow(
		ClientState::StateWaitNoLandscape,
		PlayerInitialDialog::instance(),
		nullptr,
		false
	);
	GLWWindowManager::instance()->addWindow(
		ClientState::StateWaitNoLandscape,
		SoundDialog::instance(),
		showSoundKey,
		false
	);
	GLWWindowManager::instance()->addWindow( ClientState::StateWaitNoLandscape, MainMenuDialog::instance(), nullptr, true );
	addMessageComponents(skinManager, ClientState::StateWaitNoLandscape);
	if (ScorchedClient::instance()->getOptionsGame().getTutorial()[0])
	{
		GLWWindowManager::instance()->addWindow( ClientState::StateWaitNoLandscape, TutorialDialog::instance(), nullptr, true );
	}

	// StateLoadLevel
	GLWWindowManager::instance()->removeState(ClientState::StateLoadLevel);
	GLWWindowManager::instance()->addWindow( ClientState::StateLoadLevel, BackdropDialog::instance(), nullptr, true );
	addStateWindows( skinManager, ClientState::StateLoadLevel, "start" );
	GLWWindowManager::instance()->addWindow( ClientState::StateLoadLevel, ProgressDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateLoadLevel, SoundDialog::instance(), showSoundKey, false );

	// StateWait
	GLWWindowManager::instance()->removeState(ClientState::StateWait);
	addCommonComponents(skinManager, ClientState::StateWait);

	// StateBuyWeapons
	GLWWindowManager::instance()->removeState(ClientState::StateBuyWeapons);
	addCommonComponents(skinManager, ClientState::StateBuyWeapons);
	GLWWindowManager::instance()->addWindow( ClientState::StateBuyWeapons, BuyAccessoryDialog::instance(), nullptr, true );
	GLWWindowManager::instance()->addWindow( ClientState::StateBuyWeapons, GiftMoneyDialog::instance(), nullptr, false );

	// StateAutoDefense
	GLWWindowManager::instance()->removeState(ClientState::StateAutoDefense);
	addCommonComponents(skinManager, ClientState::StateAutoDefense);
	GLWWindowManager::instance()->addWindow( ClientState::StateAutoDefense, AutoDefenseDialog::instance(), nullptr, false );

	// StatePlaying
	GLWWindowManager::instance()->removeState(ClientState::StatePlaying);
	addStateWindows(skinManager, ClientState::StatePlaying, "playing");
	KEYBOARDKEY("SHOW_PROFILE_DIALOG", profileKey);
	GLWWindowManager::instance()->addWindow( ClientState::StatePlaying, ProfileDialog::instance(), profileKey, false );
	GLWWindowManager::instance()->addWindow( ClientState::StatePlaying, SkipDialog::instance(), skipKey, false );
	GLWWindowManager::instance()->addWindow( ClientState::StatePlaying, SkipAllDialog::instance(), nullptr, false );
	addCommonComponents(skinManager, ClientState::StatePlaying);

	// StateScore
	GLWWindowManager::instance()->removeState(ClientState::StateScore);
	addCommonComponents(skinManager, ClientState::StateScore);
	GLWWindowManager::instance()->addWindow( ClientState::StateScore, ScoreDialog::instance2(), nullptr, true );
}
