/*
	Copyright (C) 2025-2026 Mark Tyler

	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 in the file COPYING.
*/

#include "ginbench_be.h"



void TestSuite::run_test_all ()
{
	for ( auto const & pair : m_test_map )
	{
		if ( pair.first != "all" )
		{
			print_next_test_name (
				pair.first.c_str(),
				pair.second.measure.c_str()
				);
			pair.second.func();
		}
	}
}

void TestSuite::run_test_clear ( PixmapVector & canvas )
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap * const pm = canvas[c].get();

		for ( int j=0; j < m_cline->get_test_total(); j++ )
		{
			pixy_pixmap_clear_canvas ( pm, 0 );
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_dup ( PixmapVector & canvas )
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap * const pm = canvas[c].get();

		for ( int j=0; j < m_cline->get_test_total(); j++ )
		{
			mtPixmap * pixmap = pixy_pixmap_duplicate ( pm );
			pixy_pixmap_destroy ( pixmap );
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_idx2rgb ( PixmapVector & canvas )
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap * const pm = canvas[c].get();

		for ( int j=0; j < m_cline->get_test_total(); j++ )
		{
			mtPixmap * pixmap = pixy_pixmap_convert_to_rgb( pm );
			pixy_pixmap_destroy ( pixmap );
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_lines ( PixmapVector & canvas )
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap	* const pm = canvas[c].get();
		mtPalette	* pal = pixy_pixmap_get_palette ( pm );
		mtColor	const	* cols = pal->color;
		int	const	w = pixy_pixmap_get_width ( pm );
		int	const	h = pixy_pixmap_get_height ( pm );

		m_brush.set_shape ( 0 );
		m_brush.set_pattern ( 0 );
		m_brush.set_color_ab ( 1, 0, cols );

		for ( int j=0; j < m_cline->get_test_total(); j++ )
		{
			int dx, dy, dw, dh;
			int const x1 = m_random.get_int ( w );
			int const y1 = m_random.get_int ( h );
			int const x2 = m_random.get_int ( w );
			int const y2 = m_random.get_int ( h );

			m_brush.paint_brush(pm, x1, y1, x2, y2, dx, dy, dw, dh);
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_rects ( PixmapVector & canvas )
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap	* const pm = canvas[c].get();
		mtPalette	* pal = pixy_pixmap_get_palette ( pm );
		mtColor	const	* cols = pal->color;
		int	const	w = pixy_pixmap_get_width ( pm );
		int	const	h = pixy_pixmap_get_height ( pm );

		m_brush.set_shape ( 0 );
		m_brush.set_pattern ( 0 );
		m_brush.set_color_ab ( 1, 0, cols );

		for ( int j=0; j < m_cline->get_test_total(); j++ )
		{
			int const xw = 1 + m_random.get_int ( 30 );
			int const yh = 1 + m_random.get_int ( 30 );
			int const x1 = m_random.get_int ( w - xw );
			int const y1 = m_random.get_int ( h - yh );
			m_brush.paint_rectangle ( pm, x1, y1, xw, yh );
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_paste (
	PixmapVector		& canvas,
	PixmapVector	const	& sprites
	)
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap * const pm = canvas[c].get();
		int	const	w = pixy_pixmap_get_width ( pm );
		int	const	h = pixy_pixmap_get_height ( pm );

		// Skip 1st + alpha channel sprites
		for ( size_t i=1; i < sprites.size(); i++ )
		{
			mtPixmap const * const s = sprites[i].get();

			if ( pixy_pixmap_get_alpha ( s ) )
			{
				continue;
			}

			int const sw = pixy_pixmap_get_width ( s );
			int const sh = pixy_pixmap_get_height ( s );

			for ( int j=0; j < m_cline->get_test_total(); j++ )
			{
				int const x = m_random.get_int(w + sw) - sw + 1;
				int const y = m_random.get_int(h + sh) - sh + 1;

				pixy_pixmap_paste ( pm, s, x, y );
			}
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_apaste (
	PixmapVector		& canvas,
	PixmapVector	const	& sprites
	)
{
	for ( size_t c=0; c < canvas.size(); c++ )
	{
		mtKit::Clock clock;

		mtPixmap * const pm = canvas[c].get();
		int	const	w = pixy_pixmap_get_width ( pm );
		int	const	h = pixy_pixmap_get_height ( pm );

		// Skip 1st + non-alpha channel sprites
		for ( size_t i=1; i < sprites.size(); i++ )
		{
			mtPixmap const * const s = sprites[i].get();

			if ( ! pixy_pixmap_get_alpha ( s ) )
			{
				continue;
			}

			int const sw = pixy_pixmap_get_width ( s );
			int const sh = pixy_pixmap_get_height ( s );

			for ( int j=0; j < m_cline->get_test_total(); j++ )
			{
				int const x = m_random.get_int(w + sw) - sw + 1;
				int const y = m_random.get_int(h + sh) - sh + 1;

				pixy_pixmap_paste_alpha_blend ( pm, s, x, y );
			}
		}

		print_per_sec ( clock.seconds() );
	}
}

void TestSuite::run_test_text ()
{
	char const * const str = "0123456789";
	mtPixy::Font	font ( "Sans Mono", 12 );

	mtKit::Clock clock;

	for ( int j=0; j < m_cline->get_test_total(); j++ )
	{
		mtPixy::Pixmap text ( font.render_pixmap( str, 0 ) );
	}

	print_per_sec ( clock.seconds() );
}

void TestSuite::run_test_sdl ( PixmapVector &canvas )
{
	for ( auto & c : canvas )
	{
		mtGin::App	gin ( SDL_INIT_VIDEO );
		mtGin::Window	window ( GIN_WINDOW_CANVAS_2D );
		int	const	fps = 30;
		int	const	frame_tot = fps * 3;	// 3 secs per pixmap
		int		frames = 0;
		double		secs_tot = 0;
		mtPixmap * const pm = c.get();

		gin.set_fps_max ( fps );

		// Detect the real screen size
		SDL_DisplayMode mode;
		SDL_GetDesktopDisplayMode ( 0, &mode );

		window.init ( BIN_NAME, 50, 50, mode.w, mode.h, 0 );
		gin.window_add ( window );

		SDL_SetWindowFullscreen ( window.sdl(),
			SDL_WINDOW_FULLSCREEN_DESKTOP );

		window.render_scale ( pm, 1, 0 );

		window.m_render.set ( [&window, &secs_tot, pm]()
		{
			mtKit::Clock	clock;

			SDL_SetRenderDrawColor( window.renderer(), 0, 0, 128,
				SDL_ALPHA_OPAQUE );
			window.render_pixmap ( pm );

			secs_tot += clock.seconds();
		} );

		gin.frame_callback.set ( [this, &frames, &gin]()
		{
			frames++;
			if ( frames > 0 )
			{
				if ( frames > frame_tot )
				{
					gin.stop_main_loop ();
				}
			}
		} );

		window.m_render.start ();
		gin.frame_callback.start ();

		gin.main_loop ();

		print_percent ( (double)frames / fps, secs_tot );
	}
}

