/*****************************************************************************

GRAOUMF TRACKER 2

Copyright (c) 1996 - 2002 Laurent de Soras

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 2
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Contact the author : laurent@ohmforce.com
More information about this license : http://www.gnu.org/licenses/gpl.html

*****************************************************************************/



/*\\\ FICHIERS INCLUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include	<stdio.h>
#include	<stdlib.h>

#include	"base.h"
#include	"base_ct.h"
#include	"ConfigFile.h"
#include	"ConfigKey.h"
#include	"ConfigKeyValue.h"
#include	"file.h"
#include	"intrface.h"
#include	"log.h"
#include	"resource.h"
#include	"Skin.h"



/*\\\ CONSTANTES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ CONSTANTES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ TYPES & STRUCTURES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ DEFINITION DES VARIABLES DE CLASSE PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ DEFINITION DES VARIABLES DE CLASSE PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ METHODES PUBLIQUES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*==========================================================================*/
/*      Nom: (constructeur)                                                 */
/*      Description: Initialise                                             */
/*      Parametres en entree:                                               */
/*      Parametres en sortie:                                               */
/*      Parametres en entree/sortie:                                        */
/*==========================================================================*/

Skin::Skin (const char *main_path_0)
{
	_main_path = main_path_0;
	init ();
}



/*==========================================================================*/
/*      Nom: (destructeur)                                                  */
/*      Description: Detruit                                                */
/*==========================================================================*/

Skin::~Skin (void)
{
	clear_all ();
}



/*==========================================================================*/
/*      Nom: check_ok                                                       */
/*      Description: Verifie l'intergrite de l'objet.                       */
/*      Retour: 0 si l'objet parait correct.                                */
/*==========================================================================*/

signed int	Skin::check_ok (void) const
{
	if (this == NULL)
	{
		LOG_printf ("Skin::check_ok: Error: \"this\" pointer is NULL.\n");
		return (-1);
	}

	/*** A faire ***/

	return (0);
}



/*==========================================================================*/
/*      Nom: self_display                                                   */
/*      Description: Affiche "textuellement" le contenu courant de l'objet. */
/*==========================================================================*/

void	Skin::self_display (void) const
{

	/*** A faire ***/

}



signed long	Skin::add_pic (const char *filename_0, bool custom_flag)
{
	long		pic;
	String	pathname;

	pic = reserve_first_free_pic ();
	if (custom_flag)
	{
		pathname = _skin_path;
	}
	else
	{
		pathname = _main_path;
	}
	pathname += filename_0;

	_pic_array [pic].pic_ptr = RSC_pcxload (pathname.c_str (), NULL);
	if (_pic_array [pic].pic_ptr == NULL)
	{
		LOG_printf ("Skin::add_pic: Error: couldn't load picture.\n");
		return (-1);
	}
	if (! custom_flag)
	{
		_pic_array [pic].normal_name_ptr = new String (filename_0);
	}
	_pic_array [pic].current_name_ptr = new String (filename_0);

	return (pic);
}



signed long	Skin::merge_pic (const char *filename_0, bool custom_flag)
{
	signed long		pic;

	pic = get_named_pic (filename_0);
	if (pic < 0)
	{
		pic = add_pic (filename_0, custom_flag);
	}

	return (pic);
}



signed long	Skin::replace_pic (const char *filename_0, bool custom_flag, long pic)
{
	String		filename;
	String		pathname;

	if (custom_flag)
	{
		pathname = _skin_path;
	}
	else
	{
		pathname = _main_path;
	}

	if (strcmp (filename_0, "") == 0)
	{
		if (custom_flag)
		{
			filename = *_pic_array [pic].current_name_ptr;
		}
		else
		{
			if (_pic_array [pic].normal_name_ptr != NULL)
			{
				filename = *_pic_array [pic].normal_name_ptr;
			}
			else
			{
				clear_pic (pic);
				return (0);
			}
		}
	}
	else
	{
		filename = filename_0;
	}

	pathname += filename;

	if (FILE_file_exist (pathname.c_str ()))
	{
		if (_pic_array [pic].pic_ptr != NULL)
		{
			delete _pic_array [pic].pic_ptr;
			_pic_array [pic].pic_ptr = NULL;
		}
		if (_pic_array [pic].current_name_ptr != NULL)
		{
			delete _pic_array [pic].current_name_ptr;
			_pic_array [pic].current_name_ptr = NULL;
		}

		_pic_array [pic].pic_ptr = RSC_pcxload (pathname.c_str (), NULL);
		if (_pic_array [pic].pic_ptr == NULL)
		{
			LOG_printf ("Skin::replace_pic: Error: couldn't load picture.\n");
			return (-1);
		}
		_pic_array [pic].current_name_ptr = new String (filename);

		if (! custom_flag)
		{
			if (_pic_array [pic].normal_name_ptr != NULL)
			{
				delete _pic_array [pic].normal_name_ptr;
				_pic_array [pic].normal_name_ptr = NULL;
			}
			_pic_array [pic].normal_name_ptr = new String (filename);
		}
	}

	return (0);
}



/* Passer -1 pour signaler une image absente */
/* Ajoute toujours dans les 2 modes */
signed long	Skin::add_elt (int pic [3])
{
	long		elt;
	int		pic_cnt;

	elt = _nbr_elt;
	for (pic_cnt = 0; pic_cnt < 3; pic_cnt ++)
	{
		_elt_array [elt].pic [0] [pic_cnt] = pic [pic_cnt];
		_elt_array [elt].pic [1] [pic_cnt] = pic [pic_cnt];
	}
	_nbr_elt ++;

	return (elt);
}



signed int	Skin::replace_elt (long elt, int pic [3])
{
	int		pic_cnt;

	for (pic_cnt = 0; pic_cnt < 3; pic_cnt ++)
	{
		_elt_array [elt].pic [0] [pic_cnt] = pic [pic_cnt];
	}
	_nbr_elt ++;

	return (0);
}



signed int	Skin::load_palette (const char *palettefile_0, LWORD palette_array [256])
{
	Image		*dummy_ptr;

	dummy_ptr = RSC_pcxload (palettefile_0, palette_array);
	if (dummy_ptr == NULL)
	{
		LOG_printf ("Skin::load_palette: Error: couldn't load picture.\n");
		return (-1);
	}
	delete dummy_ptr;

	return (0);
}



signed int	Skin::load_custom_skin (const char *skin_path_0)
{
	signed long	ret_code;
	int		pic;
	int		color;

	_skin_path = skin_path_0;

	/* Sauve la palette */
	INTR_graph_ptr->get_palette (_palette);
	for (color = 0; color < 256; color ++)
	{
		_old_palette [color] = _palette [color];
	}

	/* Charge les images de substitution */
	for (pic = 0; pic < _nbr_pic; pic ++)
	{
		if (! is_empty_pic (pic))
		{
			if (replace_pic ("", true, pic))
			{
				LOG_printf ("Skin::load_custom_skin: Error: couldn't replace picture.\n");
				return (-1);
			}
		}
	}

	/* Lit les images additionnelles */
	ConfigFile config_file ((_skin_path + "skin.inf").c_str ());
	std::list <ConfigKey>	key_list;
	if (config_file.read (key_list) != ConfigFile_OK)
	{
		LOG_printf ("Skin::load_custom_skin: Error: couldn't load skin definitions.\n");
		return (-1);
	}

	ret_code = decode_key_list (key_list);

	_custom_flag = true;

	return (ret_code);
}



signed int	Skin::restore_standard_skin (void)
{
	int		elt;
	int		color_type;
	int		pic;
	int		color;

	/* Efface les elements additionnels */
	for (elt = 0; elt < Skin_NBR_SPEC_ELT; elt ++)
	{
		for (color_type = 0; color_type < 2; color_type ++)
		{
			_special_elt [elt] [color_type] = Skin_SpecialElt ();
		}
	}

	/* Efface la color map */
	for (color = 0; color < 256; color ++)
	{
		_basic_color_map [color] = color;
	}

	/* Efface la palette */
	for (color = 0; color < 256; color ++)
	{
		_palette [color] = _old_palette [color];
	}

	/* Applique la palette */
	if (_custom_flag)
	{
		INTR_graph_ptr->set_palette (_palette);
	}

	/* Recharge les images par defaut */
	for (pic = 0; pic < _nbr_pic; pic ++)
	{
		if (! is_empty_pic (pic))
		{
			if (replace_pic ("", false, pic))
			{
				LOG_printf ("Skin::restore_standard_skin: Error: couldn't replace picture.\n");
				return (-1);
			}
		}
	}

	_custom_flag = false;
	_skin_name = "";
	_skin_copyright = "";

	return (0);
}



void	Skin::set_tile (long pic, int type, Skin_RECTANGLE &rect)
{
	_pic_array [pic].tile.rect [type] = rect;
}



/* Retourne -1 si aucune image ne correspond
	ex: sel+dis mais pas d'image pour sel et normal */
signed long	Skin::get_pic_nbr (long elt, bool &selected_flag, bool &disable_flag)
{
	if (selected_flag)
	{
		if (_elt_array [elt].pic [0] [1] >= 0)
		{
			selected_flag = false;
			return (_elt_array [elt].pic [0] [1]);
		}
	}

	else if (disable_flag)
	{
		if (_elt_array [elt].pic [0] [2] >= 0)
		{
			disable_flag = false;
			return (_elt_array [elt].pic [0] [2]);
		}
	}

	return (_elt_array [elt].pic [0] [0]);
}



Image	*Skin::get_pic_ptr (long pic)
{
	return (_pic_array [pic].pic_ptr);
}



Skin_SpecialElt	*Skin::get_special_elt (Skin_SpecEltType spec_type, int color_type)
{
	return (&_special_elt [spec_type] [color_type]);
}



const Skin_TileData	*Skin::get_tile_info (long pic)
{
	return (&_pic_array [pic].tile);
}



int	Skin::map_color (int color)
{
	return (_basic_color_map [color]);
}



const char	*Skin::get_skin_name (void)
{
	return (_skin_name.c_str ());
}



const char	*Skin::get_skin_copyright (void)
{
	return (_skin_copyright.c_str ());
}



bool	Skin::get_custom_flag (void)
{
	return (_custom_flag);
}



/*\\\ METHODES PRIVEES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



signed int	Skin::init (void)
{
	int		color;
	int		i, j;

	_custom_flag = false;
	_skin_name = "";
	_skin_copyright = "";
	for (i = 0; i < Skin_NBR_SPEC_ELT; i ++)
	{
		for (j = 0; j < 2; j ++)
		{
			_special_elt [i] [0] = Skin_SpecialElt ();
		}
	}
	_nbr_elt = 0;
	_nbr_pic = 0;
	_skin_path = _main_path;
	memset (_palette, 0, 256 * sizeof (*_palette));
	for (color = 0; color < 256; color ++)
	{
		_basic_color_map [color] = color;
	}

	return (0);
}



void	Skin::clear_all (void)
{
	long		pic;

	for (pic = 0; pic < _nbr_pic; pic ++)
	{
		clear_pic (pic);
	}
	_nbr_pic = 0;
	_nbr_elt = 0;
}



void	Skin::clear_pic (long pic)
{
	if (_pic_array [pic].pic_ptr != NULL)
	{
		delete _pic_array [pic].pic_ptr;
		_pic_array [pic].pic_ptr = NULL;
	}
	if (_pic_array [pic].normal_name_ptr != NULL)
	{
		delete _pic_array [pic].normal_name_ptr;
		_pic_array [pic].normal_name_ptr = NULL;
	}
	if (_pic_array [pic].current_name_ptr != NULL)
	{
		delete _pic_array [pic].current_name_ptr;
		_pic_array [pic].current_name_ptr = NULL;
	}
}



long	Skin::reserve_first_free_pic (void)
{
	long		pic;

	for (pic = 0; pic < _nbr_pic; pic ++)
	{
		if (is_empty_pic (pic))
		{
			break;
		}
	}

	if (pic >= _nbr_pic)
	{
		_nbr_pic = pic + 1;
		_pic_array [pic].pic_ptr = NULL;
		_pic_array [pic].normal_name_ptr = NULL;
		_pic_array [pic].current_name_ptr = NULL;
	}

	return (pic);
}



/* Retourne -1 si l'image n'est pas trouvee */
signed long	Skin::get_named_pic (const char *filename_0)
{
	signed long	pic;
	String	filename (filename_0);

	for (pic = 0; pic < _nbr_pic; pic ++)
	{
		if (_pic_array [pic].current_name_ptr != NULL)
		{
			if (*_pic_array [pic].current_name_ptr == filename)
			{
				return (pic);
			}
		}
	}

	return (-1);
}



bool	Skin::is_empty_pic (long pic)
{
	return (   _pic_array [pic].pic_ptr == NULL
	        && _pic_array [pic].normal_name_ptr == NULL
	        && _pic_array [pic].current_name_ptr == NULL);
}



signed long	Skin::decode_key_list (const std::list <ConfigKey> &key_list)
{
	signed long	ret_val;

	for (std::list <ConfigKey>::const_iterator it = key_list.begin ()
	;	it != key_list.end ()
	;	++ it)
	{
		/* Recupere la cle */
		const ConfigKey &	key = *it;

		/* Recupere son nom */
		const String	key_name = key.get_name ();
		const ConfigKeyValue &	key_val = key.get_value ();

		/* Cle anonyme: interdit */
		if (BASE_compare_string (key_name.c_str (), "") == 0)
		{
			return (-1);
		}

		ret_val = 0;

		/* Listes */
		if (key_val.get_type () == ConfigKeyValue_Type_LIST)
		{
			/* Palette */
			if (BASE_compare_string (key_name.c_str (), "color_change") == 0)
			{
				ret_val = decode_key_color_change (key_val.get_list ());
			}

			/* Map des couleurs de 16 a 31 */
			else if (BASE_compare_string (key_name.c_str (), "color_map") == 0)
			{
				ret_val = decode_key_color_map (key_val.get_list ());
			}

			/* Blocs de la couleur principale */
			else if (BASE_compare_string (key_name.c_str (), "default_primary") == 0)
			{
				ret_val = decode_key_default_primsec (key_val.get_list (), 0);
			}

			/* Blocs de la couleur secondaire */
			else if (BASE_compare_string (key_name.c_str (), "default_secondary") == 0)
			{
				ret_val = decode_key_default_primsec (key_val.get_list (), 1);
			}

			/* Cle inconnue */
			else
			{
				LOG_printf ("Skin::decode_key_list: Warning: unknown key \"%s\".\n",
				            key_name.c_str ());
//				return (-1);
			}
		}

		/* Cles valeur chaine */
		else
		{
			if (BASE_compare_string (key_name.c_str (), "skin_name") == 0)
			{
				_skin_name = key_val.get_string ();
			}

			else if (BASE_compare_string (key_name.c_str (), "skin_copyright") == 0)
			{
				_skin_copyright = key_val.get_string ();
			}

			/* Cle inconnue */
			else
			{
				LOG_printf (
					"Skin::decode_key_list: Warning: unknown key \"%s\".\n",
					key_name.c_str ()
				);
//				return (-1);
			}
		}

		if (ret_val)
		{
			return (-1);
		}
	}

	return (0);
}



signed long	Skin::decode_key_color_change (const std::list <ConfigKey> &key_list)
{
	int		start;
	int		end;
	int		cnt;
	LWORD		palette_array [256];

	/* Verifie qu'on a le bon nombre d'elements */
	int				length = int (key_list.size ());
	if (length < 1 || length > 3)
	{
		return (-1);
	}

	std::list <ConfigKey>::const_iterator	it = key_list.begin ();

	/* Param obligatoire: nom du fichier contenant la palette */
	if (load_palette (
		(_skin_path + it->get_string ()).c_str (),
		palette_array
	))
	{
		return (-1);
	}

	start = 128;
	end = 254;

	/* Parametre optionels: debut et fin des index a changer. */
	if (length > 1)
	{
		++ it;
		start = atoi ((it->get_string ()).c_str ());
		if (length > 2)
		{
			++ it;
			end = atoi ((it->get_string ()).c_str ());
		}
	}

	/* Change les couleurs demandees */
	for (cnt = start; cnt <= end; cnt ++)
	{
		_palette [cnt] = palette_array [cnt];
	}

	/* Applique la palette */
	INTR_graph_ptr->set_palette (_palette);

	return (0);
}



signed long	Skin::decode_key_color_map (const std::list <ConfigKey> &key_list)
{
	int		index;
	int		cnt;

	/* Verifie qu'on a le bon nombre d'elements */
	int				length = int (key_list.size ());
	if (length < 1)
	{
		return (-1);
	}

	std::list <ConfigKey>::const_iterator	it = key_list.begin ();

	/* Decode chaque couleur */
	for (cnt = 0; cnt < length; cnt ++)
	{
		index = atoi ((it->get_string ()).c_str ());
		if (cnt >= 1 && cnt <= 15)
		{
			_basic_color_map [cnt] = index;
		}
		_basic_color_map [cnt + 16] = index;
		++ it;
	}

	return (0);
}



signed long	Skin::decode_key_default_primsec (const std::list <ConfigKey> &key_list, int type)
{
	signed long	ret_val;
	int		key_cnt;
	struct
	{
		const char	*name_0;
		Skin_SpecEltType	type;
		bool		flag;
	}			key_array [Skin_NBR_SPEC_ELT+1] =
	{
		{ "frame", Skin_SPEC_ELT_FRAME, false },
		{ "button", Skin_SPEC_ELT_BUTTON, false },
		{ "text_field", Skin_SPEC_ELT_TEXT_FIELD, false },
		{ NULL, Skin_NBR_SPEC_ELT, false },
	};

	for (std::list <ConfigKey>::const_iterator it = key_list.begin ()
	;	it != key_list.end ()
	;	++ it)
	{
		/* Recupere la cle */
		const ConfigKey &	key = *it;

		/* Recupere son nom */
		const String	key_name = key.get_name ();
		const ConfigKeyValue &	key_val = key.get_value ();

		ret_val = 0;

		/* Listes */
		if (key_val.get_type () == ConfigKeyValue_Type_LIST)
		{
			for (key_cnt = 0; ; key_cnt ++)
			{
				if (key_array [key_cnt].name_0 == NULL)
				{
					LOG_printf ("Skin::decode_key_default_primsec: Warning: unknown key \"%s\".\n",
					            key_name.c_str ());
//					ret_val = -1;
					break;
				}
				if (BASE_compare_string (key_name.c_str (), key_array [key_cnt].name_0) == 0)
				{
					if (key_array [key_cnt].flag)
					{
						return (-1);
					}
					ret_val = decode_key_dps_element (key_val.get_list (), type, key_array [key_cnt]. type);
					key_array [key_cnt].flag = true;
					break;
				}
			}
		}

		/* Cles valeur chaine: y en a pas */
		else
		{
			LOG_printf ("Skin::decode_key_default_primsec: Warning: unknown key \"%s\".\n",
			            key_name.c_str ());
//			return (-1);
		}

		if (ret_val)
		{
			return (-1);
		}
	}

	return (0);
}



signed long	Skin::decode_key_dps_element (const std::list <ConfigKey> &key_list, int color_type, Skin_SpecEltType elt_type)
{
	signed long	ret_val;
	Skin_BlockData	block_data [3];
	int		pic [3];
	int		pic_cnt;

	/* Recupere les donnees du bloc */
	ret_val = decode_key_dps_block (key_list, block_data);
	if (ret_val)
	{
		return (-1);
	}

	/* Analyse et stoque les donnees */
	for (pic_cnt = 0; pic_cnt < 3; pic_cnt ++)
	{
		pic [pic_cnt] = -1;	// Aucune par defaut
		if (BASE_compare_string (block_data [pic_cnt].filename.c_str (), "") != 0)
		{
			pic [pic_cnt] = merge_pic (block_data [pic_cnt].filename.c_str (), true);
			if (pic [pic_cnt] < 0)
			{
				return (-1);
			}
			_pic_array [pic [pic_cnt]].tile = block_data [pic_cnt].tile;
		}
	}
	_special_elt [elt_type] [color_type].elt = add_elt (pic);

	return (0);
}



signed long	Skin::decode_key_dps_block (const std::list <ConfigKey> &key_list, Skin_BlockData block_data [3])
{
	signed long	ret_val;
	int		state;
	const char	*const state_name_0 [3] =
	{
		"normal", "selected", "disable"
	};

	for (std::list <ConfigKey>::const_iterator it = key_list.begin ()
	;	it != key_list.end ()
	;	++ it)
	{
		/* Recupere la cle */
		const ConfigKey &	key = *it;

		/* Recupere son nom */
		const String	key_name = key.get_name ();
		const ConfigKeyValue &	key_val = key.get_value ();

		ret_val = 0;

		/* Listes */
		if (key_val.get_type () == ConfigKeyValue_Type_LIST)
		{
			for (state = 0; state < 3; state ++)
			{
				if (BASE_compare_string (key_name.c_str (), state_name_0 [state]) == 0)
				{
					if (BASE_compare_string (block_data [state].filename.c_str (), "") != 0)
					{
						return (-1);
					}

					ret_val = decode_key_dps_block_state (key_val.get_list (), block_data [state]);

					/*** A faire ***/

					break;
				}
			}
			if (state >= 3)
			{
				LOG_printf ("Skin::decode_key_dps_block: Warning: unknown key \"%s\".\n",
				            key_name.c_str ());
//				return (-1);
			}
		}

		/* Cles valeur chaine: y en a pas */
		else
		{
			LOG_printf ("Skin::decode_key_dps_block: Warning: unknown key \"%s\".\n",
			            key_name.c_str ());
//			return (-1);
		}

		if (ret_val)
		{
			return (-1);
		}
	}

	return (0);
}



signed long	Skin::decode_key_dps_block_state (const std::list <ConfigKey> &key_list, Skin_BlockData &block_data)
{
	signed long	ret_val;
	int		key_cnt;
	struct
	{
		const char	*name_0;
		signed long	(Skin::*routine_ptr) (const ConfigKeyValue &key_val, Skin_BlockData &block_data, int nbr);
		int		nbr;
		bool		flag;
	}			key_array [] =
	{
		{ "pic",    &Skin::decode_key_dps_block_state_pic,  0,                false },
		{ "tile",   &Skin::decode_key_dps_block_state_tile, Skin_RECT_TILE,   false },
		{ "center", &Skin::decode_key_dps_block_state_tile, Skin_RECT_CENTER, false },
		{ NULL, NULL, 0, false },
	};

	for (std::list <ConfigKey>::const_iterator it = key_list.begin ()
	;	it != key_list.end ()
	;	++ it)
	{
		/* Recupere la cle */
		const ConfigKey &	key = *it;

		/* Recupere son nom */
		const String	key_name = key.get_name ();
		const ConfigKeyValue &	key_val = key.get_value ();

		ret_val = 0;

		for (key_cnt = 0; ; key_cnt ++)
		{
			if (key_array [key_cnt].name_0 == NULL)
			{
				LOG_printf ("Skin::decode_key_dps_block_state: Warning: unknown key \"%s\".\n",
				            key_name.c_str ());
//				ret_val = -1;
				break;
			}
			if (BASE_compare_string (key_name.c_str (), key_array [key_cnt].name_0) == 0)
			{
				if (key_array [key_cnt].flag)
				{
					return (-1);
				}
				ret_val = (this->*(key_array [key_cnt].routine_ptr)) (key_val, block_data, key_array [key_cnt].nbr);
				key_array [key_cnt].flag = true;
				break;
			}
		}

		if (ret_val)
		{
			return (-1);
		}
	}

	/* Verifie qu'on a au moins les parametres strictement necessaires */
	if (! key_array [0].flag)		// pic
	{
		return (-1);
	}
	if (! key_array [1].flag)		// tile
	{
		return (-1);
	}

	return (0);
}



signed long	Skin::decode_key_dps_block_state_pic (const ConfigKeyValue &key_val, Skin_BlockData &block_data, int nbr)
{
	block_data.filename = key_val.get_string ();

	return (0);
}



signed long	Skin::decode_key_dps_block_state_tile (const ConfigKeyValue &key_val, Skin_BlockData &block_data, int nbr)
{
	if (key_val.get_type () != ConfigKeyValue_Type_LIST)
	{
		return (-1);
	}
	const std::list <ConfigKey> &	key_list = key_val.get_list ();
	if (key_list.size () != 4)
	{
		return (-1);
	}

	std::list <ConfigKey>::const_iterator	it = key_list.begin ();
	block_data.tile.rect [nbr].x = atoi ((it->get_string ()).c_str ());
	++ it;
	block_data.tile.rect [nbr].y = atoi ((it->get_string ()).c_str ());
	++ it;
	block_data.tile.rect [nbr].l = atoi ((it->get_string ()).c_str ());
	++ it;
	block_data.tile.rect [nbr].h = atoi ((it->get_string ()).c_str ());
	++ it;
	block_data.tile.rect [nbr].x = MAX (block_data.tile.rect [nbr].x, 1);
	block_data.tile.rect [nbr].y = MAX (block_data.tile.rect [nbr].y, 1);
	block_data.tile.rect [nbr].l = MAX (block_data.tile.rect [nbr].l, 1);
	block_data.tile.rect [nbr].h = MAX (block_data.tile.rect [nbr].h, 1);
	block_data.center_flag = (block_data.center_flag || (nbr == Skin_RECT_CENTER));

	return (0);
}



/****************************************************************************/
/*                                                                          */
/*                                                                          */
/*                                                                          */
/****************************************************************************/



/*==========================================================================*/
/*      Nom:                                                                */
/*      Description:                                                        */
/*      Parametres en entree:                                               */
/*      Parametres en sortie:                                               */
/*      Parametres en entree/sortie:                                        */
/*      Retour:                                                             */
/*==========================================================================*/
