
#include "unit.h"

#ifndef PandaWave_RESOURCES
#include "RevengeResources.h"
#endif

#include "RevengeApp.h"
#include <XMessages.h>
#include "tagpick.h"
#include <assert.h>
#include <XPopup.h>
#include <XWindow.h>
#include "TBitmapView.h"


// ==============================  BYTE SWAPPING DATA  ========================================
static byte_swap_code unit_definition_byte_swapping_data[]=
{
	_begin_bs_array, 1,
	
	// file_tag monster_tag;
	_4byte,

	// int number_of_customizations
	_4byte,

	// struct unit_customization_settings custom_colors[MAXIMUM_CUSTOMIZATIONS_PER_UNIT];
	_begin_bs_array, MAXIMUM_CUSTOMIZATIONS_PER_UNIT,
		// file_tag logo_txst_tag;
		_4byte,
		
		// int logo_table_index;
		_4byte,
		
		// rgb_color primary_color;
		_2byte, _2byte, _2byte, _2byte,
		
		// rgb_color secondary_color;
		_2byte, _2byte, _2byte, _2byte,
		
	_end_bs_array,
	
	// short unused[55];
	7*sizeof(short),

	// short player_index;
	// file_tag parent_unit_tag; // only interesting if this is a custom unit definition
	sizeof(short),
	sizeof(file_tag),

	// computed when postprocessing this definition
	
	// short monster_type;
	// short unused2;
	2*sizeof(short),
	
	_end_bs_array
};

unit_definition default_unit =
{
	-1,
	0,
	{	{ -1, -1, { 0xffff, 0, 0, 0 }, { 0, 0, 0xffff, 0 } },
		{ -1, -1, { 0xffff, 0, 0, 0 }, { 0, 0, 0xffff, 0 } },
		{ -1, -1, { 0xffff, 0, 0, 0 }, { 0, 0, 0xffff, 0 } },
		{ -1, -1, { 0xffff, 0, 0, 0 }, { 0, 0, 0xffff, 0 } }	},
	0, 0, 0, 0, 0, 0, 0,
	0,
	-1,
	0,
	0
};

// ==============================  EDIT WINDOW  ========================================
void edit_unit( tag_entry* e )
{
	TunitEditForm* form = new TunitEditForm( e );
	form->AttachWindow( 1027 );
}

void defaultnew_unit( tag_entry *e )
{
	unit_definition def;
	byte_swap_move_be( "unit", &def, &default_unit, sizeof(unit_definition), 1, unit_definition_byte_swapping_data );
	set_entry_data( e, &def, sizeof(def), false );
}

void dependency_unit( tag_entry *e )
{
	unit_definition def;
	read_unit_definition( &def, e );
	add_tag_dependency( 'mons', def.monster_tag );
	
	for( int ii = 0; ii < MAXIMUM_CUSTOMIZATIONS_PER_UNIT; ii++ )
		add_tag_dependency( 'txst', def.custom_colors[ii].logo_txst_tag );
}

void update_unit( tag_entry *e )
{
	if (get_entry_version( e ) != 2)
	{
		unit_definition def;
		read_unit_definition( &def, e );
		def.number_of_customizations = 0;
		memcpy( def.custom_colors, default_unit.custom_colors, sizeof(def.custom_colors) );
		save_unit_definition( &def, e );
		set_entry_version( e, 2 );
	}
}

// ==============================  READ TAG DATA  ========================================
bool read_unit_definition( unit_definition* def, tag_entry* e )
{
	return load_tag_data_into_struct( "unit", e, def, SIZEOF_STRUCT_UNIT_DEFINITION, 1, unit_definition_byte_swapping_data);
}


// ==============================  SAVE TAG DATA  ========================================
bool save_unit_definition( unit_definition* def, tag_entry* e )
{
	return save_tag_data_from_struct( "unit", e, def, SIZEOF_STRUCT_UNIT_DEFINITION, 1, unit_definition_byte_swapping_data);
}


// ==============================  READ TAG DATA (WITH ID) ========================================
bool read_unit_definition( unit_definition* def, tag id )
{
	tag_entry* e;
	
	assert( def );
	
	e = get_entry( 'unit', id );
	if( 0 == e ) {
		return FALSE;
	}
	
	return read_unit_definition( def, e );	
}


// ==============================  SAVE TAG DATA (WITH ID) ========================================
bool save_unit_definition( unit_definition* def, tag id )
{
	tag_entry* e;
	
	assert( def );
	
	e = get_entry( 'unit', id );
	if( 0 == e ) {
		return FALSE;
	}

	return save_unit_definition( def, e );
}


// ==============================  DISPATCH  ========================================
BEGINDISPATCH(TunitEditForm,TTagEditForm)
	DISPATCHTABLE(KXGControlClick,TunitEditForm::DoControlClick)
ENDDISPATCH


TunitEditForm::TunitEditForm( struct tag_entry *e ) : TTagEditForm( e )
{
}

// ==============================  INITIALIZE FORM =======================================
void TunitEditForm::DoFormInitialize()
{
	TTagEditForm::DoFormInitialize();

}


// ==============================  INPUT HANDLING  ========================================
long TunitEditForm::DoControlClick( long arg, void *ptr )
{
#ifdef __MWERKS__
	#pragma unused(ptr)
#endif

	tag_entry* e;
	tag new_id;
	
	switch( arg )
	{
		case 1:
			// Choose a tag
			new_id = pick_tag_of_type('mons', GetTag( arg ), fEntry );
			if(new_id != 0) {
				SetTag( arg, 'mons', new_id );
			}
		break; 
		
		case 2:
			// Open tag window
			e = get_entry('mons', GetTag( arg - 1 ) );
			if(e) {
				TRevengeApp::OpenItem( e );
			}
		break;
		
		case 107:
			new_id = pick_tag_of_type('txst', GetTag( arg ), fEntry );
			if (new_id != 0) {
				SetTag( arg, 'txst', new_id );
			}
		break; 
		
		case 207:
			new_id = pick_tag_of_type('txst', GetTag( arg ), fEntry );
			if (new_id != 0) {
				SetTag( arg, 'txst', new_id );
			}
		break; 
		
		case 307:
			new_id = pick_tag_of_type('txst', GetTag( arg ), fEntry );
			if (new_id != 0) {
				SetTag( arg, 'txst', new_id );
			}
		break; 

		default:
			return -1;
	}

	return 0;
}

		
// ========================================  SAVE TO TAG  ==================================================
void TunitEditForm::CommitToTag()
{
	GetValues();
	save_unit_definition( &def, fEntry );
}


// ========================================  RELOAD TAG  ==================================================
void TunitEditForm::ReloadTag()
{
	read_unit_definition( &def, fEntry );
	SetValues();
}


// ========================================  TAG NEEDS UPDATING  ==================================================
bool TunitEditForm::NeedCommit()
{
	GetValues();
	return tag_data_needs_update( "unit", fEntry, &def, SIZEOF_STRUCT_UNIT_DEFINITION, 1, unit_definition_byte_swapping_data);
}

		
// ========================================  SET INTERFACE VALUES  ==================================================
void TunitEditForm::SetValues()
{
	SetTag( 1, 'mons', def.monster_tag );
	SetInt( 3, def.number_of_customizations );
	for (int i = 0; i < 3; ++i)
	{
		int base = 100 * (i + 1);
		SetVisible( base, false );
		SetInt( base+1, def.custom_colors[i].primary_color.red / 256 );
		SetInt( base+2, def.custom_colors[i].primary_color.green / 256 );
		SetInt( base+3, def.custom_colors[i].primary_color.blue / 256 );
		SetInt( base+4, def.custom_colors[i].secondary_color.red / 256 );
		SetInt( base+5, def.custom_colors[i].secondary_color.green / 256 );
		SetInt( base+6, def.custom_colors[i].secondary_color.blue / 256 );
		SetTag( base+7, 'txst', def.custom_colors[i].logo_txst_tag );
	}
}


// ========================================  GET INTERFACE VALUES  ==================================================
void TunitEditForm::GetValues()
{
	def.monster_tag = GetTag( 1 );
	def.number_of_customizations = GetInt( 3 );
	if (def.number_of_customizations < 0) def.number_of_customizations = 0;
	if (def.number_of_customizations > 3) def.number_of_customizations = 3;
	for (int i = 0; i < 3; ++i)
	{
		int base = 100 * (i + 1);
		if (i < def.number_of_customizations)
		{
			bool update_bmp = false;
			if (!IsVisible( base ))
			{
				SetVisible( base, true );
				update_bmp = true;
			}
			
			struct unit_customization_settings old = def.custom_colors[i];
			def.custom_colors[i].primary_color.red = GetInt( base+1 ) * 0x101;
			def.custom_colors[i].primary_color.green = GetInt( base+2 ) * 0x101;
			def.custom_colors[i].primary_color.blue = GetInt( base+3 ) * 0x101;
			def.custom_colors[i].secondary_color.red = GetInt( base+4 ) * 0x101;
			def.custom_colors[i].secondary_color.green = GetInt( base+5 ) * 0x101;
			def.custom_colors[i].secondary_color.blue = GetInt( base+6 ) * 0x101;
			def.custom_colors[i].logo_txst_tag = GetTag( base + 7 );
			if (memcmp( &(def.custom_colors[i]), &old, sizeof(old) ) != 0)
			{
				update_bmp = true;
			}
			
			if (update_bmp)
			{
				byte bmp[80][80][3];
				for (int y = 0; y < 80; ++y)
				{
					for (int x = 0; x < 80; ++x)
					{
						if (80 - x > y)
						{
							bmp[y][x][0] = def.custom_colors[i].primary_color.red;
							bmp[y][x][1] = def.custom_colors[i].primary_color.green;
							bmp[y][x][2] = def.custom_colors[i].primary_color.blue;
						}
						else
						{
							bmp[y][x][0] = def.custom_colors[i].secondary_color.red;
							bmp[y][x][1] = def.custom_colors[i].secondary_color.green;
							bmp[y][x][2] = def.custom_colors[i].secondary_color.blue;
						}
					}
				}
				
				dynamic_cast<TBitmapView *>(GetWindow()->FindViewByID( base+8 ))->SetBitmapRGB( bmp, 80, 80 );
				GetWindow()->FindViewByID( base+8 )->InvalView();
			}
		}
		else
		{
			SetVisible( base, false );
		}
	}
}

