
#include "meef.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  ========================================
byte_swap_code mesh_effect_byte_swapping_data[]=
{
	_begin_bs_array, 1,
	
	// unsigned long flags;
	_4byte,

	// short_world_distance amplitude;
	// short_world_distance cutoff_radius;
	// short_fixed dissipation;
	_2byte,	
	_2byte,
	_2byte,

	// short_world_distance velocity;
	// short_world_distance epicenter_offset;
	_2byte,
	_2byte,

	// short camera_shaking_type;
	_2byte,

	// file_tag collection_reference_tag;
	// short sequence_index;
	_4byte,
	_2byte,

	// short number_of_radial_points;
	_2byte,

	// short_world_distance shockwave_thickness;
	// short_world_distance shockwave_height_offset;
	_2byte,
	_2byte,

	// computed during postprocessing
	
	// short collection_reference_index;
	// short collection_index, color_table_index;
	// short pad;
	4*sizeof(short),
	
	_end_bs_array
};

mesh_effect_definition default_meef =
{
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	-1,
	0,
	0,
	0,
	0,
	0,
	0, 0,
	0
};	


// ==============================  EDIT WINDOW  ========================================
void edit_meef( tag_entry* e )
{
	TmeefEditForm* form = new TmeefEditForm( e );
	form->AttachWindow( 1011 );
}

void defaultnew_meef( tag_entry *e )
{
	mesh_effect_definition def;
	byte_swap_move_be( "meef", &def, &default_meef, sizeof(mesh_effect_definition), 1, mesh_effect_byte_swapping_data );
	set_entry_data( e, &def, sizeof(def), false );
}

void dependency_meef( tag_entry *e )
{
	mesh_effect_definition def;
	read_mesh_effect_definition( &def, e );
	add_tag_dependency( 'core', def.collection_reference_tag );
}


// ==============================  READ TAG DATA  ========================================
bool read_mesh_effect_definition( mesh_effect_definition* def, tag_entry* e )
{
	return load_tag_data_into_struct( "meef", e, def, SIZEOF_STRUCT_MESH_EFFECT_DEFINITION, 1, mesh_effect_byte_swapping_data);
}


// ==============================  SAVE TAG DATA  ========================================
bool save_mesh_effect_definition( mesh_effect_definition* def, tag_entry* e )
{
	return save_tag_data_from_struct( "meef", e, def, SIZEOF_STRUCT_MESH_EFFECT_DEFINITION, 1, mesh_effect_byte_swapping_data);
}


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


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

	return save_mesh_effect_definition( def, e );
}


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


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

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

}


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

	tag_entry* e;
	tag new_id;
	
	switch( arg )
	{
		case 11109:
			// Choose a tag
			new_id = pick_tag_of_type('core', GetTag( 11109 ), fEntry );
			if(new_id != 0) {
				SetTag( 11109, 'core', new_id );
			}
		break; 
		
		case 11110:
			// Open tag window
			e = get_entry('core', GetTag( 11109 ) );
			if(e) {
				TRevengeApp::OpenItem( e );
			}
		break;
		
		default:
			return -1;
	}
	
	return 0;
}

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


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


// ========================================  TAG NEEDS UPDATING  ==================================================
bool TmeefEditForm::NeedCommit()
{
	GetValues();
	return tag_data_needs_update( "meef", fEntry, &def, SIZEOF_STRUCT_MESH_EFFECT_DEFINITION, 1, mesh_effect_byte_swapping_data);
}

		
// ========================================  SET INTERFACE VALUES  ==================================================
void TmeefEditForm::SetValues()
{
	int i;

	SetShortWorldDistance( 11101, def.amplitude );
	SetShortWorldDistance( 11102, def.velocity );
	SetShortWorldDistance( 11103, def.cutoff_radius );
	SetShortFixed( 11104, def.dissipation );
	SetShortWorldDistance( 11105, def.epicenter_offset );

	XGPopControl* pList;
	pList = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 11106 ));
	assert(pList);
	pList->DeleteAll();
	pList->Insert(0, "None");
	pList->Insert(1, "Earthquake");
	pList->Insert(2, "Explosion");
	pList->SetValue( def.camera_shaking_type + 1 );

	if(def.flags&_mesh_effect_is_inverted_flag) {
		SetFlag( 11107, TRUE );
	} else {
		SetFlag( 11107, FALSE );
	}
	if(def.flags&_mesh_effect_has_shockwave_flag) {
		SetFlag( 11108, TRUE );
	} else {
		SetFlag( 11108, FALSE );
	}
	SetTag( 11109, 'core', def.collection_reference_tag );
	SetInt( 11112, def.number_of_radial_points );

	XGPopControl* pList2;
	pList2 = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 11111 ));
	assert(pList2);
	pList2->DeleteAll();
	pList2->Insert(0, "None");
	for (i = 1; i < 200; i++) {
		pList2->Insert(i, "Sequence");
	}
	pList2->SetValue( def.sequence_index );

	SetShortWorldDistance( 11113, def.shockwave_thickness );
	SetShortWorldDistance( 11114, def.shockwave_height_offset );
}


// ========================================  GET INTERFACE VALUES  ==================================================
void TmeefEditForm::GetValues()
{
	def.amplitude = GetShortWorldDistance( 11101 );
	def.velocity = GetShortWorldDistance( 11102 );
	def.cutoff_radius = GetShortWorldDistance( 11103 );
	def.dissipation = GetShortFixed( 11104 );
	def.epicenter_offset = GetShortWorldDistance( 11105 );

	XGPopControl* pList;
	pList = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 11106 ));
	assert(pList);
	def.camera_shaking_type = pList->GetValue() - 1;

	def.flags = 0;
	if(GetFlag( 11107 )) def.flags |= _mesh_effect_is_inverted_flag;
	if(GetFlag( 11108 )) def.flags |= _mesh_effect_has_shockwave_flag;

	def.collection_reference_tag = GetTag( 11109 );
	def.number_of_radial_points = GetInt( 11112 );

	XGPopControl* pList2;
	pList2 = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 11111 ));
	assert(pList2);
	def.sequence_index = pList2->GetValue();

	def.shockwave_thickness = GetShortWorldDistance( 11113 );
	def.shockwave_height_offset = GetShortWorldDistance( 11114 );

}

