/*
	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 "pizor_be.h"



int pizor_pixmap_create_palette ( mtPixmap * pixmap )
{
	if ( ! pixmap )
	{
		return 1;
	}

	enum
	{
		PALETTE_PRESETS		= 15,
		MIX_TOT			= 21,
		MIX_MIDDLE		= 10,
		MIX_START		= 3
	};

	static mtColor const black = {0, 0, 0};
	static mtColor const white = {255, 255, 255};

	static mtColor const col[PALETTE_PRESETS] = {
		{ 180, 130, 140 },
		{ 150, 170, 150 },
		{ 150, 150, 180 },

		{ 200, 100, 100 },
		{ 190, 160, 140 },
		{ 100, 180, 100 },
		{ 130, 190, 180 },
		{ 120, 120, 210 },
		{ 180, 120, 180 },

		{ 255,  50,  50 },
		{ 230, 230, 100 },
		{  80, 220,  80 },
		{  80, 200, 220 },
		{  80,  80, 255 },
		{ 230,  80, 230 },

		};

	mtPalette mix;
	pixy_palette_init ( &mix );
	mtPalette * const pal = pixy_pixmap_get_palette ( pixmap );

	pixy_palette_set_size ( &mix, MIX_TOT );
	pixy_palette_set_size ( pal, 256 );

	pal->color[0] = black;
	pal->color[15] = white;
	pixy_palette_create_gradient ( pal, 0, 15 );

	mix.color[0] = black;
	mix.color[MIX_TOT-1] = white;

	for ( int i=0, d=16; i<PALETTE_PRESETS; i++ )
	{
		mix.color[MIX_MIDDLE] = col[i];

		pixy_palette_create_gradient ( &mix, 0, MIX_MIDDLE );
		pixy_palette_create_gradient ( &mix, MIX_MIDDLE, MIX_TOT-1 );

#if 1==1
		int const inc	= (i%2) == 0 ? -1 : 1;
		int const start	= (i%2) == 0 ? 15 : 0;
		int const end	= (i%2) == 0 ? -1 : 16;
#else
		int const inc	= 1;
		int const start	= 0;
		int const end	= 16;
#endif
		for ( int j=start; j!=end; j+=inc, d++ )
		{
			pal->color[d] = mix.color[j + MIX_START];
		}
	}

	return 0;
}



// Ode to 1994 and my Acorn A3000, and mtPaint in 2004.

#define PIXEL_WORK			\
	if ( *prnd & work->prnd_mask )	\
	{				\
		pix = (2*(		\
			src[ -1-work->w ] + src[ -work->w ] + src[ 1-work->w ]+\
			src[ -1 ] +	src[ 0 ] +	src[ 1 ] +	\
			src[ -1+work->w ] + src[ work->w ] + src[ 1+work->w ] \
			) + 27 ) / 18	\
			;		\
		*dest = (unsigned char)pix; \
	}				\
	dest++;				\
	src++;				\
	prnd++;				\


void do_pixmapwork ( PixmapWork const * const work )
{
	int const off = work->ystart * work->w;
	unsigned char * dest = work->dest + off;
	unsigned char const * src = work->src + off;
	unsigned char const * prnd = work->prnd + off;
	size_t const len = (size_t)work->w;
	int pix;

	int y=work->ystart;
	if ( y==0 )
	{
		memcpy ( dest, src, len );
		dest += work->w;
		src += work->w;
		prnd += work->w;

		y++;
	}
	if ( y==1 && y < work->ylim )
	{
		// Copy first pixel on second row
		*dest++ = *src++;
		prnd++;

		for ( int x=1; x < work->w; x++ )
		{
			PIXEL_WORK
		}

		y++;
	}

	int yl = work->ylim;
	int const h_2 = work->h - 2;
	if ( yl > h_2 )
	{
		yl = h_2;
	}

	for ( ; y < yl; y++ )
	{
		for ( int x=0; x < work->w; x++ )
		{
			PIXEL_WORK
		}
	}

	if ( y == (work->h - 2) && y < work->ylim )
	{
		for ( int x=0; x < (work->w - 1); x++ )
		{
			PIXEL_WORK
		}

		// Copy last pixel on penultimate row
		*dest++ = *src++;
		prnd++;

		y++;

		if ( y == (work->h - 1) && y < work->ylim )
		{
			memcpy ( dest, src, len );

/* Don't bother, not needed later
			dest += work->w;
			src += work->w;
			prnd += work->w;
			y++;
*/
		}
	}
}

