////////////////////////////////////////////////////////////////////////////////
//    Scorched3D (c) 2000-2011, 2025, 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 <stdio.h>
#include <graph/FrameTimer.hpp>
#include <graph/OptionsDisplay.hpp>
#include <graph/MainCamera.hpp>
#include <graph/ParticleEngine.hpp>
#include <dialogs/MainMenuDialog.hpp>
#include <dialogs/HelpButtonDialog.hpp>
#include <dialogs/SoundDialog.hpp>
#include <common/Defines.hpp>
#include <sound/Sound.hpp>
#include <GLEXT/GLInfo.hpp>
#include <GLEXT/GLState.hpp>
#include <GLEXT/GLMenu.hpp>
#include <client/ScorchedClient.hpp>
#include <client/ClientChannelManager.hpp>
#include <client/ClientSimulator.hpp>
#include <tankgraph/RenderTargets.hpp>
#include <engine/ActionController.hpp>
#include <image/ImageFactory.hpp>
#include <landscape/Landscape.hpp>
#include <landscape/ShadowMap.hpp>
#include <land/VisibilityPatchGrid.hpp>
#include <GLW/GLWWindowManager.hpp>

HelpButtonDialog *HelpButtonDialog::instance_ = nullptr;

HelpButtonDialog *HelpButtonDialog::instance()
{
	if (nullptr == instance_)
	{
		instance_ = new HelpButtonDialog();
	}
	return instance_;
}

HelpButtonDialog::HelpButtonDialog() :
	helpMenu_(),
	volumeMenu_(),
	performanceMenu_()
{}

HelpButtonDialog::~HelpButtonDialog()
{}

HelpButtonDialog::HelpMenu::HelpMenu()
{
	Image *map = new Image(
		ImageFactory::loadImage(
			S3D::eDataLocation,
			"data/images/help.bmp",
			"data/images/helpa.bmp",
			false
		)
	);
	DIALOG_ASSERT(map->getBits());
	MainMenuDialog::instance()->addMenu(
		LANG_RESOURCE("HELP", "Help"),
		"Help",
		LANG_RESOURCE(
			"HELP_MENU", "Launch an external web browser containing the\n"
			"Scorched3D online help."
		),
		32.0f,
		0,
		this,
		map,
		GLMenu::eMenuAlignRight
	);
}

bool HelpButtonDialog::HelpMenu::getMenuItems(const char* menuName, std::list<GLMenuItem> &result)
{
	result.push_back(GLMenuItem(LANG_RESOURCE("SHOW_ONLINE_HELP", "Show Online Help")));
	return true;
}

void HelpButtonDialog::HelpMenu::menuSelection(const char* menuName, const int position, GLMenuItem &item)
{
	// FIXME: literal legacy URI
	S3D::showURL("http://www.scorched3d.co.uk/wiki");
}

HelpButtonDialog::VolumeMenu::VolumeMenu()
{
	Image *map = new Image(
		ImageFactory::loadImage(
			S3D::eDataLocation,
			"data/images/sound.bmp",
			"data/images/sounda.bmp",
			false
		)
	);
	DIALOG_ASSERT(map->getBits());
	MainMenuDialog::instance()->addMenu(
		LANG_RESOURCE("VOLUME", "Volume"),
		"Volume",
		LANG_RESOURCE("VOLUME_MENU", "Change the sound and volume settings"),
		32.0f,
		0,
		this,
		map,
		GLMenu::eMenuAlignRight
	);
}

bool HelpButtonDialog::VolumeMenu::menuOpened(const char* menuName)
{
	GLWWindowManager::instance()->showWindow( SoundDialog::instance()->getId() );
	return false;
}

HelpButtonDialog::PerformanceMenu::PerformanceMenu()
{
	Image *map = new Image(
		ImageFactory::loadImage(
			S3D::eDataLocation,
			"data/images/perf.bmp",
			"data/images/perfa.bmp",
			false
		)
	);
	DIALOG_ASSERT(map->getBits());
	MainMenuDialog::instance()->addMenu(
		LANG_RESOURCE("PERFORMANCE", "Performance"),
		"Performance",
		LANG_STRING(""),
		32.0f,
		0,
		this,
		map,
		GLMenu::eMenuAlignRight
	);
}

bool HelpButtonDialog::PerformanceMenu::getMenuItems(const char* menuName, std::list<GLMenuItem> &result)
{
	return true;
}

void HelpButtonDialog::PerformanceMenu::menuSelection(
	const char* menuName,
	const int position,
	GLMenuItem &item
)
{}

LangStringStorage *HelpButtonDialog::PerformanceMenu::getMenuToolTip(const char* menuName)
{
	static LangString result;

	unsigned int pOnScreen =
		ScorchedClient::instance()->
			getParticleEngine().getParticlesOnScreen() +
		MainCamera::instance()->getTarget().
			getPrecipitationEngine().getParticlesOnScreen();

	result = LANG_STRING(
		S3D::formatStringBuffer(
		"%.2f Frames Per Second\n"
		"  %i Triangles Drawn\n"
		"  %i Particles Drawn\n"
		"  %i %i %i %i Land, Water, Roof, Total Patches\n"
		"  %i Trees Drawn\n"
		"  %i Targets Drawn\n"
		"  %i Playing Sound Channels\n"
		"  %u Shadows Drawn\n"
		"  %u OpenGL State Changes\n"
		"  %u OpenGL Texture Changes\n"
		"%.2f Server Ahead By\n"
		"  %.2f Server Round Trip Time\n"
		"  %.2f Server Simulation Step\n"
		"  %.2f%% Server Choke\n",

		(double)(FrameTimer::instance()->getFPS()),
		FrameTimer::instance()->getLastTris(),
		pOnScreen,
		VisibilityPatchGrid::instance()->getVisibleLandPatchesCount(),
		VisibilityPatchGrid::instance()->getVisibleWaterPatchesCount(),
		VisibilityPatchGrid::instance()->getVisibleRoofPatchesCount(),
		VisibilityPatchGrid::instance()->getPatchesVisitedCount(),
		RenderTargets::instance()->getTreesDrawn(),
		RenderTargets::instance()->getTargetsDrawn(),
		Sound::instance()->getPlayingChannels(),
		Landscape::instance()->getShadowMap().getShadowCount(),
		FrameTimer::instance()->getLastStateCount(),
		FrameTimer::instance()->getLastTextureSets(),
		ScorchedClient::instance()->getClientSimulator().getServerTimeDifference().asDouble(),
		ScorchedClient::instance()->getClientSimulator().getServerRoundTripTime().asDouble(),
		ScorchedClient::instance()->getClientSimulator().getServerStepTime().asDouble(),
		ScorchedClient::instance()->getClientSimulator().getServerChoke().asDouble()
		)
	);

	return (LangStringStorage *) result.c_str();
}
