
#include "medi.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>


// ==============================  BYTE SWAPPING DATA  ========================================
static byte_swap_code media_definition_byte_swapping_data[]=
{
	_begin_bs_array, 1,
	
	// unsigned long flags;
	_4byte,
	
	// file_tag collection_reference_tag;
	_4byte,
	
	// short unused[8];
	8*sizeof(short),

	// file_tag projectile_group_tags[MAXIMUM_NUMBER_OF_MEDIA_DEFINITION_PROJECTILE_GROUPS];
	
		_begin_bs_array, MAXIMUM_NUMBER_OF_MEDIA_DEFINITION_PROJECTILE_GROUPS,
		
		_4byte,
		
		_end_bs_array,

	// short_fixed reflection_tint_fraction;
	// struct rgb_color reflection_tint_color;
	_2byte,
	_2byte, _2byte, _2byte, _2byte,

	// fixed_fraction surface_effect_density; // percentage of maximum density
	// file_tag surface_effect_local_projectile_group_tag;
	_2byte,
	_4byte,

	// world_vector3d wobble_magnitude;
	// world_vector3d wobble_phase_magnitude;
	_2byte, _2byte, _2byte,
	_2byte, _2byte, _2byte,
	
	// short effects_per_cell;
	// short time_between_building_effects;
	_2byte,
	_2byte,

	// fixed_fraction reflection_transparency;
	_2byte,
	
	// short_fixed min_opacity;
	_2byte,
	
	// short_fixed max_opacity;
	_2byte,
	
	// short_fixed max_opacity_depth;
	_2byte,
	
	// fixed_fraction spec_min, spec_max;
	_2byte, _2byte,
	
	// short_fixed emboss_fraction;
	_2byte,
	
	_begin_bs_array, 4,
		// short_fixed wobble_scale;
		_2byte,
		
		// short_fixed wobble_speed;
		_2byte,
		
		// short_fixed base_scale[2];
		_2byte, _2byte,
		
		// short_fixed base_speed[2];
		_2byte, _2byte,
		
	_end_bs_array,
	
	// short unused2[18];
	18*sizeof(short),
	
	// computed during postprocessing

	// short surface_effect_local_projectile_group;
	// short surface_effect_local_projectile_group_type;
	// short collection_reference_index;
	3*sizeof(short),
	
	// short projectile_group_types[MAXIMUM_NUMBER_OF_MEDIA_DEFINITION_PROJECTILE_GROUPS];
	MAXIMUM_NUMBER_OF_MEDIA_DEFINITION_PROJECTILE_GROUPS*sizeof(short),

	_end_bs_array
};

media_definition default_medi =
{
	0,
	-1,
	0, 0, 0, 0, 0, 0, 0, 0,
	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
	0,
	0, 0, 0, 0,
	0,
	-1,
	0, 0, 0,	
	0, 0, 0,
	0,
	0,
	0,
	FLOAT_TO_SHORT_FIXED( 0.1 ),
	FLOAT_TO_SHORT_FIXED( 1.0 ),
	FLOAT_TO_SHORT_FIXED( 2.0 ),
	FLOAT_TO_FIXED( 0.2 ),
	FLOAT_TO_FIXED( 0.8 ),
	FLOAT_TO_SHORT_FIXED( 1.0 ),
	
		FLOAT_TO_SHORT_FIXED( 0.5 ),
		FLOAT_TO_SHORT_FIXED( 1.0 ),
		FLOAT_TO_SHORT_FIXED( 0.4 ),
		FLOAT_TO_SHORT_FIXED( 0.4 ),
		FLOAT_TO_SHORT_FIXED( 0.1 ),
		FLOAT_TO_SHORT_FIXED( 0.0 ),
	
		FLOAT_TO_SHORT_FIXED( 0.2 ),
		FLOAT_TO_SHORT_FIXED( 1.1 ),
		FLOAT_TO_SHORT_FIXED( 0.3 ),
		FLOAT_TO_SHORT_FIXED( 0.3 ),
		FLOAT_TO_SHORT_FIXED( 0.0 ),
		FLOAT_TO_SHORT_FIXED( 0.1 ),
	
		FLOAT_TO_SHORT_FIXED( 0.1 ),
		FLOAT_TO_SHORT_FIXED( 0.2 ),
		FLOAT_TO_SHORT_FIXED( 0.4 ),
		FLOAT_TO_SHORT_FIXED( 0.4 ),
		FLOAT_TO_SHORT_FIXED( 0.0 ),
		FLOAT_TO_SHORT_FIXED( 0.0 ),
	
		FLOAT_TO_SHORT_FIXED( 0.2 ),
		FLOAT_TO_SHORT_FIXED( 0.3 ),
		FLOAT_TO_SHORT_FIXED( 0.3 ),
		FLOAT_TO_SHORT_FIXED( 0.3 ),
		FLOAT_TO_SHORT_FIXED( 0.1 ),
		FLOAT_TO_SHORT_FIXED( 0.1 ),
	
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	
	0,
	0,
	0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};	


// ==============================  EDIT WINDOW  ========================================
void edit_medi( tag_entry* e )
{
	TmediEditForm* form = new TmediEditForm( e );
	form->AttachWindow( 1010 );
}

void dependency_medi( tag_entry *e )
{
	media_definition def;
	read_media_definition( &def, e );
	add_tag_dependency( 'txst', def.collection_reference_tag );
	add_tag_dependency( 'lpgr', def.surface_effect_local_projectile_group_tag );
	for (int i = 0; i < NUMBER_OF_MEDIA_DEFINITION_PROJECTILE_GROUPS; ++i)
	{
		add_tag_dependency( 'prgr', def.projectile_group_tags[i] );
	}
}

// ==============================  READ TAG DATA  ========================================
bool read_media_definition( media_definition* def, tag_entry* e )
{
	return load_tag_data_into_struct( "medi", e, def, SIZEOF_STRUCT_MEDIA_DEFINITION, 1, media_definition_byte_swapping_data);
}

void defaultnew_medi( tag_entry *e )
{
	media_definition def;
	byte_swap_move_be( "medi", &def, &default_medi, sizeof(media_definition), 1, media_definition_byte_swapping_data );
	set_entry_data( e, &def, sizeof(def), false );
}

// ==============================  SAVE TAG DATA  ========================================
bool save_media_definition( media_definition* def, tag_entry* e )
{
	return save_tag_data_from_struct( "medi", e, def, SIZEOF_STRUCT_MEDIA_DEFINITION, 1, media_definition_byte_swapping_data);
}


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


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

	return save_media_definition( def, e );
}


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


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

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

}


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

	tag_entry* e;
	tag new_id;
	
	switch( arg )
	{
		// Collection Reference
		case 11001:	// Choose a tag
			new_id = pick_tag_of_type('txst', GetTag( 11001 ), fEntry );
			if(new_id != 0) SetTag( 11001, 'txst', new_id );
		break; 
		
		case 11002:	// Open tag window
			e = get_entry('txst', GetTag( 11001 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Local Projectile Group
		case 11003:	// Choose a tag
			new_id = pick_tag_of_type('lpgr', GetTag( 11003 ), fEntry );
			if(new_id != 0) SetTag( 11003, 'lpgr', new_id );
		break; 
		
		case 11004:	// Open tag window
			e = get_entry('lpgr', GetTag( 11003 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11011:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11011 ), fEntry );
			if(new_id != 0) SetTag( 11011, 'prgr', new_id );
		break; 
		
		case 11012:	// Open tag window
			e = get_entry('prgr', GetTag( 11011 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11013:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11013 ), fEntry );
			if(new_id != 0) SetTag( 11013, 'prgr', new_id );
		break; 
		
		case 11014:	// Open tag window
			e = get_entry('prgr', GetTag( 11013 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11015:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11015 ), fEntry );
			if(new_id != 0) SetTag( 11015, 'prgr', new_id );
		break; 
		
		case 11016:	// Open tag window
			e = get_entry('prgr', GetTag( 11015 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11017:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11017 ), fEntry );
			if(new_id != 0) SetTag( 11017, 'prgr', new_id );
		break; 
		
		case 11018:	// Open tag window
			e = get_entry('prgr', GetTag( 11017 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11019:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11019 ), fEntry );
			if(new_id != 0) SetTag( 11019, 'prgr', new_id );
		break; 
		
		case 11020:	// Open tag window
			e = get_entry('prgr', GetTag( 11019 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11021:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11021 ), fEntry );
			if(new_id != 0) SetTag( 11021, 'prgr', new_id );
		break; 
		
		case 11022:	// Open tag window
			e = get_entry('prgr', GetTag( 11021 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		// Projectile Group
		case 11023:	// Choose a tag
			new_id = pick_tag_of_type('prgr', GetTag( 11023 ), fEntry );
			if(new_id != 0) SetTag( 11023, 'prgr', new_id );
		break; 
		
		case 11024:	// Open tag window
			e = get_entry('prgr', GetTag( 11023 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;
		
		default:
			return -1;
	}
	
	return 0;
}

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


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


// ========================================  TAG NEEDS UPDATING  ==================================================
bool TmediEditForm::NeedCommit()
{
	GetValues();
	return tag_data_needs_update( "medi", fEntry, &def, SIZEOF_STRUCT_MEDIA_DEFINITION, 1, media_definition_byte_swapping_data);
}

		
// ========================================  SET INTERFACE VALUES  ==================================================
void TmediEditForm::SetValues()
{
	SetTag( 11001, 'txst', def.collection_reference_tag );
	SetTag( 11003, 'lpgr', def.surface_effect_local_projectile_group_tag );

	SetShortFixed( 11008, def.surface_effect_density );

	SetInt( 11009, def.effects_per_cell );
	SetFloat( 11010, def.time_between_building_effects / (float)TICKS_PER_SECOND, 3);

	SetTag( 11011, 'prgr', def.projectile_group_tags[_media_projectile_group_small_splash] );
	SetTag( 11013, 'prgr', def.projectile_group_tags[_media_projectile_group_medium_splash] );
	SetTag( 11015, 'prgr', def.projectile_group_tags[_media_projectile_group_large_splash] );
	SetTag( 11017, 'prgr', def.projectile_group_tags[_media_projectile_group_bloody_splash] );
	SetTag( 11019, 'prgr', def.projectile_group_tags[_media_projectile_group_floating_splash] );
	SetTag( 11021, 'prgr', def.projectile_group_tags[_media_projectile_group_steam_splash] );
	SetTag( 11023, 'prgr', def.projectile_group_tags[_media_projectile_group_disturbance] );
	
	SetShortFixed( 12001, def.min_opacity );
	SetShortFixed( 12002, def.max_opacity );
	SetShortFixed( 12003, def.max_opacity_depth );
	SetPercentage( 12004, def.spec_min );
	SetPercentage( 12005, def.spec_max );
	SetShortFixed( 12006, def.emboss_fraction );
	
	for (int i = 0; i < 2; ++i)
	{
		for (int j = 0; j < 2; ++j)
		{
			int base = 13000 + i * 1000 + j * 500;
			SetShortFixed( base+1, def.texdata[i][j].wobble_scale );
			SetShortFixed( base+2, def.texdata[i][j].wobble_speed );
			SetShortFixed( base+3, def.texdata[i][j].base_scale[0] );
			SetShortFixed( base+4, def.texdata[i][j].base_scale[1] );
			SetShortFixed( base+5, def.texdata[i][j].base_speed[0] );
			SetShortFixed( base+6, def.texdata[i][j].base_speed[1] );
		}
	}
	
}


// ========================================  GET INTERFACE VALUES  ==================================================
void TmediEditForm::GetValues()
{
	def.collection_reference_tag = GetTag( 11001 );
	def.surface_effect_local_projectile_group_tag = GetTag( 11003 );
	
	def.surface_effect_density = GetShortFixed( 11008 );

	def.effects_per_cell = GetInt( 11009 );
	def.time_between_building_effects = GetFloat( 11010 ) * (float)TICKS_PER_SECOND;

	def.projectile_group_tags[_media_projectile_group_small_splash] = GetTag( 11011 );
	def.projectile_group_tags[_media_projectile_group_medium_splash] = GetTag( 11013 );
	def.projectile_group_tags[_media_projectile_group_large_splash] = GetTag( 11015 );
	def.projectile_group_tags[_media_projectile_group_bloody_splash] = GetTag( 11017 );
	def.projectile_group_tags[_media_projectile_group_floating_splash] = GetTag( 11019 );
	def.projectile_group_tags[_media_projectile_group_steam_splash] = GetTag( 11021 );
	def.projectile_group_tags[_media_projectile_group_disturbance] = GetTag( 11023 );
	
	def.min_opacity = GetShortFixed( 12001 );
	def.max_opacity = GetShortFixed( 12002 );
	def.max_opacity_depth = GetShortFixed( 12003 );
	def.spec_min = GetPercentage( 12004 );
	def.spec_max = GetPercentage( 12005 );
	def.emboss_fraction = GetShortFixed( 12006 );
	
	for (int i = 0; i < 2; ++i)
	{
		for (int j = 0; j < 2; ++j)
		{
			int base = 13000 + i * 1000 + j * 500;
			def.texdata[i][j].wobble_scale = GetShortFixed( base+1 );
			def.texdata[i][j].wobble_speed = GetShortFixed( base+2 );
			def.texdata[i][j].base_scale[0] = GetShortFixed( base+3 );
			def.texdata[i][j].base_scale[1] = GetShortFixed( base+4 );
			def.texdata[i][j].base_speed[0] = GetShortFixed( base+5 );
			def.texdata[i][j].base_speed[1] = GetShortFixed( base+6 );
		}
	}
}

