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

        GRAOUMF TRACKER 2
        Author: Laurent de Soras, 1996-2016

--- Legal stuff ---

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

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



#if defined (_MSC_VER)
#define	STRDUP(x)	_strdup (x)
#else
#define	STRDUP(x)	strdup (x)
#endif

#define	RED_RESOURCE_EDITOR

#include	"pc.h"
#include	"rsc_edit.h"

#include	"..\resource.h"

#include <algorithm>

#include	<cstddef>
#include <cstdint>
#include	<cstdlib>
#include	<cstring>
#include	<cstdio>
#include	<cctype>
#include	<cmath>



int	RED_init (void);
void	RED_exit (void);
void	RED_memory_clear (void);
void	RED_main_menu (void);
void	RED_clear_keyboard_buffer (void);
bool	RED_alert (char *message_0, int true_key, int false_key);
void	RED_upper_string (char *text_0);
signed int	RED_menu_edit_tree (void);
int	RED_m_e_t_edit_object_redraw (int ret_pos);
void	RED_m_e_t_edit_object (int ret_pos);
bool	RED_m_e_t_e_o_get_coord (int *pix_coord_ptr, int disp_line, int char_dim);
void	RED_m_e_t_e_o_header (int param_nbr, int object_nbr);
void	RED_m_e_t_e_o_point (int param_nbr, RSC_OBJTYPE_POINT *object_ptr);
void	RED_m_e_t_e_o_hline (int param_nbr, RSC_OBJTYPE_HLINE *object_ptr);
void	RED_m_e_t_e_o_vline (int param_nbr, RSC_OBJTYPE_VLINE *object_ptr);
void	RED_m_e_t_e_o_box (int param_nbr, RSC_OBJTYPE_BOX *object_ptr);
void	RED_m_e_t_e_o_xorbox (int param_nbr, RSC_OBJTYPE_XORBOX *object_ptr);
void	RED_m_e_t_e_o_bitmap (int param_nbr, RSC_OBJTYPE_BITMAP *object_ptr);
void	RED_m_e_t_e_o_tbitmap (int param_nbr, RSC_OBJTYPE_TBITMAP *object_ptr);
void	RED_m_e_t_e_o_text (int param_nbr, RSC_OBJTYPE_TEXT *object_ptr);
void	RED_m_e_t_e_o_ttext (int param_nbr, RSC_OBJTYPE_TTEXT *object_ptr);
void	RED_m_e_t_e_o_intbox (int param_nbr, RSC_OBJTYPE_INTBOX *object_ptr);
void	RED_m_e_t_e_o_extbox (int param_nbr, RSC_OBJTYPE_EXTBOX *object_ptr);
void	RED_m_e_t_e_o_boxtext (int param_nbr, RSC_OBJTYPE_BOXTEXT *object_ptr);
void	RED_m_e_t_e_o_edboxtext (int param_nbr, RSC_OBJTYPE_EDBOXTEXT *object_ptr);
void	RED_m_e_t_e_o_button (int param_nbr, RSC_OBJTYPE_BUTTON *object_ptr);
void	RED_m_e_t_insert_object (int position);
void	RED_m_e_t_delete_object (int position);
void	RED_m_e_t_move_object (int position);
void	RED_m_e_t_copy_object (int position);
int	RED_copy_subtree (int s_object, bool brother_flag);
signed int	RED_build_ascii_tree (bool hide_flag);
void	RED_get_type_name (char *text_0, int type);
void	RED_complete_string (char *text_0, int nbr);
int	RED_get_nbr_childs (signed int object);
void	RED_get_object_full_name (char *object_full_name_0, int tree_stack [8], int tree_depth, bool name_flag);
void	RED_menu_load_rsc (void);
void	RED_menu_save_rsc (void);
int	RED_get_free_object_number (void);
void	*RED_get_object_zone_end (void);
LWORD	RED_get_object_len (int object_type);
int	RED_create_new_object (int object_type, int object_attributes,
									  int object_child, int object_brother,
									  int object_x, int object_y);
int	RED_count_total_object_number (void);
int	RED_count_total_number_of_pics (void);
int	RED_select_object_type (void);
int	RED_select_item (const char **item_name_ptr, int *ret_pos,
							  int x_pos, int y_pos, int nbr_lines, int nbr_columns);
int	RED_input_string (char *buffer_0, int max_len);
void	RED_delete_subtree (int object, bool brother_flag);
void	RED_modify_string (char *&base_0, char *text_0);
int	RED_insert_picname (char *text_0);
void	RED_delete_picname (int pic_nbr);
int	RED_get_free_pic_number (void);
void	RED_remove_unused_picnames (void);
int	RED_save_data_file (char *filename_0);
int	RED_load_data_file (char *filename_0);
void	RED_read_string_in_file (char *buffer_0, FILE *file_ptr);
void	RED_init_object (RSC_OBJTYPE_HEADER *object_ptr);



RSC_OBJTYPE_HEADER  	*RED_object_ptr [RED_NBROBJECTS_MAXI];
char		*RED_string_ptr [RED_NBRSTRINGS_MAXI];
char		*RED_pic_ptr [RED_NBRPIC_MAXI];
int		RED_nbr_objects = 0;		/* N'indique en fait que la pos apres le dernier objet */
int		RED_nbr_pics = 0;			/* N'indique en fait que la pos apres la derniere image */
void		*RED_object_zone_ptr;
char		RED_name_ptr_0 [RED_NBROBJECTS_MAXI] [15+1];
char		RED_id_ptr_0 [RED_NBROBJECTS_MAXI] [7+1];
char		*RED_line_0_ptr;
char		**RED_line_0_ptr_ptr;
int		(*RED_tree_stack_ptr) [RED_MAX_DEPTH];
int		*RED_tree_depth_ptr;
bool		RED_selitem_superexit_flag = false;
int		RED_selected_object = -1;	/* -1: pas d'objet selectionne */
char		*RED_relative_resource_pathname_0 = "..\\..\\src\\";



void	main (void)
{
	if (RED_init () != 0)
	{
		exit (-1);
	}

	RED_main_menu ();

	exit (0);
}



int	RED_init (void)
{
	OS_clear_screen ();

	/* Allocation de la memoire */
	memset (RED_object_ptr, 0, sizeof (*RED_object_ptr) * RED_NBROBJECTS_MAXI);
	memset (RED_pic_ptr, 0, sizeof (*RED_pic_ptr) * RED_NBRPIC_MAXI);
	RED_object_zone_ptr = malloc (RED_OBJECT_ZONE_LEN);
	if (RED_object_zone_ptr == NULL)
	{
		return (-1);
	}
	RED_memory_clear ();
	RED_create_new_object (RSC_OBJECT_NUMBER_NULL, 0, -1, -1, 0, 0);
	atexit (RED_exit);

	return (0);
}



void	RED_exit (void)
{
	free (RED_object_zone_ptr);
}



void	RED_memory_clear (void)
{
	memset (RED_object_ptr, 0, RED_NBROBJECTS_MAXI * sizeof (LWORD));

	for ( ; RED_nbr_pics > 0; RED_nbr_pics --)
	{
		if (RED_pic_ptr [RED_nbr_pics - 1] != NULL)
		{
			free (RED_pic_ptr [RED_nbr_pics - 1]);
			RED_pic_ptr [RED_nbr_pics - 1] = NULL;
		}
	}

	RED_nbr_objects = 0;
}



void	RED_main_menu (void)
{
	int		key;
	bool		exit_flag = false;
	int		total_object_number;
	int		total_number_of_pics;
	char		ton_0 [255 + 1];

	while (!exit_flag)
	{
		OS_clear_screen ();
		OS_print_at (1, 5, "E. Edit tree");
		OS_print_at (1, 7, "L. Load RSC");
		OS_print_at (1, 9, "S. Save RSC");
		OS_print_at (1, 11, "Q. Quit");
		total_object_number = RED_count_total_object_number ();
		total_number_of_pics = RED_count_total_number_of_pics ();
		sprintf (ton_0,
		         "Number of objects:           %d\n"
		         "Number of picture filenames: %d\n",
		         total_object_number, total_number_of_pics);
		OS_print_at (1, OS_NBR_LINES - 3, ton_0);

		RED_clear_keyboard_buffer ();
		key = OS_get_key ();
		switch (toupper (key))
		{
		case	'Q':
		case	0x01:
			exit_flag = RED_alert ("Quit ? Y/N", 'Y', 'N');
			break;
		case	'E':
			RED_menu_edit_tree ();
			break;
		case	'L':
			RED_menu_load_rsc ();
			break;
		case	'S':
			RED_menu_save_rsc ();
			break;
		}
	}
}



void	RED_clear_keyboard_buffer (void)
{
	while (OS_key_pressed ())
	{
		OS_get_key ();
	}
}



bool	RED_alert (char *message_0, int true_key, int false_key)
{
	int		ans;
	bool		exit_flag = false;
	bool		ret_code;
	char		vide_0 [OS_NBR_COLUMNS];

	memset (vide_0, ' ', OS_NBR_COLUMNS - 1);
	vide_0 [OS_NBR_COLUMNS - 1] = 0;
	while (!exit_flag)
	{
		OS_print_at (1, OS_NBR_LINES, message_0);
		RED_clear_keyboard_buffer ();
		ans = toupper (OS_get_key ());
		OS_print_at (1, OS_NBR_LINES, vide_0);
		if (ans == true_key)
		{
			exit_flag = true;
			ret_code = true;
		}
		else if (ans == false_key)
		{
			exit_flag = true;
			ret_code = false;
		}
		else
		{
			printf ("\x07");
		}
	}

	return (ret_code);
}



void	RED_upper_string (char *text_0)
{
	const int		string_len = int (strlen (text_0));
	for (int char_cpt = 0; char_cpt < string_len; char_cpt ++)
	{
		text_0 [char_cpt] = toupper (text_0 [char_cpt]);
	}
}


signed int	RED_menu_edit_tree (void)
{
	int		ret_pos;
	int		ret_key;
	int		object;
	RSC_OBJTYPE_HEADER	*object_ptr;

	ret_key = 0;
	ret_pos = 0;
	while (ret_key != 0x01)
	{
		OS_clear_screen ();
		OS_print_at (3, 4, "                Name            Id      Type      char_x  char_y  pix_x pix_y");
		OS_print_at (1, OS_NBR_LINES - 2, "<Return> Edit, <Insert>, <Delete>, <S>elect, <C>opy, <M>ove, <+><->, <Esc> Exit");

		if (RED_build_ascii_tree (true))
		{
			return (-1);
		}
		if (*RED_line_0_ptr_ptr == NULL)
		{
			free (RED_line_0_ptr);
			free (RED_line_0_ptr_ptr);
			free (RED_tree_stack_ptr);
			free (RED_tree_depth_ptr);
			break;		/* Il n'y a plus d'objet, on s'en va */
		}

		RED_selitem_superexit_flag = true;
		ret_key = RED_select_item ((const char **) RED_line_0_ptr_ptr, &ret_pos, 1, 6, OS_NBR_LINES - 10, 76);
		RED_selitem_superexit_flag = false;
		switch (toupper (ret_key))
		{
		case	0x02:		/* Enter: Edit object */
			RED_m_e_t_edit_object (ret_pos);
			ret_pos ++;
			break;
		case	0x07:		/* Insert: Insere un frere */
			RED_m_e_t_insert_object (ret_pos);
			break;
		case	0x08:		/* Delete */
			RED_m_e_t_delete_object (ret_pos);
			break;
		case	'+':		/* +/-: Masque ou affiche l'arborescence d'un objet */
		case	'-':
			object = RED_tree_stack_ptr [ret_pos] [RED_tree_depth_ptr [ret_pos] - 1];
			object_ptr = RED_object_ptr [object];
			object_ptr->attributes ^= RSC_ATTR_HIDECHILD;
			break;
		case	'S':		/* S: Select object */
			RED_selected_object = RED_tree_stack_ptr [ret_pos] [RED_tree_depth_ptr [ret_pos] - 1];
			break;
		case	'C':		/* C: Copy selected object (famille) */
			RED_m_e_t_copy_object (ret_pos);
			break;
		case	'M':		/* M: Move selected object */
			RED_m_e_t_move_object (ret_pos);
			break;
		}

		free (RED_line_0_ptr);
		free (RED_line_0_ptr_ptr);
		free (RED_tree_stack_ptr);
		free (RED_tree_depth_ptr);
	}

	return (0);
}



int	RED_m_e_t_edit_object_redraw (int ret_pos)
{
	int		object;
	RSC_OBJTYPE_HEADER	*object_ptr;
	int		nbr_options;
	int		img_cnt;
	const char	*img_name_0 [] =
	{
		"Img (norm): ",
		"Img (sel):  ",
		"Img (dis):  "
	};
	char		name_0 [127+1];
	char		id_0 [127+1];
	char		type_0 [127+1];
	char		xpos_0 [127+1];
	char		ypos_0 [127+1];
	char		attrib_0 [127+1];
	char		param_0 [1023+1];

	RSC_OBJTYPE_NULL			*o_null_ptr;
	RSC_OBJTYPE_POINT			*o_point_ptr;
	RSC_OBJTYPE_HLINE			*o_hline_ptr;
	RSC_OBJTYPE_VLINE			*o_vline_ptr;
	RSC_OBJTYPE_BOX			*o_box_ptr;
	RSC_OBJTYPE_XORBOX		*o_xorbox_ptr;
	RSC_OBJTYPE_BITMAP		*o_bitmap_ptr;
	RSC_OBJTYPE_TBITMAP		*o_tbitmap_ptr;
	RSC_OBJTYPE_TEXT			*o_text_ptr;
	RSC_OBJTYPE_TTEXT			*o_ttext_ptr;
	RSC_OBJTYPE_INTBOX		*o_intbox_ptr;
	RSC_OBJTYPE_EXTBOX		*o_extbox_ptr;
	RSC_OBJTYPE_BOXTEXT		*o_boxtext_ptr;
	RSC_OBJTYPE_EDBOXTEXT	*o_edboxtext_ptr;
	RSC_OBJTYPE_BUTTON		*o_button_ptr;

	object = RED_tree_stack_ptr [ret_pos] [RED_tree_depth_ptr [ret_pos] - 1];
	object_ptr = RED_object_ptr [object];
	o_null_ptr = (RSC_OBJTYPE_NULL *) object_ptr;
	o_point_ptr = (RSC_OBJTYPE_POINT *) object_ptr;
	o_hline_ptr = (RSC_OBJTYPE_HLINE *) object_ptr;
	o_vline_ptr = (RSC_OBJTYPE_VLINE *) object_ptr;
	o_box_ptr = (RSC_OBJTYPE_BOX *) object_ptr;
	o_xorbox_ptr = (RSC_OBJTYPE_XORBOX *) object_ptr;
	o_bitmap_ptr = (RSC_OBJTYPE_BITMAP *) object_ptr;
	o_tbitmap_ptr = (RSC_OBJTYPE_TBITMAP *) object_ptr;
	o_text_ptr = (RSC_OBJTYPE_TEXT *) object_ptr;
	o_ttext_ptr = (RSC_OBJTYPE_TTEXT *) object_ptr;
	o_intbox_ptr = (RSC_OBJTYPE_INTBOX *) object_ptr;
	o_extbox_ptr = (RSC_OBJTYPE_EXTBOX *) object_ptr;
	o_boxtext_ptr = (RSC_OBJTYPE_BOXTEXT *) object_ptr;
	o_edboxtext_ptr = (RSC_OBJTYPE_EDBOXTEXT *) object_ptr;
	o_button_ptr = (RSC_OBJTYPE_BUTTON *) object_ptr;
	OS_clear_screen ();

/*______________________________________________
 *
 * Affichage commun a tous les types d'objets
 *______________________________________________
 */

	/* Nom */
	sprintf (name_0, "Name:       %s", RED_name_ptr_0 [object]);
	OS_print_at (3, 3, name_0);

	/* Id */
	sprintf (id_0, "Label:      %s", RED_id_ptr_0 [object]);
	OS_print_at (3, 4, id_0);

	/* Type */
	sprintf (type_0,"Type:       ");
	RED_get_type_name (type_0 + strlen (type_0), object_ptr->primitive);
	OS_print_at (3, 5, type_0);

	/* X pos */
	sprintf (xpos_0, "X_char:     %+07.2f   X_pix: %+03d", (double) (object_ptr->x*100/RSC_CHAR_W) / 100, object_ptr->x);
	OS_print_at (3, 6, xpos_0);

	/* Y pos */
	sprintf (ypos_0, "Y_char:     %+07.2f   Y_pix: %+03d", (double) (object_ptr->y*100/RSC_CHAR_H) / 100, object_ptr->y);
	OS_print_at (3, 7, ypos_0);

	/* Attributs */
	strcpy (attrib_0, "Attributes: ");
	if ((object_ptr->attributes & RSC_ATTR_NOTDISP) != 0)
	{
		strcat (attrib_0, "ndisp ");
	}
	if ((object_ptr->attributes & RSC_ATTR_DISABLE) != 0)
	{
		strcat (attrib_0, "disable ");
	}
	if ((object_ptr->attributes & RSC_ATTR_NOCLICK) != 0)
	{
		strcat (attrib_0, "nclic ");
	}
	if ((object_ptr->attributes & RSC_ATTR_SELECTABLE) != 0)
	{
		strcat (attrib_0, "selectable ");
	}
	if ((object_ptr->attributes & RSC_ATTR_SELECTED) != 0)
	{
		strcat (attrib_0, "selected ");
	}
	if ((object_ptr->attributes & RSC_ATTR_PERMANENT) != 0)
	{
		strcat (attrib_0, "perm ");
	}
	if ((object_ptr->attributes & RSC_ATTR_RADIO) != 0)
	{
		strcat (attrib_0, "radio ");
	}
	if ((object_ptr->attributes & RSC_ATTR_TOUCHEXIT) != 0)
	{
		strcat (attrib_0, "texit ");
	}
	if ((object_ptr->attributes & RSC_ATTR_NOTEMPO) != 0)
	{
		strcat (attrib_0, "notempo ");
	}
	if ((object_ptr->attributes & RSC_ATTR_CAPTURE) != 0)
	{
		strcat (attrib_0, "capture ");
	}
	if ((object_ptr->attributes & RSC_ATTR_ONRELEASE) != 0)
	{
		strcat (attrib_0, "onrel ");
	}
	switch (object_ptr->attributes & 0x7FFF)
	{
	case	RSC_ATTRP_CLICKONLY:
		strcat (attrib_0, "(Click only)");
		break;
	case	RSC_ATTRP_BUT:
		strcat (attrib_0, "(Button)");
		break;
	case	RSC_ATTRP_PBUT:
		strcat (attrib_0, "(Permanent button)");
		break;
	case	RSC_ATTRP_RBUT:
		strcat (attrib_0, "(Radio-button)");
		break;
	case	RSC_ATTRP_CONT:
		strcat (attrib_0, "(Continuous action)");
		break;
	case	RSC_ATTRP_DECOR:
		strcat (attrib_0, "(Decor)");
		break;
	case	RSC_ATTRP_DISABLE:
		strcat (attrib_0, "(Disable)");
		break;
	case	RSC_ATTRP_SLIDER:
		strcat (attrib_0, "(Slider)");
		break;
	case	RSC_ATTRP_FASTREP:
		strcat (attrib_0, "(CLick only with fast rep)");
		break;
	}
	OS_print_at (3, 8, attrib_0);

/*______________________________________________
 *
 * Affichages particuliers a chaque objet
 *______________________________________________
 */

	switch (object_ptr->primitive)
	{
	/* Null */
	case	RSC_OBJECT_NUMBER_NULL:
		nbr_options = 0;
		break;

	/* Point */
	case	RSC_OBJECT_NUMBER_POINT:
		nbr_options = 1;
		sprintf (param_0, "Color:      %d", o_point_ptr->c);
		OS_print_at (3, 9, param_0);
		break;

	/* HLine */
	case	RSC_OBJECT_NUMBER_HLINE:
		nbr_options = 2;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_hline_ptr->l*100/RSC_CHAR_W) / 100,
					o_hline_ptr->l);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "Color:      %d", o_hline_ptr->c);
		OS_print_at (3, 10, param_0);
		break;

	/* VLine */
	case	RSC_OBJECT_NUMBER_VLINE:
		nbr_options = 2;
		sprintf (param_0, "H_char:     %+07.2f   H_pix: %+03d",
					(double) (o_vline_ptr->h*100/RSC_CHAR_H) / 100,
					o_vline_ptr->h);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "Color:      %d", o_vline_ptr->c);
		OS_print_at (3, 10, param_0);
		break;

	/* Box */
	case	RSC_OBJECT_NUMBER_BOX:
		nbr_options = 3;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_box_ptr->l*100/RSC_CHAR_W) / 100,
					o_box_ptr->l);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "H_char:     %+07.2f   H_pix: %+03d",
					(double) (o_box_ptr->h*100/RSC_CHAR_H) / 100,
					o_box_ptr->h);
		OS_print_at (3, 10, param_0);
		sprintf (param_0, "Color:      %d", o_box_ptr->c);
		OS_print_at (3, 11, param_0);
		break;

	/* XorBox */
	case	RSC_OBJECT_NUMBER_XORBOX:
		nbr_options = 3;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_xorbox_ptr->l*100/RSC_CHAR_W) / 100,
					o_xorbox_ptr->l);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "H_char:     %+07.2f   H_pix: %+03d",
					(double) (o_xorbox_ptr->h*100/RSC_CHAR_H) / 100,
					o_xorbox_ptr->h);
		OS_print_at (3, 10, param_0);
		sprintf (param_0, "Color:      %d", o_xorbox_ptr->c);
		OS_print_at (3, 11, param_0);
		break;

	/* Bitmap */
	case	RSC_OBJECT_NUMBER_BITMAP:
		nbr_options = 3;
		for (img_cnt = 0; img_cnt < 3; img_cnt ++)
		{
			strcpy (param_0, img_name_0 [img_cnt]);
			if (o_bitmap_ptr->img [img_cnt] >= 0)
			{
				strcat (param_0, RED_pic_ptr [o_bitmap_ptr->img [img_cnt]]);
			}
			OS_print_at (3, 9 + img_cnt, param_0);
		}
		break;

	/* TBitmap */
	case	RSC_OBJECT_NUMBER_TBITMAP:
		nbr_options = 3;
		for (img_cnt = 0; img_cnt < 3; img_cnt ++)
		{
			strcpy (param_0, img_name_0 [img_cnt]);
			if (o_tbitmap_ptr->img [img_cnt] >= 0)
			{
				strcat (param_0, RED_pic_ptr [o_tbitmap_ptr->img [img_cnt]]);
			}
			OS_print_at (3, 9 + img_cnt, param_0);
		}
		break;

	/* Text */
	case	RSC_OBJECT_NUMBER_TEXT:
		nbr_options = 3;
		sprintf (param_0, "Color:      %d", o_text_ptr->c);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "Text len:   %d", strlen (o_text_ptr->text_0));
		OS_print_at (3, 10, param_0);
		sprintf (param_0, "Text:       %s#end", o_text_ptr->text_0);
		OS_print_at (3, 11, param_0);
		break;

	/* TText */
	case	RSC_OBJECT_NUMBER_TTEXT:
		sprintf (param_0, "Color:      %d", o_ttext_ptr->c);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "Text len:   %d", strlen (o_ttext_ptr->text_0));
		OS_print_at (3, 10, param_0);
		sprintf (param_0, "Text:       %s#end", o_ttext_ptr->text_0);
		OS_print_at (3, 11, param_0);
		nbr_options = 3;
		break;

	/* IntBox */
	case	RSC_OBJECT_NUMBER_INTBOX:
		nbr_options = 3;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_intbox_ptr->l*100/RSC_CHAR_W) / 100,
					o_intbox_ptr->l);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "H_char:     %+07.2f   H_pix: %+03d",
					(double) (o_intbox_ptr->h*100/RSC_CHAR_H) / 100,
					o_intbox_ptr->h);
		OS_print_at (3, 10, param_0);
		strcpy (param_0, "Color type: ");
		switch (o_intbox_ptr->t)
		{
		case	RSC_INTBOX_T_GREY:
			strcat (param_0, "Grey");
			break;
		case	RSC_INTBOX_T_BLUE:
			strcat (param_0, "Grey-Blue");
			break;
		}
		OS_print_at (3, 11, param_0);
		break;

	/* ExtBox */
	case	RSC_OBJECT_NUMBER_EXTBOX:
		nbr_options = 3;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_extbox_ptr->l*100/RSC_CHAR_W) / 100,
					o_extbox_ptr->l);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "H_char:     %+07.2f   H_pix: %+03d",
					(double) (o_extbox_ptr->h*100/RSC_CHAR_H) / 100,
					o_extbox_ptr->h);
		OS_print_at (3, 10, param_0);
		strcpy (param_0, "Color type: ");
		switch (o_extbox_ptr->t)
		{
		case	RSC_EXTBOX_T_BLACKG:
			strcat (param_0, "Black (Grey borders)");
			break;
		case	RSC_EXTBOX_T_BLACKB:
			strcat (param_0, "Black (Grey-Blue borders)");
			break;
		case	RSC_EXTBOX_T_BLUEG:
			strcat (param_0, "Blue (Grey borders)");
			break;
		case	RSC_EXTBOX_T_BLUEB:
			strcat (param_0, "Blue (Grey-Blue borders)");
			break;
		}
		OS_print_at (3, 11, param_0);
		break;

	/* BoxText */
	case	RSC_OBJECT_NUMBER_BOXTEXT:
		nbr_options = 6;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_boxtext_ptr->l*100/RSC_CHAR_W) / 100,
					o_boxtext_ptr->l);
		OS_print_at (3, 9, param_0);
		sprintf (param_0, "H_char:     %+07.2f   H_pix: %+03d",
					(double) (o_boxtext_ptr->h*100/RSC_CHAR_H) / 100,
					o_boxtext_ptr->h);
		OS_print_at (3, 10, param_0);
		strcpy (param_0, "Type:       ");
		switch (o_boxtext_ptr->t)
		{
		case	RSC_BOXTEXT_T_GREY:
			strcat (param_0, "Grey");
			break;
		case	RSC_BOXTEXT_T_BLUE:
			strcat (param_0, "Grey-blue");
			break;
		}
		OS_print_at (3, 11, param_0);
		strcpy (param_0, "Justify:    ");
		switch (o_boxtext_ptr->j)
		{
		case	RSC_BOXTEXT_J_CENTER:
			strcat (param_0, "Center");
			break;
		case	RSC_BOXTEXT_J_LEFT:
			strcat (param_0, "Left");
			break;
		case	RSC_BOXTEXT_J_RIGHT:
			strcat (param_0, "Right");
			break;
		}
		OS_print_at (3, 12, param_0);
		sprintf (param_0, "Text len:   %d", strlen (o_boxtext_ptr->text_0));
		OS_print_at (3, 13, param_0);
		sprintf (param_0, "Text:       %s#end", o_boxtext_ptr->text_0);
		OS_print_at (3, 14, param_0);
		break;

	/* EdBoxText */
	case	RSC_OBJECT_NUMBER_EDBOXTEXT:
		nbr_options = 4;
		sprintf (param_0, "L_char:     %+07.2f   L_pix: %+03d",
					(double) (o_edboxtext_ptr->l*100/RSC_CHAR_W) / 100,
					o_edboxtext_ptr->l);
		OS_print_at (3, 9, param_0);
		strcpy (param_0, "Type:       ");
		switch (o_edboxtext_ptr->t)
		{
		case	RSC_EDBOXTEXT_T_GREY:
			strcat (param_0, "Grey");
			break;
		case	RSC_EDBOXTEXT_T_BLUE:
			strcat (param_0, "Grey-blue");
			break;
		}
		OS_print_at (3, 10, param_0);
		sprintf (param_0, "Text len:   %d", strlen (o_edboxtext_ptr->text_0));
		OS_print_at (3, 11, param_0);
		sprintf (param_0, "Text:       %s#end", o_edboxtext_ptr->text_0);
		OS_print_at (3, 12, param_0);
		break;

	/* Button */
	case	RSC_OBJECT_NUMBER_BUTTON:
		nbr_options = 5;
		strcpy (param_0, "Type:       ");
		switch (o_button_ptr->t)
		{
		case	RSC_BUTTON_T_NONE:
			strcat (param_0, "Custom");
			break;
		case	RSC_BUTTON_T_UARROW:
			strcat (param_0, "Up arrow");
			break;
		case	RSC_BUTTON_T_DARROW:
			strcat (param_0, "Down arrow");
			break;
		case	RSC_BUTTON_T_LARROW:
			strcat (param_0, "Left arrow");
			break;
		case	RSC_BUTTON_T_RARROW:
			strcat (param_0, "Right arrow");
			break;
		case	RSC_BUTTON_T_RRADIO:
			strcat (param_0, "Radio-button (round)");
			break;
		case	RSC_BUTTON_T_CROSS:
			strcat (param_0, "Button (cross)");
			break;
		}
		OS_print_at (3, 9, param_0);
		strcpy (param_0, "Type 2:     ");
		switch (o_button_ptr->t2)
		{
		case	RSC_BUTTON_T2_GREY:
			strcat (param_0, "Grey");
			break;
		case	RSC_BUTTON_T2_BLUE:
			strcat (param_0, "Grey-blue");
			break;
		}
		OS_print_at (3, 10, param_0);
		for (img_cnt = 0; img_cnt < 3; img_cnt ++)
		{
			strcpy (param_0, img_name_0 [img_cnt]);
			if (o_button_ptr->img [img_cnt] >= 0)
			{
				strcat (param_0, RED_pic_ptr [o_button_ptr->img [img_cnt]]);
			}
			OS_print_at (3, 11 + img_cnt, param_0);
		}
		break;

	default:
		nbr_options = 0;
		break;
	}

	return (nbr_options);
}



void	RED_m_e_t_edit_object (int ret_pos)
{
	int		object;
	RSC_OBJTYPE_HEADER	*object_ptr;
	int		nbr_options;
	int		cursor_pos;
	int		key;
	bool		exit_flag;

	RSC_OBJTYPE_NULL			*o_null_ptr;
	RSC_OBJTYPE_POINT			*o_point_ptr;
	RSC_OBJTYPE_HLINE			*o_hline_ptr;
	RSC_OBJTYPE_VLINE			*o_vline_ptr;
	RSC_OBJTYPE_BOX			*o_box_ptr;
	RSC_OBJTYPE_XORBOX		*o_xorbox_ptr;
	RSC_OBJTYPE_BITMAP		*o_bitmap_ptr;
	RSC_OBJTYPE_TBITMAP		*o_tbitmap_ptr;
	RSC_OBJTYPE_TEXT			*o_text_ptr;
	RSC_OBJTYPE_TTEXT			*o_ttext_ptr;
	RSC_OBJTYPE_INTBOX		*o_intbox_ptr;
	RSC_OBJTYPE_EXTBOX		*o_extbox_ptr;
	RSC_OBJTYPE_BOXTEXT		*o_boxtext_ptr;
	RSC_OBJTYPE_EDBOXTEXT	*o_edboxtext_ptr;
	RSC_OBJTYPE_BUTTON		*o_button_ptr;

	nbr_options = RED_m_e_t_edit_object_redraw (ret_pos);

	object = RED_tree_stack_ptr [ret_pos] [RED_tree_depth_ptr [ret_pos] - 1];
	object_ptr = RED_object_ptr [object];
	o_null_ptr = (RSC_OBJTYPE_NULL *) object_ptr;
	o_point_ptr = (RSC_OBJTYPE_POINT *) object_ptr;
	o_hline_ptr = (RSC_OBJTYPE_HLINE *) object_ptr;
	o_vline_ptr = (RSC_OBJTYPE_VLINE *) object_ptr;
	o_box_ptr = (RSC_OBJTYPE_BOX *) object_ptr;
	o_xorbox_ptr = (RSC_OBJTYPE_XORBOX *) object_ptr;
	o_bitmap_ptr = (RSC_OBJTYPE_BITMAP *) object_ptr;
	o_tbitmap_ptr = (RSC_OBJTYPE_TBITMAP *) object_ptr;
	o_text_ptr = (RSC_OBJTYPE_TEXT *) object_ptr;
	o_ttext_ptr = (RSC_OBJTYPE_TTEXT *) object_ptr;
	o_intbox_ptr = (RSC_OBJTYPE_INTBOX *) object_ptr;
	o_extbox_ptr = (RSC_OBJTYPE_EXTBOX *) object_ptr;
	o_boxtext_ptr = (RSC_OBJTYPE_BOXTEXT *) object_ptr;
	o_edboxtext_ptr = (RSC_OBJTYPE_EDBOXTEXT *) object_ptr;
	o_button_ptr = (RSC_OBJTYPE_BUTTON *) object_ptr;

/*______________________________________________
 *
 * Gestion du curseur
 *______________________________________________
 */

	cursor_pos = 0;
	exit_flag = false;
	while (!exit_flag)
	{
		OS_print_at (1, cursor_pos + 3, ">");
		key = OS_get_key ();
		switch (key)
		{
		case	1:		/* Esc */
			exit_flag = true;
			break;
		case	2:		/* Enter */
			if (cursor_pos >= 6)
			{
				switch (object_ptr->primitive)
				{
				case	RSC_OBJECT_NUMBER_NULL:
					break;
				case	RSC_OBJECT_NUMBER_POINT:
					RED_m_e_t_e_o_point (cursor_pos - 6, o_point_ptr);
					break;
				case	RSC_OBJECT_NUMBER_HLINE:
					RED_m_e_t_e_o_hline (cursor_pos - 6, o_hline_ptr);
					break;
				case	RSC_OBJECT_NUMBER_VLINE:
					RED_m_e_t_e_o_vline (cursor_pos - 6, o_vline_ptr);
					break;
				case	RSC_OBJECT_NUMBER_BOX:
					RED_m_e_t_e_o_box (cursor_pos - 6, o_box_ptr);
					break;
				case	RSC_OBJECT_NUMBER_XORBOX:
					RED_m_e_t_e_o_xorbox (cursor_pos - 6, o_xorbox_ptr);
					break;
				case	RSC_OBJECT_NUMBER_BITMAP:
					RED_m_e_t_e_o_bitmap (cursor_pos - 6, o_bitmap_ptr);
					break;
				case	RSC_OBJECT_NUMBER_TBITMAP:
					RED_m_e_t_e_o_tbitmap (cursor_pos - 6, o_tbitmap_ptr);
					break;
				case	RSC_OBJECT_NUMBER_TEXT:
					RED_m_e_t_e_o_text (cursor_pos - 6, o_text_ptr);
					break;
				case	RSC_OBJECT_NUMBER_TTEXT:
					RED_m_e_t_e_o_ttext (cursor_pos - 6, o_ttext_ptr);
					break;
				case	RSC_OBJECT_NUMBER_INTBOX:
					RED_m_e_t_e_o_intbox (cursor_pos - 6, o_intbox_ptr);
					break;
				case	RSC_OBJECT_NUMBER_EXTBOX:
					RED_m_e_t_e_o_extbox (cursor_pos - 6, o_extbox_ptr);
					break;
				case	RSC_OBJECT_NUMBER_BOXTEXT:
					RED_m_e_t_e_o_boxtext (cursor_pos - 6, o_boxtext_ptr);
					break;
				case	RSC_OBJECT_NUMBER_EDBOXTEXT:
					RED_m_e_t_e_o_edboxtext (cursor_pos - 6, o_edboxtext_ptr);
					break;
				case	RSC_OBJECT_NUMBER_BUTTON:
					RED_m_e_t_e_o_button (cursor_pos - 6, o_button_ptr);
					break;
				}
			}
			else
			{
				RED_m_e_t_e_o_header (cursor_pos, object);
			}
			cursor_pos ++;
			nbr_options = RED_m_e_t_edit_object_redraw (ret_pos);
			break;
		case	3: 	/* Up */
			OS_print_at (1, cursor_pos + 3, " ");
			cursor_pos --;
			break;
		case	4:		/* Down */
			OS_print_at (1, cursor_pos + 3, " ");
			cursor_pos ++;
			break;
		}
		cursor_pos = std::max (std::min (cursor_pos, nbr_options + 5), 0);
	}
}



bool	RED_m_e_t_e_o_get_coord (int *pix_coord_ptr, int disp_line, int char_dim)
{
	int		ret_pos;
	float		char_coord;
	char		tampon_0 [15+1];
	const char	*scale_ptr [] =
		{
			"-CANCEL-",
			"Characters",
			"Pixels",
			""
		};

	char_coord = 0;
	ret_pos = 1;
	RED_select_item (scale_ptr, &ret_pos, 1, disp_line, 3, 20);
	if (ret_pos == 1)
	{
		OS_print_at (1, disp_line + 4, "Input value in characters");
		OS_locate (1, disp_line + 5);
		RED_input_string (tampon_0, 15);
		sscanf (tampon_0, "%f", &char_coord);
		*pix_coord_ptr = (int) floor (char_coord * char_dim);
		return (true);
	}
	else if (ret_pos == 2)
	{
		OS_print_at (1, disp_line + 4, "Input value in pixels");
		OS_locate (1, disp_line + 5);
		RED_input_string (tampon_0, 15);
		sscanf (tampon_0, "%d", pix_coord_ptr);
		return (true);
	}

		return (false);
}



void	RED_m_e_t_e_o_header (int param_nbr, int object_nbr)
{
	RSC_OBJTYPE_HEADER	*object_ptr;
	int		ret_pos;
	int		pix_coord;
	LWORD		attributes;
	int		bitcpt;
	int		old_len;
	int		new_len;
	int		obj2;
	int		key;
	int		old_type;
	char		tampon_0 [15+1];
	const char	* type_name_ptr [] =
		{
			"-CANCEL-",
			"Null",
			"Point",
			"Horizontal line",
			"Vertical line",
			"Box",
			"XOR-Box",
			"Bitmap",
			"Transparent Bitmap",
			"Text",
			"Transparent text",
			"Box with inside borders",
			"Box with outside borders",
			"Boxtext",
			"Editable boxtext",
			"Button",
			""
		};
	const int	type_number_ptr [] =
		{
			0xbad,

			RSC_OBJECT_NUMBER_NULL,
			RSC_OBJECT_NUMBER_POINT,
			RSC_OBJECT_NUMBER_HLINE,
			RSC_OBJECT_NUMBER_VLINE,
			RSC_OBJECT_NUMBER_BOX,
			RSC_OBJECT_NUMBER_XORBOX,
			RSC_OBJECT_NUMBER_BITMAP,
			RSC_OBJECT_NUMBER_TBITMAP,
			RSC_OBJECT_NUMBER_TEXT,
			RSC_OBJECT_NUMBER_TTEXT,

			RSC_OBJECT_NUMBER_INTBOX,
			RSC_OBJECT_NUMBER_EXTBOX,
			RSC_OBJECT_NUMBER_BOXTEXT,
			RSC_OBJECT_NUMBER_EDBOXTEXT,
			RSC_OBJECT_NUMBER_BUTTON
		};
	char		attribute_txt_0 [] [64+1] =
	{
		"-CANCEL-",
		"-OK-",
		"Presets:",
		"[ ] Click only",
		"[ ] Button",
		"[ ] Permanent button",
		"[ ] Radio button",
		"[ ] Continuous action",
		"[ ] Decor",
		"[ ] Disable",
		"[ ] Click only with fast response",
		"[ ] Slider",
		"Flags:",
		"[ ] Not displayed",
		"[ ] Disable",
		"[ ] Not clickable",
		"[ ] Selectable",
		"[ ] Selected",
		"[ ] Permanent",
		"[ ] Radio",
		"[ ] Touchexit",
		"[ ] No tempo",
		"[ ] Capture",
		"[ ] On release",
		""
	};
	char		*attribute_ptr [99] = { 0 };
	for (int i = 0; attribute_txt_0 [i] [0] != '\0'; ++i)
	{
		attribute_ptr [i] = attribute_txt_0 [i];
	}

	object_ptr = RED_object_ptr [object_nbr];
	switch (param_nbr)
	{

	/* Nom */
	case	0:
		OS_print_at (1, 17, "Please input object name (15 characters max, no space):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 15);
		strcpy (RED_name_ptr_0 [object_nbr], tampon_0);
		break;

	/* Id */
	case	1:
		OS_print_at (1, 17, "Please input object label (7 characters max, no space):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		RED_upper_string (tampon_0);
		strcpy (RED_id_ptr_0 [object_nbr], tampon_0);
		break;

	/* Type */
	case	2:
		ret_pos = 0;
		RED_select_item (type_name_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
		if (ret_pos != 0)
		{
			old_type = object_ptr->primitive;

			/* Destruction des chaines attachees */
			switch (old_type)
			{
			case	RSC_OBJECT_NUMBER_TEXT:
				free (((RSC_OBJTYPE_TEXT *) object_ptr)->text_0);
				((RSC_OBJTYPE_TEXT *) object_ptr)->text_0 = NULL;
				break;
			case	RSC_OBJECT_NUMBER_TTEXT:
				free (((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0);
				((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0 = NULL;
				break;
			case	RSC_OBJECT_NUMBER_BOXTEXT:
				free (((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0);
				((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0 = NULL;
				break;
			case	RSC_OBJECT_NUMBER_EDBOXTEXT:
				free (((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0);
				((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0 = NULL;
				break;
			}
			new_len = RED_get_object_len (type_number_ptr [ret_pos]);
			old_len = RED_get_object_len (object_ptr->primitive);
			memmove ((BYTE *)object_ptr + new_len, (BYTE *)object_ptr + old_len,
						(BYTE *)RED_get_object_zone_end () - ((BYTE *)object_ptr + old_len));
			for (obj2 = 0; obj2 < RED_nbr_objects; obj2 ++)
			{
				if (RED_object_ptr [obj2] - object_ptr > 0)
				{
					RED_object_ptr [obj2] = (RSC_OBJTYPE_HEADER *) ((BYTE *) RED_object_ptr [obj2] - old_len + new_len);
				}
			}
			object_ptr->primitive = type_number_ptr [ret_pos];
			RED_init_object (object_ptr);

			/* Destruction des images attachees */
			switch (old_type)
			{
			case	RSC_OBJECT_NUMBER_BITMAP:
			case	RSC_OBJECT_NUMBER_TBITMAP:
			case	RSC_OBJECT_NUMBER_BUTTON:
				RED_remove_unused_picnames ();
				break;
			}
		}
		break;

	/* X pos */
	case	3:
		if (RED_m_e_t_e_o_get_coord (&pix_coord, 17, RSC_CHAR_W))
		{
			object_ptr->x = pix_coord;
		}
		break;

	/* Y pos */
	case	4:
		if (RED_m_e_t_e_o_get_coord (&pix_coord, 17, RSC_CHAR_H))
		{
			object_ptr->y = pix_coord;
		}
		break;

	/* Attributes */
	case	5:
		ret_pos = 999;
		attributes = object_ptr->attributes;
		while (ret_pos > 1)
		{
			attribute_ptr [3] [1] = ' ';
			attribute_ptr [4] [1] = ' ';
			attribute_ptr [5] [1] = ' ';
			attribute_ptr [6] [1] = ' ';
			attribute_ptr [7] [1] = ' ';
			attribute_ptr [8] [1] = ' ';
			attribute_ptr [9] [1] = ' ';
			attribute_ptr [10] [1] = ' ';
			attribute_ptr [11] [1] = ' ';
			switch (attributes)
			{
			case	RSC_ATTRP_CLICKONLY:
				attribute_ptr [3] [1] = 'x';
				break;
			case	RSC_ATTRP_BUT:
				attribute_ptr [4] [1] = 'x';
				break;
			case	RSC_ATTRP_PBUT:
				attribute_ptr [5] [1] = 'x';
				break;
			case	RSC_ATTRP_RBUT:
				attribute_ptr [6] [1] = 'x';
				break;
			case	RSC_ATTRP_CONT:
				attribute_ptr [7] [1] = 'x';
				break;
			case	RSC_ATTRP_DECOR:
				attribute_ptr [8] [1] = 'x';
				break;
			case	RSC_ATTRP_DISABLE:
				attribute_ptr [9] [1] = 'x';
				break;
			case	RSC_ATTRP_FASTREP:
				attribute_ptr [10] [1] = 'x';
				break;
			case	RSC_ATTRP_SLIDER:
				attribute_ptr [11] [1] = 'x';
				break;
			}
			for (bitcpt = 0; bitcpt < 11; bitcpt ++)
			{
				if ((attributes & (1 << bitcpt)) != 0)
				{
					attribute_ptr [bitcpt + 13] [1] = 'x';
				}
				else
				{
					attribute_ptr [bitcpt + 13] [1] = ' ';
				}
			}
			if (ret_pos >= 999)
			{
				ret_pos = 4;
			}
			key = RED_select_item ((const char **) attribute_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
			if (key == 0x01)
			{
				break;		/* Fin du while */
			}
			if (ret_pos >= 13 && ret_pos < (13+11))
			{
				attributes = attributes ^ (1 << (ret_pos - 13));
			}
			else
			{
				switch (ret_pos)
				{
				case	3:
					attributes = RSC_ATTRP_CLICKONLY;
					break;
				case	4:
					attributes = RSC_ATTRP_BUT;
					break;
				case	5:
					attributes = RSC_ATTRP_PBUT;
					break;
				case	6:
					attributes = RSC_ATTRP_RBUT;
					break;
				case	7:
					attributes = RSC_ATTRP_CONT;
					break;
				case	8:
					attributes = RSC_ATTRP_DECOR;
					break;
				case	9:
					attributes = RSC_ATTRP_DISABLE;
					break;
				case	10:
					attributes = RSC_ATTRP_FASTREP;
					break;
				case	11:
					attributes = RSC_ATTRP_SLIDER;
					break;
				}
			}
		}
		if (ret_pos == 1 || key == 0x01)
		{
			object_ptr->attributes = attributes | (object_ptr->attributes & 0x8000);
		}
		break;

	}
}



void	RED_m_e_t_e_o_point (int param_nbr, RSC_OBJTYPE_POINT *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;

	switch (param_nbr)
	{

	/* Color */
	case	0:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;
	}
}



void	RED_m_e_t_e_o_hline (int param_nbr, RSC_OBJTYPE_HLINE *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Color */
	case	1:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;
	}
}



void	RED_m_e_t_e_o_vline (int param_nbr, RSC_OBJTYPE_VLINE *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;

	switch (param_nbr)
	{

	/* Height */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_H))
		{
			object_ptr->h = std::max (param, 0);
		}
		break;

	/* Color */
	case	1:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;
	}
}



void	RED_m_e_t_e_o_box (int param_nbr, RSC_OBJTYPE_BOX *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Height */
	case	1:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_H))
		{
			object_ptr->h = std::max (param, 0);
		}
		break;

	/* Color */
	case	2:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;
	}
}



void	RED_m_e_t_e_o_xorbox (int param_nbr, RSC_OBJTYPE_XORBOX *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Height */
	case	1:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_H))
		{
			object_ptr->h = std::max (param, 0);
		}
		break;

	/* Color */
	case	2:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;
	}
}



void	RED_m_e_t_e_o_bitmap (int param_nbr, RSC_OBJTYPE_BITMAP *object_ptr)
{
	char		text_0 [255+1];

	OS_print_at (1, 17, "Please input image name:");
	OS_locate (1, 18);
	RED_input_string (text_0, 255);
	if (strlen (text_0) > 0)
	{
		object_ptr->img [param_nbr] = RED_insert_picname (text_0);
	}
	else
	{
		object_ptr->img [param_nbr] = -1;
	}
	RED_remove_unused_picnames ();
}



void	RED_m_e_t_e_o_tbitmap (int param_nbr, RSC_OBJTYPE_TBITMAP *object_ptr)
{
	char		text_0 [255+1];

	OS_print_at (1, 17, "Please input image name:");
	OS_locate (1, 18);
	RED_input_string (text_0, 255);
	if (strlen (text_0) > 0)
	{
		object_ptr->img [param_nbr] = RED_insert_picname (text_0);
	}
	else
	{
		object_ptr->img [param_nbr] = -1;
	}
	RED_remove_unused_picnames ();
}



void	RED_m_e_t_e_o_text (int param_nbr, RSC_OBJTYPE_TEXT *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;
	char		text_0 [255+1];

	switch (param_nbr)
	{

	/* Color */
	case	0:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;

	/* Text len */
	case	1:
		OS_print_at (1, 17, "Please input text len:");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		param = std::max (std::min (param, 255), 0);
		strncpy (text_0, object_ptr->text_0, param);
		text_0 [255] = 0;
		memset (text_0 + strlen (text_0), ' ', 255 - strlen (text_0));
		text_0 [param] = 0;
		RED_modify_string (object_ptr->text_0, text_0);
		break;

	/* Text */
	case	2:
		OS_print_at (1, 17, "Please input text string:");
		OS_locate (1, 18);
		RED_input_string (text_0, 255);
		RED_modify_string (object_ptr->text_0, text_0);
		break;
	}
}



void	RED_m_e_t_e_o_ttext (int param_nbr, RSC_OBJTYPE_TTEXT *object_ptr)
{
	char		tampon_0 [15+1];
	int		param;
	char		text_0 [255+1];

	switch (param_nbr)
	{

	/* Color */
	case	0:
		OS_print_at (1, 17, "Please input object color (0-255):");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		object_ptr->c = std::max (std::min (param, 255), 0);
		break;

	/* Text len */
	case	1:
		OS_print_at (1, 17, "Please input text len:");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		param = std::max (std::min (param, 255), 0);
		strncpy (text_0, object_ptr->text_0, param);
		text_0 [255] = 0;
		memset (text_0 + strlen (text_0), ' ', 255 - strlen (text_0));
		text_0 [param] = 0;
		RED_modify_string (object_ptr->text_0, text_0);
		break;

	/* Text */
	case	2:
		OS_print_at (1, 17, "Please input text string:");
		OS_locate (1, 18);
		RED_input_string (text_0, 255);
		RED_modify_string (object_ptr->text_0, text_0);
		break;
	}
}



void	RED_m_e_t_e_o_intbox (int param_nbr, RSC_OBJTYPE_INTBOX *object_ptr)
{
	int		param;
	int		ret_pos;
	const char	*type_ptr [] =
	{
		"-CANCEL-",
		"Grey",
		"Grey-blue",
		""
	};
	const int	type_nbr [] =
	{
		0xbad,
		RSC_INTBOX_T_GREY,
		RSC_INTBOX_T_BLUE
	};

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Height */
	case	1:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_H))
		{
			object_ptr->h = std::max (param, 0);
		}
		break;

	/* Type */
	case	2:
		ret_pos = 0;
		RED_select_item (type_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
		if (ret_pos != 0)
		{
			object_ptr->t = type_nbr [ret_pos];
		}
		break;
	}
}



void	RED_m_e_t_e_o_extbox (int param_nbr, RSC_OBJTYPE_EXTBOX *object_ptr)
{
	int		param;
	int		ret_pos;
	const char	*type_ptr [] =
	{
		"-CANCEL-",
		"Black with grey borders",
		"Black with grey-blue borders",
		"Blue with grey borders",
		"Blue with grey-blue borders",
		""
	};
	const int	type_nbr [] =
	{
		0xbad,
		RSC_EXTBOX_T_BLACKG,
		RSC_EXTBOX_T_BLACKB,
		RSC_EXTBOX_T_BLUEG,
		RSC_EXTBOX_T_BLUEB
	};

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Height */
	case	1:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_H))
		{
			object_ptr->h = std::max (param, 0);
		}
		break;

	/* Type */
	case	2:
		ret_pos = 0;
		RED_select_item (type_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
		if (ret_pos != 0)
		{
			object_ptr->t = type_nbr [ret_pos];
		}
		break;
	}
}



void	RED_m_e_t_e_o_boxtext (int param_nbr, RSC_OBJTYPE_BOXTEXT *object_ptr)
{
	int		param;
	int		ret_pos;
	char		tampon_0 [15+1];
	char		text_0 [255+1];
	const char	*type_ptr [] =
	{
		"-CANCEL-",
		"Grey",
		"Grey-blue",
		""
	};
	const int	type_nbr [] =
	{
		0xbad,
		RSC_BOXTEXT_T_GREY,
		RSC_BOXTEXT_T_BLUE
	};
	const char	*justify_ptr [] =
	{
		"-CANCEL-",
		"Center",
		"Left",
		"Right",
		""
	};
	const int	justify_nbr [] =
	{
		0xbad,
		RSC_BOXTEXT_J_CENTER,
		RSC_BOXTEXT_J_LEFT,
		RSC_BOXTEXT_J_RIGHT
	};

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Height */
	case	1:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_H))
		{
			object_ptr->h = std::max (param, 0);
		}
		break;

	/* Type */
	case	2:
		ret_pos = 0;
		RED_select_item (type_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
		if (ret_pos != 0)
		{
			object_ptr->t = type_nbr [ret_pos];
		}
		break;

	/* Justify */
	case	3:
		ret_pos = 0;
		RED_select_item (justify_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
		if (ret_pos != 0)
		{
			object_ptr->j = justify_nbr [ret_pos];
		}
		break;

	/* Text len */
	case	4:
		OS_print_at (1, 17, "Please input text len:");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		param = std::max (std::min (param, 255), 0);
		strncpy (text_0, object_ptr->text_0, param);
		text_0 [255] = 0;
		memset (text_0 + strlen (text_0), ' ', 255 - strlen (text_0));
		text_0 [param] = 0;
		RED_modify_string (object_ptr->text_0, text_0);
		break;

	/* Text */
	case	5:
		OS_print_at (1, 17, "Please input text string:");
		OS_locate (1, 18);
		RED_input_string (text_0, 255);
		RED_modify_string (object_ptr->text_0, text_0);
		break;
	}
}



void	RED_m_e_t_e_o_edboxtext (int param_nbr, RSC_OBJTYPE_EDBOXTEXT *object_ptr)
{
	int		param;
	int		ret_pos;
	char		tampon_0 [15+1];
	char		text_0 [255+1];
	const char	*type_ptr [] =
	{
		"-CANCEL-",
		"Grey",
		"Grey-blue",
		""
	};
	const int	type_nbr [] =
	{
		0xbad,
		RSC_EDBOXTEXT_T_GREY,
		RSC_EDBOXTEXT_T_BLUE
	};

	switch (param_nbr)
	{

	/* Length */
	case	0:
		if (RED_m_e_t_e_o_get_coord (&param, 17, RSC_CHAR_W))
		{
			object_ptr->l = std::max (param, 0);
		}
		break;

	/* Type */
	case	1:
		ret_pos = 0;
		RED_select_item (type_ptr, &ret_pos, 1, 17, OS_NBR_LINES-18, 48);
		if (ret_pos != 0)
		{
			object_ptr->t = type_nbr [ret_pos];
		}
		break;

	/* Text len */
	case	2:
		OS_print_at (1, 17, "Please input text len:");
		OS_locate (1, 18);
		RED_input_string (tampon_0, 7);
		sscanf (tampon_0, "%d", &param);
		param = std::max (std::min (param, 255), 0);
		strncpy (text_0, object_ptr->text_0, param);
		text_0 [255] = 0;
		memset (text_0 + strlen (text_0), ' ', 255 - strlen (text_0));
		text_0 [param] = 0;
		RED_modify_string (object_ptr->text_0, text_0);
		break;

	/* Text */
	case	3:
		OS_print_at (1, 17, "Please input text string:");
		OS_locate (1, 18);
		RED_input_string (text_0, 255);
		RED_modify_string (object_ptr->text_0, text_0);
		break;
	}
}



void	RED_m_e_t_e_o_button (int param_nbr, RSC_OBJTYPE_BUTTON *object_ptr)
{
	int		ret_pos;
	char		text_0 [255+1];
	const char	*type_ptr [] =
	{
		"-CANCEL-",
		"Custom",
		"Up arrow",
		"Down arrow",
		"Left arrow",
		"Right arrow",
		"Round radio button",
		"Button (cross)",
		""
	};
	const int	type_nbr [] =
	{
		0xbad,
		RSC_BUTTON_T_NONE,
		RSC_BUTTON_T_UARROW,
		RSC_BUTTON_T_DARROW,
		RSC_BUTTON_T_LARROW,
		RSC_BUTTON_T_RARROW,
		RSC_BUTTON_T_RRADIO,
		RSC_BUTTON_T_CROSS
	};
	const char	*type2_ptr [] =
	{
		"-CANCEL-",
		"Grey",
		"Grey-blue",
		""
	};
	const int	type2_nbr [] =
	{
		0xbad,
		RSC_BUTTON_T2_GREY,
		RSC_BUTTON_T2_BLUE
	};

	switch (param_nbr)
	{

	/* Type */
	case	0:
		ret_pos = 0;
		RED_select_item (type_ptr, &ret_pos, 1, 20, OS_NBR_LINES-21, 48);
		if (ret_pos != 0)
		{
			object_ptr->t = type_nbr [ret_pos];
			RED_remove_unused_picnames ();
		}
		break;

	/* Type 2 */
	case	1:
		ret_pos = 0;
		RED_select_item (type2_ptr, &ret_pos, 1, 20, OS_NBR_LINES-21, 48);
		if (ret_pos != 0)
		{
			object_ptr->t2 = type2_nbr [ret_pos];
			RED_remove_unused_picnames ();
		}
		break;

	/* Images */
	case	2:
	case	3:
	case	4:
		OS_print_at (1, 17, "Please input image name:");
		OS_locate (1, 18);
		RED_input_string (text_0, 255);
		if (strlen (text_0) > 0)
		{
			object_ptr->img [param_nbr - 2] = RED_insert_picname (text_0);
			object_ptr->t = RSC_BUTTON_T_NONE;
		}
		else
		{
			object_ptr->img [param_nbr - 2] = -1;
		}
		RED_remove_unused_picnames ();
		break;
	}
}



void	RED_m_e_t_insert_object (int position)
{
	int		new_object_nbr;
	int		object_nbr;
	int		ret_pos;
	RSC_OBJTYPE_HEADER	*object_ptr;
	const char	*loc_ptr [] =
	{
		"-CANCEL-",
		"Before (not implemented yet)",
		"After",
		"In",
		"In (children become sub-children)",
		""
	};

	OS_clear_screen ();
	OS_print_at (1, 1, "Insert new object");
	ret_pos = 2;
	RED_select_item (loc_ptr, &ret_pos, 1, 3, OS_NBR_LINES-18, 48);
	if (ret_pos > 0)
	{
		object_nbr = RED_tree_stack_ptr [position] [RED_tree_depth_ptr [position] - 1];
		object_ptr = RED_object_ptr [object_nbr];
		switch (ret_pos)
		{

		/* Ajoute un frere avant l'objet pointe */
		case	1:
			if (object_nbr == 0)
			{
			}
			else
			{
			}
			break;

		/* Ajoute un frere apres l'objet pointe */
		case	2:
			object_nbr = object_ptr->brother.number;
			new_object_nbr = RED_create_new_object (RSC_OBJECT_NUMBER_NULL,
																 RSC_ATTRP_DECOR,
																 -1, object_nbr, 0, 0);
			object_ptr->brother.number = new_object_nbr;
			break;

		/* Ajoute un fils a l'objet pointe */
		case	3:
			object_nbr = object_ptr->child.number;
			new_object_nbr = RED_create_new_object (RSC_OBJECT_NUMBER_NULL,
																 RSC_ATTRP_DECOR,
																 -1, object_nbr, 0, 0);
			object_ptr->child.number = new_object_nbr;
			break;

		/* Ajoute un fils a l'objet pointe. Les fils precedents deviennent petit-fils */
		case	4:
			object_nbr = object_ptr->child.number;
			new_object_nbr = RED_create_new_object (RSC_OBJECT_NUMBER_NULL,
																 RSC_ATTRP_DECOR,
																 object_nbr, -1, 0, 0);
			object_ptr->child.number = new_object_nbr;
			break;

		}
	}
}



void	RED_m_e_t_delete_object (int position)
{
	char		object_full_name_0 [255+1];
	char		text_0 [255+1];
	char		object_name_0 [255+1];
	char		object_id_0 [255+1];
	int		object;
	RSC_OBJTYPE_HEADER	*object_ptr;

	object = RED_tree_stack_ptr [position] [RED_tree_depth_ptr [position] - 1];
	RED_get_object_full_name (object_full_name_0, &(RED_tree_stack_ptr [position] [0]), RED_tree_depth_ptr [position], true);
	if (strlen (object_full_name_0) > OS_NBR_COLUMNS - 16)
	{
		RED_get_object_full_name (object_full_name_0, &(RED_tree_stack_ptr [position] [0]), RED_tree_depth_ptr [position], false);
	}
	sprintf (text_0, "Delete %s ? (Y/N)", object_full_name_0);
	if (RED_alert (text_0, 'Y', 'N'))
	{
		if (object == 0)
		{
			object = RED_object_ptr [0]->brother.number;
			if (object < 0)
			{
				RED_alert ("Tree can\'t be empty. You\'re not allowed to delete the whole tree. <Return>", 0x01, 0x02);
				return;
			}
			object_ptr = RED_object_ptr [0];
			RED_object_ptr [0] = RED_object_ptr [object];
			RED_object_ptr [object] = object_ptr;
			strcpy (object_name_0, RED_name_ptr_0 [0]);
			strcpy (RED_name_ptr_0 [0], RED_name_ptr_0 [object]);
			strcpy (RED_name_ptr_0 [object], object_name_0);
			strcpy (object_id_0, RED_id_ptr_0 [0]);
			strcpy (RED_id_ptr_0 [0], RED_id_ptr_0 [object]);
			strcpy (RED_id_ptr_0 [object], object_id_0);
		}
		RED_delete_subtree (object, false);
	}
}



void	RED_m_e_t_move_object (int position)
{

	/*** A faire ***/

}



void	RED_m_e_t_copy_object (int position)
{
	int		l_object;	/* Objet sur lequel sera attache le nouvel objet */
	int		d_object;	/* Nouvel objet */
	RSC_OBJTYPE_HEADER	*d_object_ptr;
	RSC_OBJTYPE_HEADER	*l_object_ptr;
	int		ret_pos;
	const char	*loc_ptr [] =
	{
		"-CANCEL-",
		"Before (not implemented yet)",
		"After",
		"In",
		""
	};

	if (RED_selected_object < 0)
	{
		RED_alert ("No selected object. <Return>", 0x01, 0x02);
		return;
	}
	if (RED_object_ptr [RED_selected_object] == NULL)
	{
		RED_alert ("Selected object not found. <Return>", 0x01, 0x02);
		return;
	}

	OS_clear_screen ();
	OS_print_at (1, 1, "Copy object");
	ret_pos = 2;
	RED_select_item (loc_ptr, &ret_pos, 1, 3, OS_NBR_LINES-18, 48);
	if (ret_pos > 0)
	{
		l_object = RED_tree_stack_ptr [position] [RED_tree_depth_ptr [position] - 1];
		switch (ret_pos)
		{
		case	1:
			break;

		case	2:
			d_object = RED_copy_subtree (RED_selected_object, false);
			l_object_ptr = RED_object_ptr [l_object];
			d_object_ptr = RED_object_ptr [d_object];
			d_object_ptr->brother.number = l_object_ptr->brother.number;
			l_object_ptr->brother.number = d_object;
			break;

		case	3:
			d_object = RED_copy_subtree (RED_selected_object, false);
			l_object_ptr = RED_object_ptr [l_object];
			d_object_ptr = RED_object_ptr [d_object];
			d_object_ptr->brother.number = l_object_ptr->child.number;
			l_object_ptr->child.number = d_object;
			break;
		}
	}
}



int	RED_copy_subtree (int s_object, bool brother_flag)
{
	int		s_type;
	int		d_object;
	int		s2_object;
	int		d2_object;
	RSC_OBJTYPE_HEADER	*s_object_ptr;
	RSC_OBJTYPE_HEADER	*d_object_ptr;

	s_object_ptr = RED_object_ptr [s_object];
	s_type = s_object_ptr->primitive;
	d_object = RED_create_new_object (s_type, s_object_ptr->attributes, -1, -1,
												 s_object_ptr->x, s_object_ptr->y);
	d_object_ptr = RED_object_ptr [d_object];

	switch (s_type)
	{
	case	RSC_OBJECT_NUMBER_NULL:
		break;

	case	RSC_OBJECT_NUMBER_POINT:
		((RSC_OBJTYPE_POINT *) d_object_ptr)->c = ((RSC_OBJTYPE_POINT *) s_object_ptr)->c;
		break;

	case	RSC_OBJECT_NUMBER_HLINE:
		((RSC_OBJTYPE_HLINE *) d_object_ptr)->l = ((RSC_OBJTYPE_HLINE *) s_object_ptr)->l;
		((RSC_OBJTYPE_HLINE *) d_object_ptr)->c = ((RSC_OBJTYPE_HLINE *) s_object_ptr)->c;
		break;

	case	RSC_OBJECT_NUMBER_VLINE:
		((RSC_OBJTYPE_VLINE *) d_object_ptr)->h = ((RSC_OBJTYPE_VLINE *) s_object_ptr)->h;
		((RSC_OBJTYPE_VLINE *) d_object_ptr)->c = ((RSC_OBJTYPE_VLINE *) s_object_ptr)->c;
		break;

	case	RSC_OBJECT_NUMBER_BOX:
		((RSC_OBJTYPE_BOX *) d_object_ptr)->l = ((RSC_OBJTYPE_BOX *) s_object_ptr)->l;
		((RSC_OBJTYPE_BOX *) d_object_ptr)->h = ((RSC_OBJTYPE_BOX *) s_object_ptr)->h;
		((RSC_OBJTYPE_BOX *) d_object_ptr)->c = ((RSC_OBJTYPE_BOX *) s_object_ptr)->c;
		break;

	case	RSC_OBJECT_NUMBER_XORBOX:
		((RSC_OBJTYPE_XORBOX *) d_object_ptr)->l = ((RSC_OBJTYPE_XORBOX *) s_object_ptr)->l;
		((RSC_OBJTYPE_XORBOX *) d_object_ptr)->h = ((RSC_OBJTYPE_XORBOX *) s_object_ptr)->h;
		((RSC_OBJTYPE_XORBOX *) d_object_ptr)->c = ((RSC_OBJTYPE_XORBOX *) s_object_ptr)->c;
		break;

	case	RSC_OBJECT_NUMBER_BITMAP:
		((RSC_OBJTYPE_BITMAP *) d_object_ptr)->img [0] = ((RSC_OBJTYPE_BITMAP *) s_object_ptr)->img [0];
		((RSC_OBJTYPE_BITMAP *) d_object_ptr)->img [1] = ((RSC_OBJTYPE_BITMAP *) s_object_ptr)->img [1];
		((RSC_OBJTYPE_BITMAP *) d_object_ptr)->img [2] = ((RSC_OBJTYPE_BITMAP *) s_object_ptr)->img [2];
		break;

	case	RSC_OBJECT_NUMBER_TBITMAP:
		((RSC_OBJTYPE_TBITMAP *) d_object_ptr)->img [0] = ((RSC_OBJTYPE_TBITMAP *) s_object_ptr)->img [0];
		((RSC_OBJTYPE_TBITMAP *) d_object_ptr)->img [1] = ((RSC_OBJTYPE_TBITMAP *) s_object_ptr)->img [1];
		((RSC_OBJTYPE_TBITMAP *) d_object_ptr)->img [2] = ((RSC_OBJTYPE_TBITMAP *) s_object_ptr)->img [2];
		break;

	case	RSC_OBJECT_NUMBER_TEXT:
		((RSC_OBJTYPE_TEXT *) d_object_ptr)->c = ((RSC_OBJTYPE_TEXT *) s_object_ptr)->c;
		((RSC_OBJTYPE_TEXT *) d_object_ptr)->text_0 = STRDUP (((RSC_OBJTYPE_TEXT *) s_object_ptr)->text_0);
		break;

	case	RSC_OBJECT_NUMBER_TTEXT:
		((RSC_OBJTYPE_TTEXT *) d_object_ptr)->c = ((RSC_OBJTYPE_TTEXT *) s_object_ptr)->c;
		((RSC_OBJTYPE_TTEXT *) d_object_ptr)->text_0 = STRDUP (((RSC_OBJTYPE_TTEXT *) s_object_ptr)->text_0);
		break;

	case	RSC_OBJECT_NUMBER_INTBOX:
		((RSC_OBJTYPE_INTBOX *) d_object_ptr)->l = ((RSC_OBJTYPE_INTBOX *) s_object_ptr)->l;
		((RSC_OBJTYPE_INTBOX *) d_object_ptr)->h = ((RSC_OBJTYPE_INTBOX *) s_object_ptr)->h;
		((RSC_OBJTYPE_INTBOX *) d_object_ptr)->t = ((RSC_OBJTYPE_INTBOX *) s_object_ptr)->t;
		break;

	case	RSC_OBJECT_NUMBER_EXTBOX:
		((RSC_OBJTYPE_EXTBOX *) d_object_ptr)->l = ((RSC_OBJTYPE_EXTBOX *) s_object_ptr)->l;
		((RSC_OBJTYPE_EXTBOX *) d_object_ptr)->h = ((RSC_OBJTYPE_EXTBOX *) s_object_ptr)->h;
		((RSC_OBJTYPE_EXTBOX *) d_object_ptr)->t = ((RSC_OBJTYPE_EXTBOX *) s_object_ptr)->t;
		break;

	case	RSC_OBJECT_NUMBER_BOXTEXT:
		((RSC_OBJTYPE_BOXTEXT *) d_object_ptr)->l = ((RSC_OBJTYPE_BOXTEXT *) s_object_ptr)->l;
		((RSC_OBJTYPE_BOXTEXT *) d_object_ptr)->h = ((RSC_OBJTYPE_BOXTEXT *) s_object_ptr)->h;
		((RSC_OBJTYPE_BOXTEXT *) d_object_ptr)->t = ((RSC_OBJTYPE_BOXTEXT *) s_object_ptr)->t;
		((RSC_OBJTYPE_BOXTEXT *) d_object_ptr)->j = ((RSC_OBJTYPE_BOXTEXT *) s_object_ptr)->j;
		((RSC_OBJTYPE_BOXTEXT *) d_object_ptr)->text_0 = STRDUP (((RSC_OBJTYPE_BOXTEXT *) s_object_ptr)->text_0);
		break;

	case	RSC_OBJECT_NUMBER_EDBOXTEXT:
		((RSC_OBJTYPE_EDBOXTEXT *) d_object_ptr)->l = ((RSC_OBJTYPE_EDBOXTEXT *) s_object_ptr)->l;
		((RSC_OBJTYPE_EDBOXTEXT *) d_object_ptr)->t = ((RSC_OBJTYPE_EDBOXTEXT *) s_object_ptr)->t;
		((RSC_OBJTYPE_EDBOXTEXT *) d_object_ptr)->text_0 = STRDUP (((RSC_OBJTYPE_EDBOXTEXT *) s_object_ptr)->text_0);
		break;

	case	RSC_OBJECT_NUMBER_BUTTON:
		((RSC_OBJTYPE_BUTTON *) d_object_ptr)->t = ((RSC_OBJTYPE_BUTTON *) s_object_ptr)->t;
		((RSC_OBJTYPE_BUTTON *) d_object_ptr)->t2 = ((RSC_OBJTYPE_BUTTON *) s_object_ptr)->t2;
		((RSC_OBJTYPE_BUTTON *) d_object_ptr)->img [0] = ((RSC_OBJTYPE_BUTTON *) s_object_ptr)->img [0];
		((RSC_OBJTYPE_BUTTON *) d_object_ptr)->img [1] = ((RSC_OBJTYPE_BUTTON *) s_object_ptr)->img [1];
		((RSC_OBJTYPE_BUTTON *) d_object_ptr)->img [2] = ((RSC_OBJTYPE_BUTTON *) s_object_ptr)->img [2];
		break;

	default:
		break;
	}

	strcpy (RED_name_ptr_0 [d_object], RED_name_ptr_0 [s_object]);
	strcpy (RED_id_ptr_0 [d_object], RED_id_ptr_0 [s_object]);

	s2_object = s_object_ptr->child.number;
	if (s2_object >= 0)
	{
		d2_object = RED_copy_subtree (s2_object, true);
		d_object_ptr->child.number = d2_object;
	}

	if (brother_flag)
	{
		s2_object = s_object_ptr->brother.number;
		if (s2_object >= 0)
		{
			d2_object = RED_copy_subtree (s2_object, true);
			d_object_ptr->brother.number = d2_object;
		}
	}

	return (d_object);
}



signed int	RED_build_ascii_tree (bool hide_flag)
{
	char		*buffer_0_ptr;
	int		current_tree_stack_ptr [RED_MAX_DEPTH];
	int		depth;
	int		object_nbr;
	int		nbr_lines;
	RSC_OBJTYPE_HEADER	*object_ptr;
	int		level;
	int		rec_state;

/*______________________________________________
 *
 * Reservation de la memoire
 *______________________________________________
 */

	RED_line_0_ptr     = (char *) malloc ((RED_nbr_objects+1) * 80);
	RED_line_0_ptr_ptr = (char **) malloc ((RED_nbr_objects+1) * sizeof (LWORD));
	RED_tree_stack_ptr = (int (*)[RED_MAX_DEPTH]) malloc ((RED_nbr_objects+1) * sizeof (int) * RED_MAX_DEPTH);
	RED_tree_depth_ptr = (int *) malloc ((RED_nbr_objects+1) * sizeof (int));
	if (   RED_line_0_ptr     == 0
	    || RED_line_0_ptr_ptr == 0
	    || RED_tree_stack_ptr == 0
	    || RED_tree_depth_ptr == 0)
	{
		RED_alert ("Memory allocation error. Press <Return>", 0x01, 0x02);
		if (RED_line_0_ptr     != 0) { free (RED_line_0_ptr    ); RED_line_0_ptr     = 0; }
		if (RED_line_0_ptr_ptr != 0) { free (RED_line_0_ptr_ptr); RED_line_0_ptr_ptr = 0; }
		if (RED_tree_stack_ptr != 0) { free (RED_tree_stack_ptr); RED_tree_stack_ptr = 0; }
		if (RED_tree_depth_ptr != 0) { free (RED_tree_depth_ptr); RED_tree_depth_ptr = 0; }
		return (-1);
	}

/*______________________________________________
 *
 * Remplissage des tableaux
 *______________________________________________
 */

	depth = 1;
	current_tree_stack_ptr [0] = 0;
	object_nbr = 0;
	object_ptr = RED_object_ptr [object_nbr];
	nbr_lines = 0;
	while (depth > 0)
	{
		buffer_0_ptr = RED_line_0_ptr + nbr_lines * 80;
		RED_line_0_ptr_ptr [nbr_lines] = buffer_0_ptr;
		memmove (&(RED_tree_stack_ptr [nbr_lines] [0]), current_tree_stack_ptr, depth * sizeof (int));
		RED_tree_depth_ptr [nbr_lines] = depth;

		memset (buffer_0_ptr, ' ', 16);
		for (level = 0; level < depth - 1; level ++)
		{
			if (RED_object_ptr [current_tree_stack_ptr [level]]->brother.number >= 0)
			{
				buffer_0_ptr [level << 1] = '³';		/* 179 */
			}
			else
			{
				buffer_0_ptr [level << 1] = ' ';
			}
		}
		if (RED_object_ptr [current_tree_stack_ptr [depth - 1]]->brother.number >= 0)
		{
			buffer_0_ptr [(depth << 1) - 2] = 'Ã';	/* 195 */
		}
		else
		{
			buffer_0_ptr [(depth << 1) - 2] = 'À';	/* 192 */
		}
		if (   hide_flag != false
			 && (object_ptr->attributes & RSC_ATTR_HIDECHILD) != 0)
		{
			buffer_0_ptr [(depth << 1) - 1] = '+';
		}
		else
		{
			buffer_0_ptr [(depth << 1) - 1] = 'Ä';		/* 196 */
		}
		buffer_0_ptr [depth << 1] = 0;

		/* 0/32: name */
		strcat (buffer_0_ptr, RED_name_ptr_0 [object_nbr]);
		RED_complete_string (buffer_0_ptr, 32);
		/* 32/8: id */
		strcpy (buffer_0_ptr + 32, RED_id_ptr_0 [object_nbr]);
		RED_complete_string (buffer_0_ptr + 32, 8);
		/* 40/10: type */
		RED_get_type_name (buffer_0_ptr + 40, object_ptr->primitive);
		RED_complete_string (buffer_0_ptr + 40, 10);
		/* 50/8: char_x */
		sprintf (buffer_0_ptr + 50, "%+7.2f", (double) (object_ptr->x*100/RSC_CHAR_W) / 100);
		RED_complete_string (buffer_0_ptr + 50, 8);
		/* 58/8: char_y */
		sprintf (buffer_0_ptr + 58, "%+7.2f", (double) (object_ptr->y*100/RSC_CHAR_H) / 100);
		RED_complete_string (buffer_0_ptr + 58, 8);
		/* 66/6: pix_x */
		sprintf (buffer_0_ptr + 66, "%+4d", object_ptr->x);
		RED_complete_string (buffer_0_ptr + 66, 6);
		/* 72/4: pix_y */
		sprintf (buffer_0_ptr + 72, "%+4d", object_ptr->y);
		RED_complete_string (buffer_0_ptr + 72, 4);

		nbr_lines ++;

		/* On recherche le prochain objet de l'arborescence */
		rec_state = 0;
		while (rec_state != 2)
		{
			object_nbr = object_ptr->child.number;
			if (   object_nbr >= 0
				 && rec_state == 0
				 && (   (object_ptr->attributes & RSC_ATTR_HIDECHILD) == 0
					  || hide_flag == false))
			{
				current_tree_stack_ptr [depth] = object_nbr;
				depth ++;
				rec_state = 2;
			}
			else
			{
				object_nbr = object_ptr->brother.number;
				if (object_nbr >= 0)
				{
					current_tree_stack_ptr [depth - 1] = object_nbr;
					rec_state = 2;
				}
				else
				{
					depth --;
					if (depth <= 0)
					{
						break;
					}
					object_nbr = current_tree_stack_ptr [depth - 1];
					rec_state = 1;
				}
			}
			object_ptr = RED_object_ptr [object_nbr];
		}
	}
	RED_line_0_ptr_ptr [nbr_lines] = NULL;

	return (0);
}



void	RED_get_type_name (char *text_0, int type)
{
	switch (type)
	{
	case	RSC_OBJECT_NUMBER_NULL:
		strcpy (text_0, "Null");
		break;
	case	RSC_OBJECT_NUMBER_POINT:
		strcpy (text_0, "Point");
		break;
	case	RSC_OBJECT_NUMBER_HLINE:
		strcpy (text_0, "HLine");
		break;
	case	RSC_OBJECT_NUMBER_VLINE:
		strcpy (text_0, "VLine");
		break;
	case	RSC_OBJECT_NUMBER_BOX:
		strcpy (text_0, "Box");
		break;
	case	RSC_OBJECT_NUMBER_XORBOX:
		strcpy (text_0, "XorBox");
		break;
	case	RSC_OBJECT_NUMBER_BITMAP:
		strcpy (text_0, "Bitmap");
		break;
	case	RSC_OBJECT_NUMBER_TBITMAP:
		strcpy (text_0, "TBitmap");
		break;
	case	RSC_OBJECT_NUMBER_TEXT:
		strcpy (text_0, "Text");
		break;
	case	RSC_OBJECT_NUMBER_TTEXT:
		strcpy (text_0, "TText");
		break;
	case	RSC_OBJECT_NUMBER_INTBOX:
		strcpy (text_0, "IntBox");
		break;
	case	RSC_OBJECT_NUMBER_EXTBOX:
		strcpy (text_0, "ExtBox");
		break;
	case	RSC_OBJECT_NUMBER_BOXTEXT:
		strcpy (text_0, "BoxText");
		break;
	case	RSC_OBJECT_NUMBER_EDBOXTEXT:
		strcpy (text_0, "EdBoxText");
		break;
	case	RSC_OBJECT_NUMBER_BUTTON:
		strcpy (text_0, "Button");
		break;
	default:
		strcpy (text_0, "???");
		break;
	}
}



void	RED_complete_string (char *text_0, int nbr)
{
	const int		length = int (strlen (text_0));
	if (length < nbr)
	{
		memset (text_0 + length, ' ', nbr - length);
	}
	text_0 [nbr] = 0;
}



int	RED_get_nbr_childs (signed int object)
{
	int		nbr_childs;

	nbr_childs = 0;
	object = RED_object_ptr [object]->child.number;
	while (object > -1)
	{
		nbr_childs ++;
		object = RED_object_ptr [object]->brother.number;
	}

	return (nbr_childs);
}



/* Renvoie sous la forme nom\nom\...\nom si name_flag a true,
	sous la forme RSC_OBJ_id_id_..._id_nom si name_flag a false */
void	RED_get_object_full_name (char *object_full_name_0, int tree_stack [RED_MAX_DEPTH], int tree_depth, bool name_flag)
{
	int		depth;

	if (name_flag)
	{
		*object_full_name_0 = 0;
	}
	else
	{
		strcpy (object_full_name_0, "RSC_OBJ");
	}
	for (depth = 0; depth < tree_depth; depth ++)
	{
		if (name_flag)
		{
			strcat (object_full_name_0, "\\");
		}
		else
		{
			strcat (object_full_name_0, "_");
		}
		if (depth == tree_depth - 1 || name_flag)
		{
			strcat (object_full_name_0, RED_name_ptr_0 [tree_stack [depth]]);
		}
		else
		{
			strcat (object_full_name_0, RED_id_ptr_0 [tree_stack [depth]]);
		}
	}
}



void	RED_menu_load_rsc (void)
{
	char		filename_0 [8+1];
	char		full_filename_0 [2047+1];

	OS_clear_screen ();
	OS_print_at (1, 1, "Load resource file");
	OS_print_at (1, 3, "Enter filename (without extension, path and disk):");
	OS_locate (1, 4);
	RED_input_string (filename_0, 8);
	strcpy (full_filename_0, RED_relative_resource_pathname_0);
	strcat (full_filename_0, filename_0);
	if (RED_alert ("Load file ? (Y/N)", 'Y', 'N'))
	{
		RED_load_data_file (full_filename_0);
	}
}



void	RED_menu_save_rsc (void)
{
	char		filename_0 [8+1];
	char		full_filename_0 [2047+1];

	OS_clear_screen ();
	OS_print_at (1, 1, "Save resource file");
	OS_print_at (1, 3, "Enter filename (without extension, path and disk):");
	OS_locate (1, 4);
	RED_input_string (filename_0, 8);
	strcpy (full_filename_0, RED_relative_resource_pathname_0);
	strcat (full_filename_0, filename_0);
	if (RED_alert ("Save file ? (Y/N)", 'Y', 'N'))
	{
		RED_save_data_file (full_filename_0);
	}
}



int	RED_get_free_object_number (void)
{
	int		object;

	for (object = 0; object <= RED_nbr_objects; object ++)
	{
		if (RED_object_ptr [object] == NULL)
		{
			break;
		}
	}

	return (object);
}



void	*RED_get_object_zone_end (void)
{
	int		object;
	BYTE		*object_max_ptr;
	RSC_OBJTYPE_HEADER	*current_object_ptr;
	int		current_object_type;
	LWORD		current_object_len;

	object_max_ptr = (BYTE *) RED_object_zone_ptr;
	for (object = 0; object < RED_nbr_objects; object ++)
	{
		current_object_ptr = RED_object_ptr [object];
		if (current_object_ptr != NULL)
		{
			current_object_type = current_object_ptr->primitive;
			current_object_len = RED_get_object_len (current_object_type);
			if (  (BYTE *) current_object_ptr + current_object_len
			    - (BYTE *) object_max_ptr > 0)
			{
				object_max_ptr = (BYTE *)current_object_ptr + current_object_len;
			}
		}
	}

	return (object_max_ptr);
}



LWORD	RED_get_object_len (int object_type)
{
	LWORD		object_len;

	switch (object_type)
	{
	case	RSC_OBJECT_NUMBER_NULL:
		object_len = sizeof (RSC_OBJTYPE_NULL);
		break;
	case	RSC_OBJECT_NUMBER_POINT:
		object_len = sizeof (RSC_OBJTYPE_POINT);
		break;
	case	RSC_OBJECT_NUMBER_HLINE:
		object_len = sizeof (RSC_OBJTYPE_HLINE);
		break;
	case	RSC_OBJECT_NUMBER_VLINE:
		object_len = sizeof (RSC_OBJTYPE_VLINE);
		break;
	case	RSC_OBJECT_NUMBER_BOX:
		object_len = sizeof (RSC_OBJTYPE_BOX);
		break;
	case	RSC_OBJECT_NUMBER_XORBOX:
		object_len = sizeof (RSC_OBJTYPE_XORBOX);
		break;
	case	RSC_OBJECT_NUMBER_BITMAP:
		object_len = sizeof (RSC_OBJTYPE_BITMAP);
		break;
	case	RSC_OBJECT_NUMBER_TBITMAP:
		object_len = sizeof (RSC_OBJTYPE_TBITMAP);
		break;
	case	RSC_OBJECT_NUMBER_TEXT:
		object_len = sizeof (RSC_OBJTYPE_TEXT);
		break;
	case	RSC_OBJECT_NUMBER_TTEXT:
		object_len = sizeof (RSC_OBJTYPE_TTEXT);
		break;
	case	RSC_OBJECT_NUMBER_INTBOX:
		object_len = sizeof (RSC_OBJTYPE_INTBOX);
		break;
	case	RSC_OBJECT_NUMBER_EXTBOX:
		object_len = sizeof (RSC_OBJTYPE_EXTBOX);
		break;
	case	RSC_OBJECT_NUMBER_BOXTEXT:
		object_len = sizeof (RSC_OBJTYPE_BOXTEXT);
		break;
	case	RSC_OBJECT_NUMBER_EDBOXTEXT:
		object_len = sizeof (RSC_OBJTYPE_EDBOXTEXT);
		break;
	case	RSC_OBJECT_NUMBER_BUTTON:
		object_len = sizeof (RSC_OBJTYPE_BUTTON);
		break;
	default:
		object_len = 0;
		break;
	}

	return (object_len);
}



int	RED_create_new_object (int object_type, int object_attributes,
									  int object_child, int object_brother,
									  int object_x, int object_y)
{
	int		object_number;
	RSC_OBJTYPE_HEADER	*object_ptr;

	object_number = RED_get_free_object_number ();
	object_ptr = (RSC_OBJTYPE_HEADER *) RED_get_object_zone_end ();
	object_ptr->primitive = object_type;
	object_ptr->attributes = object_attributes;
	object_ptr->child.number = object_child;
	object_ptr->brother.number = object_brother;
	object_ptr->x = object_x;
	object_ptr->y = object_y;
	RED_object_ptr [object_number] = object_ptr;
	if (object_number >= RED_nbr_objects)
	{
		RED_nbr_objects ++;
	}

	RED_init_object (object_ptr);

	return (object_number);
}



int	RED_count_total_object_number (void)
{
	int		nbr;
	int		object;

	nbr = 0;
	for (object = 0; object < RED_nbr_objects; object ++)
	{
		if (RED_object_ptr [object] != NULL)
		{
			nbr ++;
		}
	}

	return (nbr);
}



int	RED_count_total_number_of_pics (void)
{
	int		nbr;
	int		pic;

	nbr = 0;
	for (pic = 0; pic < RED_nbr_pics; pic ++)
	{
		if (RED_pic_ptr [pic] != NULL)
		{
			nbr ++;
		}
	}

	return (nbr);
}



int	RED_select_object_type (void)
{
	const int	type_number_ptr [] =
		{
			RSC_OBJECT_NUMBER_NULL,
			RSC_OBJECT_NUMBER_POINT,
			RSC_OBJECT_NUMBER_HLINE,
			RSC_OBJECT_NUMBER_VLINE,
			RSC_OBJECT_NUMBER_BOX,
			RSC_OBJECT_NUMBER_XORBOX,
			RSC_OBJECT_NUMBER_BITMAP,
			RSC_OBJECT_NUMBER_TBITMAP,
			RSC_OBJECT_NUMBER_TEXT,
			RSC_OBJECT_NUMBER_TTEXT,

			RSC_OBJECT_NUMBER_INTBOX,
			RSC_OBJECT_NUMBER_EXTBOX,
			RSC_OBJECT_NUMBER_BOXTEXT,
			RSC_OBJECT_NUMBER_EDBOXTEXT,
			RSC_OBJECT_NUMBER_BUTTON
		};
	const char	*type_name_ptr [] =
		{
			"Null",
			"Point",
			"Horizontal line",
			"Vertical line",
			"Box",
			"XOR-Box",
			"Bitmap",
			"Transparent Bitmap",
			"Text",
			"Transparent text",
			"Box with inside borders",
			"Box with outside borders",
			"Boxtext",
			"Editable boxtext",
			"Button",
			""
		};
	int		ret_pos;

	ret_pos = 0;
	RED_select_item (type_name_ptr, &ret_pos, 1, 3, OS_NBR_LINES-4, 48);

	return (type_number_ptr [ret_pos]);
}



/* La fin de la liste est obtenue avec un pointeur nul ou une chaine nulle */
int	RED_select_item (const char **item_name_ptr, int *ret_pos,
							  int x_pos, int y_pos, int nbr_lines, int nbr_columns)
{
	char		line_0 [OS_NBR_COLUMNS + 2];
	char		space_0 [OS_NBR_COLUMNS + 2];
	int		liste_len;
	bool		redraw_flag;
	signed int	page_index;
	signed int	cursor_pos;
	bool		exit_flag;
	int		key;
	int		line;
	int		line_len;

	memset (space_0, ' ', nbr_columns);
	space_0 [nbr_columns] = 0;
	liste_len = 0;
	while (item_name_ptr [liste_len] != NULL)
	{
		if (item_name_ptr [liste_len] [0] == 0)
		{
			break;
		}
		liste_len ++;
	}

	redraw_flag = true;
	exit_flag = false;
	cursor_pos = std::max (std::min (*ret_pos, liste_len - 1), 0);
	page_index = 0;
	if (cursor_pos >= nbr_lines)
	{
		page_index = cursor_pos - (nbr_lines >> 1);
		page_index = std::max (std::min (page_index, liste_len - nbr_lines), 0);
	}
	RED_clear_keyboard_buffer ();

	while (!exit_flag)
	{
		if (redraw_flag)
		{
			for (line = 0; line < nbr_lines; line ++)
			{
				if (page_index + line < liste_len)
				{
					strcpy (line_0, item_name_ptr [page_index + line]);
					line_len = int (strlen (line_0));
					memset (line_0 + line_len, ' ', std::max (nbr_columns - line_len, 1));
					line_0 [nbr_columns] = 0;
					OS_print_at (x_pos + 2, y_pos + line, line_0);
				}
				else
				{
					OS_print_at (x_pos + 2, y_pos + line, space_0);
				}
			}
			redraw_flag = false;
		}
		OS_print_at (x_pos, y_pos + cursor_pos - page_index, ">");

		key = OS_get_key ();
		OS_print_at (x_pos, y_pos + cursor_pos - page_index, " ");
		switch (key)
		{
		case	1:		/* Esc */
		case	2:		/* Enter */
			exit_flag = true;
			break;
		case	3: 	/* Up */
			cursor_pos --;
			break;
		case	4:		/* Down */
			cursor_pos ++;
			break;
		default:
			if (RED_selitem_superexit_flag)
			{
				exit_flag = true;
			}
			break;
		}
		while (cursor_pos < 0)
		{
			cursor_pos += liste_len;
		}
		while (cursor_pos >= liste_len)
		{
			cursor_pos -= liste_len;
		}
		if (cursor_pos < page_index)
		{
			page_index = cursor_pos;
			redraw_flag = true;
		}
		else if (cursor_pos >= page_index + nbr_lines)
		{
			page_index = cursor_pos - nbr_lines + 1;
			page_index = std::max (page_index, 0);
			redraw_flag = true;
		}
	}

	*ret_pos = cursor_pos;
	return (key);
}



int	RED_input_string (char *buffer_0, int max_len)
{
	int		string_len;
	char		character;
	bool		buffer_flag;

	RED_clear_keyboard_buffer ();
	buffer_flag = true;
	for (string_len = 0; string_len < max_len; string_len ++)
	{
		character = getchar ();
		if (character == '\n')
		{
			buffer_0 [string_len] = 0;
			buffer_flag = false;
			break;
		}
		else if (character == '\b')
		{
			if (string_len > 0)
			{
				string_len -= 2;
			}
		}
		else
		{
			buffer_0 [string_len] = character;
		}
	}
	buffer_0 [string_len] = 0;
	if (buffer_flag)
	{
		while (getchar () != '\n')
		{
		}
	}

	return (string_len);
}



/* Premier appel avec brother_flag = false */
void	RED_delete_subtree (int object, bool brother_flag)
{
	int		object_type;
	int		child;
	int		brother;
	RSC_OBJTYPE_HEADER  	*object_ptr;
	LWORD		object_len;
	int		obj2;

	if (object == -1)
	{
		return;
	}
	if (RED_object_ptr [object] == NULL)
	{
		return;
	}
	object_type = RED_object_ptr [object]->primitive;
	child = RED_object_ptr [object]->child.number;
	brother = RED_object_ptr [object]->brother.number;
	RED_delete_subtree (child, true);
	if (brother_flag)
	{
		RED_delete_subtree (brother, true);
		brother = -1;
	}

	/* Les objets sont maintenant fixes, on peut recuperer l'adresse */
	object_ptr = RED_object_ptr [object];

	/* Destruction des chaines attachees */
	switch (object_type)
	{
	case	RSC_OBJECT_NUMBER_TEXT:
		free (((RSC_OBJTYPE_TEXT *) object_ptr)->text_0);
		((RSC_OBJTYPE_TEXT *) object_ptr)->text_0 = NULL;
		break;
	case	RSC_OBJECT_NUMBER_TTEXT:
		free (((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0);
		((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0 = NULL;
		break;
	case	RSC_OBJECT_NUMBER_BOXTEXT:
		free (((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0);
		((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0 = NULL;
		break;
	case	RSC_OBJECT_NUMBER_EDBOXTEXT:
		free (((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0);
		((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0 = NULL;
		break;
	}

	object_len = RED_get_object_len (object_type);
	memmove (object_ptr, (BYTE *)object_ptr + object_len,
				(BYTE *)RED_get_object_zone_end () - (BYTE *)object_ptr);
	if (object + 1 >= RED_nbr_objects)
	{
		RED_nbr_objects --;
	}
	for (obj2 = 0; obj2 < RED_nbr_objects; obj2 ++)
	{
		if (RED_object_ptr [obj2] - object_ptr > 0)
		{
			RED_object_ptr [obj2] = (RSC_OBJTYPE_HEADER *) ((BYTE *) RED_object_ptr [obj2] - object_len);
		}
	}

	RED_object_ptr [object] = NULL;

	/* Remplace les liens sur cet objet avec
		la reference du frere (mort ou vif). */
	for (obj2 = 0; obj2 < RED_nbr_objects; obj2 ++)
	{
		object_ptr = RED_object_ptr [obj2];
		if (object_ptr != NULL)
		{
			if (object_ptr->brother.number == object)
			{
				object_ptr->brother.number = brother;
			}
			if (object_ptr->child.number == object)
			{
				object_ptr->child.number = brother;
			}
		}
	}

	/* Destruction des images attachees */
	switch (object_type)
	{
	case	RSC_OBJECT_NUMBER_BITMAP:
	case	RSC_OBJECT_NUMBER_TBITMAP:
	case	RSC_OBJECT_NUMBER_BUTTON:
		RED_remove_unused_picnames ();
		break;
	}
}



void	RED_modify_string (char *&base_0, char *text_0)
{
	if (base_0 != NULL)
	{
		free (base_0);
		base_0 = NULL;
	}

	base_0 = STRDUP (text_0);
}



int	RED_insert_picname (char *text_0)
{
	int		pic_nbr;

	if (text_0 == NULL)
	{
		return (-1);
	}

	if (strlen (text_0) == 0)
	{
		return (-1);
	}
	
	/* On regarde d'abord si le nom existe deja */
	for (pic_nbr = 0; pic_nbr < RED_nbr_pics; pic_nbr ++)
	{
		if (RED_pic_ptr [pic_nbr] != NULL)
		{
			if (strcmp (text_0, RED_pic_ptr [pic_nbr]) == 0)
			{
				return (pic_nbr);
			}
		}
	}

	/* Insere le nouveau nom */
	pic_nbr = RED_get_free_pic_number ();
	if (pic_nbr >= RED_nbr_pics)
	{
		RED_nbr_pics = pic_nbr + 1;
	}
	
	RED_pic_ptr [pic_nbr] = STRDUP (text_0);

	return (pic_nbr);
}



void	RED_delete_picname (int pic_nbr)
{
	free (RED_pic_ptr [pic_nbr]);
	RED_pic_ptr [pic_nbr] = NULL;

	/* Change le nombre de noms */
	if (pic_nbr >= RED_nbr_pics - 1)
	{
		while (RED_pic_ptr [RED_nbr_pics - 1] == NULL)
		{
			RED_nbr_pics --;
			if (RED_nbr_pics <= 0)
			{
				break;
			}
		}
	}
}



int	RED_get_free_pic_number (void)
{
	int		pic_nbr;

	for (pic_nbr = 0; pic_nbr < RED_nbr_pics; pic_nbr ++)
	{
		if (RED_pic_ptr [pic_nbr] == NULL)
		{
			break;
		}
	}

	return (pic_nbr);
}



void	RED_remove_unused_picnames (void)
{
	int		pic_nbr;
	int		object;
	int		img;
	bool		found_flag;
	RSC_OBJTYPE_BUTTON	*button_ptr;
	RSC_OBJTYPE_BITMAP	*bitmap_ptr;
	RSC_OBJTYPE_TBITMAP	*tbitmap_ptr;

	/* Verifie le type de chaque icone, et vire les
	   numeros d'image si necessaire */
	for (object = 0; object < RED_nbr_objects; object ++)
	{
		if (RED_object_ptr [object] == NULL)
		{
			continue;
		}

		if (RED_object_ptr [object]->primitive == RSC_OBJECT_NUMBER_BUTTON)
		{
			button_ptr = (RSC_OBJTYPE_BUTTON *) (RED_object_ptr [object]);
			if (   button_ptr->t == RSC_BUTTON_T_UARROW
			    || button_ptr->t == RSC_BUTTON_T_DARROW
			    || button_ptr->t == RSC_BUTTON_T_LARROW
			    || button_ptr->t == RSC_BUTTON_T_RARROW)
			{
				button_ptr->img [0] = -1;
				button_ptr->img [1] = -1;
				button_ptr->img [2] = -1;
			}
		}
	}

	/* Elimine les noms dont on n'a pas besoin */
	for (pic_nbr = 0; pic_nbr < RED_nbr_pics; pic_nbr ++)
	{
		if (RED_pic_ptr [pic_nbr] == NULL)
		{
			continue;
		}

		found_flag = false;

		for (object = 0; object < RED_nbr_objects; object ++)
		{
			if (RED_object_ptr [object] == NULL)
			{
				continue;
			}

			if (RED_object_ptr [object]->primitive == RSC_OBJECT_NUMBER_BUTTON)
			{
				button_ptr = (RSC_OBJTYPE_BUTTON *) (RED_object_ptr [object]);
				if (   button_ptr->t != RSC_BUTTON_T_UARROW
				    && button_ptr->t != RSC_BUTTON_T_DARROW
				    && button_ptr->t != RSC_BUTTON_T_LARROW
				    && button_ptr->t != RSC_BUTTON_T_RARROW)
				{
					for (img = 0; img < 3; img ++)
					{
						if (button_ptr->img [img] == pic_nbr)
						{
							found_flag = true;
							break;
						}
					}
				}
			}

			else if (RED_object_ptr [object]->primitive == RSC_OBJECT_NUMBER_BITMAP)
			{
				bitmap_ptr = (RSC_OBJTYPE_BITMAP *) (RED_object_ptr [object]);
				for (img = 0; img < 3; img ++)
				{
					if (bitmap_ptr->img [img] == pic_nbr)
					{
						found_flag = true;
						break;
					}
				}
			}
			
			else if (RED_object_ptr [object]->primitive == RSC_OBJECT_NUMBER_TBITMAP)
			{
				tbitmap_ptr = (RSC_OBJTYPE_TBITMAP *) (RED_object_ptr [object]);
				for (img = 0; img < 3; img ++)
				{
					if (tbitmap_ptr->img [img] == pic_nbr)
					{
						found_flag = true;
						break;
					}
				}
			}

			if (found_flag)
			{
				break;
			}
		}

		if (! found_flag)
		{
			RED_delete_picname (pic_nbr);
		}
	}
}



int	RED_save_data_file (char *filename_0)
{
	char		filename2_0 [255+1];
	FILE		*file_ptr;
	RSC_OBJTYPE_HEADER	*object_ptr;
	int		object;
	const char	*text_0;
	int		level;
	int		label;
	int		img;
	int		pic;
	int		line_length;
	long		total_string_length;
	long		total_object_length;

/*______________________________________________
 *
 * Fichier de donnees des objets
 *______________________________________________
 */

	/* Ouverture */
	strcpy (filename2_0, filename_0);
	strcat (filename2_0, ".rsc");
	file_ptr = fopen (filename2_0, "wb");
	if (file_ptr == NULL)
	{
		RED_alert ("Cannot open .rsc file. Press <Return>.", 0x01, 0x02);
		return (-1);
	}

	/* Ecriture */
	fprintf (file_ptr, "%s\n", "GRAOUMF_TRACKER_resource_file");

	/* Objets */
	total_string_length = 0;
	total_object_length = 0;
	for (object = 0; object < RED_nbr_objects; object ++)
	{
		object_ptr = RED_object_ptr [object];
		if (object_ptr != NULL)
		{
			fprintf (file_ptr, "Object %d\n", object);

			text_0 = RED_name_ptr_0 [object];
			fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
			fprintf (file_ptr, "%s\n", RED_id_ptr_0 [object]);
			fprintf (file_ptr, "%d %ld %d %d %d %d\n",
						object_ptr->primitive,
						object_ptr->attributes,
						object_ptr->child,
						object_ptr->brother,
						object_ptr->x,
						object_ptr->y);
			total_object_length += RED_get_object_len (object_ptr->primitive);

			switch (object_ptr->primitive)
			{
			case	RSC_OBJECT_NUMBER_NULL:
				break;

			case	RSC_OBJECT_NUMBER_POINT:
				fprintf (file_ptr, "%d\n",
							((RSC_OBJTYPE_POINT *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_HLINE:
				fprintf (file_ptr, "%d %d\n",
							((RSC_OBJTYPE_HLINE *) object_ptr)->l,
							((RSC_OBJTYPE_HLINE *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_VLINE:
				fprintf (file_ptr, "%d %d\n",
							((RSC_OBJTYPE_VLINE *) object_ptr)->h,
							((RSC_OBJTYPE_VLINE *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_BOX:
				fprintf (file_ptr, "%d %d %d\n",
							((RSC_OBJTYPE_BOX *) object_ptr)->l,
							((RSC_OBJTYPE_BOX *) object_ptr)->h,
							((RSC_OBJTYPE_BOX *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_XORBOX:
				fprintf (file_ptr, "%d %d %d\n",
							((RSC_OBJTYPE_XORBOX *) object_ptr)->l,
							((RSC_OBJTYPE_XORBOX *) object_ptr)->h,
							((RSC_OBJTYPE_XORBOX *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_BITMAP:
				for (img = 0; img < 3; img ++)
				{
					pic = ((RSC_OBJTYPE_BITMAP *) object_ptr)->img [img];
					if (pic >= 0)
					{
						text_0 = RED_pic_ptr [pic];
					}
					else
					{
						text_0 = "";
					}
					fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				}
				break;

			case	RSC_OBJECT_NUMBER_TBITMAP:
				for (img = 0; img < 3; img ++)
				{
					pic = ((RSC_OBJTYPE_TBITMAP *) object_ptr)->img [img];
					if (pic >= 0)
					{
						text_0 = RED_pic_ptr [pic];
					}
					else
					{
						text_0 = "";
					}
					fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				}
				break;

			case	RSC_OBJECT_NUMBER_TEXT:
				fprintf (file_ptr, "%d\n",
							((RSC_OBJTYPE_TEXT *) object_ptr)->c);
				text_0 = ((RSC_OBJTYPE_TEXT *) object_ptr)->text_0;
				fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				total_string_length += long (strlen (text_0)) + 1;
				break;

			case	RSC_OBJECT_NUMBER_TTEXT:
				fprintf (file_ptr, "%d\n",
							((RSC_OBJTYPE_TTEXT *) object_ptr)->c);
				text_0 = ((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0;
				fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				total_string_length += long (strlen (text_0)) + 1;
				break;

			case	RSC_OBJECT_NUMBER_INTBOX:
				fprintf (file_ptr, "%d %d %d\n",
							((RSC_OBJTYPE_INTBOX *) object_ptr)->l,
							((RSC_OBJTYPE_INTBOX *) object_ptr)->h,
							((RSC_OBJTYPE_INTBOX *) object_ptr)->t);
				break;

			case	RSC_OBJECT_NUMBER_EXTBOX:
				fprintf (file_ptr, "%d %d %d\n",
							((RSC_OBJTYPE_EXTBOX *) object_ptr)->l,
							((RSC_OBJTYPE_EXTBOX *) object_ptr)->h,
							((RSC_OBJTYPE_EXTBOX *) object_ptr)->t);
				break;

			case	RSC_OBJECT_NUMBER_BOXTEXT:
				fprintf (file_ptr, "%d %d %d %d\n",
							((RSC_OBJTYPE_BOXTEXT *) object_ptr)->l,
							((RSC_OBJTYPE_BOXTEXT *) object_ptr)->h,
							((RSC_OBJTYPE_BOXTEXT *) object_ptr)->t,
							((RSC_OBJTYPE_BOXTEXT *) object_ptr)->j);
				text_0 = ((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0;
				fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				total_string_length += long (strlen (text_0)) + 1;
				break;

			case	RSC_OBJECT_NUMBER_EDBOXTEXT:
				fprintf (file_ptr, "%d %d \n",
							((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->l,
							((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->t);
				text_0 = ((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0;
				fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				total_string_length += long (strlen (text_0)) + 1;
				break;

			case	RSC_OBJECT_NUMBER_BUTTON:
				fprintf (file_ptr, "%d %d\n",
							((RSC_OBJTYPE_BUTTON *) object_ptr)->t,
							((RSC_OBJTYPE_BUTTON *) object_ptr)->t2);
				for (img = 0; img < 3; img ++)
				{
					pic = ((RSC_OBJTYPE_BUTTON *) object_ptr)->img [img];
					if (pic >= 0)
					{
						text_0 = RED_pic_ptr [pic];
					}
					else
					{
						text_0 = "";
					}
					fprintf (file_ptr, "%d \"%s\"\n", strlen (text_0), text_0);
				}
				break;

			default:
				break;
			}

			if (ferror (file_ptr))
			{
				RED_alert ("Write error. Press <Return>.", 0x01, 0x02);
				fclose (file_ptr);
				return (-2);
			}
		}
	}

	/* Fin du fichier */
	fprintf (file_ptr, "END_OF_FILE 0\n");

	/* Fermeture */
	fclose (file_ptr);

/*______________________________________________
 *
 * Fichier .H
 *______________________________________________
 */

	/* Ouverture */
	strcpy (filename2_0, filename_0);
	strcat (filename2_0, ".h");
	file_ptr = fopen (filename2_0, "wb");
	if (file_ptr == NULL)
	{
		RED_alert ("Cannot open .h file. Press <Return>.", 0x01, 0x02);
		return (-1);
	}

	/* Informations diverses */
	fprintf (file_ptr, "#define\tRSC_NBROBJECTS_MAXI\t\t%d\n", RED_nbr_objects);
	fprintf (file_ptr, "#define\tRSC_NBRPICTURES_MAXI\t\t%d\n", RED_nbr_pics);
	fprintf (file_ptr, "#define\tRSC_OBJECT_ZONE_LENGTH\t%Ld\n", total_object_length);

	/* Nom des objets */
	RED_build_ascii_tree (false);
	free (RED_line_0_ptr);
	label = 0;
	while (RED_line_0_ptr_ptr [label] != NULL)
	{
		fprintf (file_ptr, "%s", "#define\tRSC_OBJ");
		line_length = 16;		/* Longueur du texte ci-dessus avec Tab = 3 */
		for (level = 0; level < RED_tree_depth_ptr [label]; level++)
		{
			object = RED_tree_stack_ptr [label] [level];
			fprintf (file_ptr, "_%s", RED_id_ptr_0 [object]);
			line_length += int (strlen (RED_id_ptr_0 [object]) + 1);
		}
		line_length = (line_length / 3) * 3;
		do
		{
			fprintf (file_ptr, "\t");
			line_length += 3;
		}
		while (line_length < 33);
		fprintf (file_ptr, "%d\n", object);
		label ++;
	}
	free (RED_line_0_ptr_ptr);
	free (RED_tree_stack_ptr);
	free (RED_tree_depth_ptr);

	/* Fermeture */
	fclose (file_ptr);

	return (0);
}



int	RED_load_data_file (char *filename_0)
{
	char		filename2_0 [255+1];
	FILE		*file_ptr;
	RSC_OBJTYPE_HEADER	*object_ptr;
	int		parameter;
	int		object;
	int		pic;
	char		buffer_0 [1023+1];

	/* Ouverture */
	strcpy (filename2_0, filename_0);
	strcat (filename2_0, ".rsc");
	file_ptr = fopen (filename2_0, "rb");
	if (file_ptr == NULL)
	{
		RED_alert ("Cannot open file. Press <Return>.", 0x01, 0x02);
		return (-1);
	}

	/* Lecture */
	fscanf (file_ptr, "%s\n", buffer_0);
	if (strcmp (buffer_0, "GRAOUMF_TRACKER_resource_file") != 0)
	{
		RED_alert ("Not a GRAOUMF TRACKER resource file. Press <Return>.", 0x01, 0x02);
		fclose (file_ptr);
		return (-2);
	}

	RED_memory_clear ();
	object_ptr = (RSC_OBJTYPE_HEADER *) RED_object_zone_ptr;
	for (;;)
	{
		fscanf (file_ptr, "%s %d\n", buffer_0, &parameter);

		/* Objets */
		if (strcmp (buffer_0, "Object") == 0)
		{
			object = parameter;
			RED_object_ptr [object] = object_ptr;
			RED_read_string_in_file (buffer_0, file_ptr);
			strcpy (RED_name_ptr_0 [object], buffer_0);
			fscanf (file_ptr, "%s\n", RED_id_ptr_0 [object]);
			fscanf (file_ptr, "%d %ld %d %d %d %d\n",
						&object_ptr->primitive,
						&object_ptr->attributes,
						&object_ptr->child,
						&object_ptr->brother,
						&object_ptr->x,
						&object_ptr->y);

			switch (object_ptr->primitive)
			{
			case	RSC_OBJECT_NUMBER_NULL:
				break;

			case	RSC_OBJECT_NUMBER_POINT:
				fscanf (file_ptr, "%d\n",
						  &((RSC_OBJTYPE_POINT *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_HLINE:
				fscanf (file_ptr, "%d %d\n",
						  &((RSC_OBJTYPE_HLINE *) object_ptr)->l,
						  &((RSC_OBJTYPE_HLINE *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_VLINE:
				fscanf (file_ptr, "%d %d\n",
						  &((RSC_OBJTYPE_VLINE *) object_ptr)->h,
						  &((RSC_OBJTYPE_VLINE *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_BOX:
				fscanf (file_ptr, "%d %d %d\n",
						  &((RSC_OBJTYPE_BOX *) object_ptr)->l,
						  &((RSC_OBJTYPE_BOX *) object_ptr)->h,
						  &((RSC_OBJTYPE_BOX *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_XORBOX:
				fscanf (file_ptr, "%d %d %d\n",
						  &((RSC_OBJTYPE_XORBOX *) object_ptr)->l,
						  &((RSC_OBJTYPE_XORBOX *) object_ptr)->h,
						  &((RSC_OBJTYPE_XORBOX *) object_ptr)->c);
				break;

			case	RSC_OBJECT_NUMBER_BITMAP:
				for (pic = 0; pic < 3; pic ++)
				{
					RED_read_string_in_file (buffer_0, file_ptr);
					((RSC_OBJTYPE_BITMAP *) object_ptr)->img [pic] = RED_insert_picname (buffer_0);
				}
				break;

			case	RSC_OBJECT_NUMBER_TBITMAP:
				for (pic = 0; pic < 3; pic ++)
				{
					RED_read_string_in_file (buffer_0, file_ptr);
					((RSC_OBJTYPE_TBITMAP *) object_ptr)->img [pic] = RED_insert_picname (buffer_0);
				}
				break;

			case	RSC_OBJECT_NUMBER_TEXT:
				fscanf (file_ptr, "%d\n",
						  &((RSC_OBJTYPE_TEXT *) object_ptr)->c);
				RED_read_string_in_file (buffer_0, file_ptr);
				((RSC_OBJTYPE_TEXT *) object_ptr)->text_0 = _strdup (buffer_0);
				break;

			case	RSC_OBJECT_NUMBER_TTEXT:
				fscanf (file_ptr, "%d\n",
						  &((RSC_OBJTYPE_TTEXT *) object_ptr)->c);
				RED_read_string_in_file (buffer_0, file_ptr);
				((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0 = _strdup (buffer_0);
				break;

			case	RSC_OBJECT_NUMBER_INTBOX:
				fscanf (file_ptr, "%d %d %d\n",
						  &((RSC_OBJTYPE_INTBOX *) object_ptr)->l,
						  &((RSC_OBJTYPE_INTBOX *) object_ptr)->h,
						  &((RSC_OBJTYPE_INTBOX *) object_ptr)->t);
				break;

			case	RSC_OBJECT_NUMBER_EXTBOX:
				fscanf (file_ptr, "%d %d %d\n",
						  &((RSC_OBJTYPE_EXTBOX *) object_ptr)->l,
						  &((RSC_OBJTYPE_EXTBOX *) object_ptr)->h,
						  &((RSC_OBJTYPE_EXTBOX *) object_ptr)->t);
				break;

			case	RSC_OBJECT_NUMBER_BOXTEXT:
				fscanf (file_ptr, "%d %d %d %d\n",
						  &((RSC_OBJTYPE_BOXTEXT *) object_ptr)->l,
						  &((RSC_OBJTYPE_BOXTEXT *) object_ptr)->h,
						  &((RSC_OBJTYPE_BOXTEXT *) object_ptr)->t,
						  &((RSC_OBJTYPE_BOXTEXT *) object_ptr)->j);
				RED_read_string_in_file (buffer_0, file_ptr);
				((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0 = _strdup (buffer_0);
				break;

			case	RSC_OBJECT_NUMBER_EDBOXTEXT:
				fscanf (file_ptr, "%d %d\n",
						  &((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->l,
						  &((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->t);
				RED_read_string_in_file (buffer_0, file_ptr);
				((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0 = _strdup (buffer_0);
				break;

			case	RSC_OBJECT_NUMBER_BUTTON:
				fscanf (file_ptr, "%d %d\n",
						  &((RSC_OBJTYPE_BUTTON *) object_ptr)->t,
						  &((RSC_OBJTYPE_BUTTON *) object_ptr)->t2);
				for (pic = 0; pic < 3; pic ++)
				{
					RED_read_string_in_file (buffer_0, file_ptr);
					((RSC_OBJTYPE_BUTTON *) object_ptr)->img [pic] = RED_insert_picname (buffer_0);
				}
				break;

			default:
				break;
			}

			RED_nbr_objects = std::max (RED_nbr_objects, object + 1);
			object_ptr = (RSC_OBJTYPE_HEADER *) ((BYTE *)object_ptr + RED_get_object_len (object_ptr->primitive));
		}

		/* Fin du fichier */
		else if (strcmp (buffer_0, "END_OF_FILE") == 0)
		{
			break;
		}

		if (ferror (file_ptr))
		{
			RED_alert ("Load error. Press <Return>.", 0x01, 0x02);
			fclose (file_ptr);
			return (-2);
		}
	}

	/* Fermeture */
	fclose (file_ptr);

	return (0);
}



void	RED_read_string_in_file (char *buffer_0, FILE *file_ptr)
{
	int		string_len;
	signed int	char_cpt;
	char		c;

	fscanf (file_ptr, "%d ", &string_len);
	char_cpt = -1;
	while (char_cpt < string_len)
	{
		c = fgetc (file_ptr);
		if (char_cpt == -1)
		{
			if (c == '\"')
			{
				char_cpt = 0;
			}
		}
		else
		{
			buffer_0 [char_cpt] = c;
			char_cpt ++;
		}
	}
	fgetc (file_ptr);	/* Saute la deuxieme apostrophe */
	buffer_0 [char_cpt] = '\0';
}



void	RED_init_object (RSC_OBJTYPE_HEADER *object_ptr)
{
	switch (object_ptr->primitive)
	{
	case	RSC_OBJECT_NUMBER_NULL:
		break;
	case	RSC_OBJECT_NUMBER_POINT:
		((RSC_OBJTYPE_POINT *) object_ptr)->c = 9;
		break;
	case	RSC_OBJECT_NUMBER_HLINE:
		((RSC_OBJTYPE_HLINE *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_HLINE *) object_ptr)->c = 9;
		break;
	case	RSC_OBJECT_NUMBER_VLINE:
		((RSC_OBJTYPE_VLINE *) object_ptr)->h = RSC_CHAR_H;
		((RSC_OBJTYPE_VLINE *) object_ptr)->c = 9;
		break;
	case	RSC_OBJECT_NUMBER_BOX:
		((RSC_OBJTYPE_BOX *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_BOX *) object_ptr)->h = RSC_CHAR_H;
		((RSC_OBJTYPE_BOX *) object_ptr)->c = 9;
		break;
	case	RSC_OBJECT_NUMBER_XORBOX:
		((RSC_OBJTYPE_XORBOX *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_XORBOX *) object_ptr)->h = RSC_CHAR_H;
		((RSC_OBJTYPE_XORBOX *) object_ptr)->c = 9;
		break;
	case	RSC_OBJECT_NUMBER_BITMAP:
		((RSC_OBJTYPE_BITMAP *) object_ptr)->img [0] = -1;
		((RSC_OBJTYPE_BITMAP *) object_ptr)->img [1] = -1;
		((RSC_OBJTYPE_BITMAP *) object_ptr)->img [2] = -1;
		break;
	case	RSC_OBJECT_NUMBER_TBITMAP:
		((RSC_OBJTYPE_TBITMAP *) object_ptr)->img [0] = -1;
		((RSC_OBJTYPE_TBITMAP *) object_ptr)->img [1] = -1;
		((RSC_OBJTYPE_TBITMAP *) object_ptr)->img [2] = -1;
		break;
	case	RSC_OBJECT_NUMBER_TEXT:
		((RSC_OBJTYPE_TEXT *) object_ptr)->c = 1;
		((RSC_OBJTYPE_TEXT *) object_ptr)->text_0 = _strdup ("");
		break;
	case	RSC_OBJECT_NUMBER_TTEXT:
		((RSC_OBJTYPE_TTEXT *) object_ptr)->c = 10;
		((RSC_OBJTYPE_TTEXT *) object_ptr)->text_0 = _strdup ("");
		break;
	case	RSC_OBJECT_NUMBER_INTBOX:
		((RSC_OBJTYPE_INTBOX *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_INTBOX *) object_ptr)->h = RSC_CHAR_H;
		((RSC_OBJTYPE_INTBOX *) object_ptr)->t = RSC_INTBOX_T_GREY;
		break;
	case	RSC_OBJECT_NUMBER_EXTBOX:
		((RSC_OBJTYPE_EXTBOX *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_EXTBOX *) object_ptr)->h = RSC_CHAR_H;
		((RSC_OBJTYPE_EXTBOX *) object_ptr)->t = RSC_EXTBOX_T_BLACKG;
		break;
	case	RSC_OBJECT_NUMBER_BOXTEXT:
		((RSC_OBJTYPE_BOXTEXT *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_BOXTEXT *) object_ptr)->h = RSC_BOXTEXT_H;
		((RSC_OBJTYPE_BOXTEXT *) object_ptr)->t = RSC_BOXTEXT_T_GREY;
		((RSC_OBJTYPE_BOXTEXT *) object_ptr)->j = RSC_BOXTEXT_J_CENTER;
		((RSC_OBJTYPE_BOXTEXT *) object_ptr)->text_0 = _strdup ("");
		break;
	case	RSC_OBJECT_NUMBER_EDBOXTEXT:
		((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->l = RSC_CHAR_W;
		((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->t = RSC_EDBOXTEXT_T_GREY;
		((RSC_OBJTYPE_EDBOXTEXT *) object_ptr)->text_0 = _strdup ("");
		break;
	case	RSC_OBJECT_NUMBER_BUTTON:
		((RSC_OBJTYPE_BUTTON *) object_ptr)->t = RSC_BUTTON_T_UARROW;
		((RSC_OBJTYPE_BUTTON *) object_ptr)->t2 = RSC_BUTTON_T2_GREY;
		((RSC_OBJTYPE_BUTTON *) object_ptr)->img [0] = -1;
		((RSC_OBJTYPE_BUTTON *) object_ptr)->img [1] = -1;
		((RSC_OBJTYPE_BUTTON *) object_ptr)->img [2] = -1;
		break;
	}
}
