
#ifndef __monsters_h__
#include "monsters.h"
#endif

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

#include <XMessages.h>
#include "tagpick.h"


byte_swap_code monster_definition_byte_swapping_data[]=
{
	_begin_bs_array, 1,
	
	// unsigned long flags;
	_4byte,
	
	// file_tag collection_tag;
	_4byte,

	// short sequence_indexes[MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SEQUENCES];
	_begin_bs_array, MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SEQUENCES, _2byte, _end_bs_array,

	// char terrain_costs[MAXIMUM_NUMBER_OF_TERRAIN_TYPES];
	MAXIMUM_NUMBER_OF_TERRAIN_TYPES,

	// word impassable_terrain_flags;
	// short_world_distance pathfinding_radius;
	_2byte,
	_2byte,
	
	// short_fixed_fraction movement_modifiers[MAXIMUM_NUMBER_OF_TERRAIN_TYPES];
	MAXIMUM_NUMBER_OF_TERRAIN_TYPES,

	// fixed_fraction absorbed_fraction;
	_2byte,

	// short_world_distance warning_distance; // used to awake nearby friends to new target
	// short_world_distance critical_distance; // used for fight vs. flight
	_2byte,
	_2byte,

	// short_fixed healing_fraction;
	_2byte,

	// short initial_ammunition_lower_bound, initial_ammunition_delta;
	_2byte, _2byte,

	// short_world_distance activation_distance; // range of "sight and hearing" for automatic attack vs. retreat
	// short unused;
	_2byte,
	sizeof(short),

	// angle turning_speed; // not a function of terrain
	// short_world_distance base_movement_speed;
	_2byte,
	_2byte,

	// fixed_fraction left_handed_fraction; // the fraction of this type that is left-handed
	// short size;
	_2byte,
	_2byte,

	// file_tag object_tag;
	_4byte,

	// short number_of_attacks;
	// short desired_projectile_volume;
	_2byte,
	_2byte,
	
	// struct monster_attack_definition attacks[MAXIMUM_NUMBER_OF_ATTACKS_PER_MONSTER];
	MAXIMUM_NUMBER_OF_ATTACKS_PER_MONSTER * sizeof(struct monster_attack_definition), // byteswap it later

	// file_tag map_action_tag; // for ambient life
	_4byte,

	// short attack_frequency_lower_bound, attack_frequency_delta;
	_2byte, _2byte,

	// file_tag exploding_projectile_group_tag;
	_4byte,

	// short unused4;
	// short maximum_ammunition_count;
	sizeof(short),
	_2byte,

	// fixed_fraction hard_death_system_shock, flinch_system_shock;
	_2byte, _2byte,

	// file_tag melee_impact_projectile_group_tag;
	// file_tag dying_projectile_group_tag;
	_4byte,
	_4byte,
	
	// file_tag spelling_string_list_tag; // sigular and plural spelling
	// file_tag names_string_list_tag; // common names for this monster
	// file_tag flavor_string_list_tag; // flavor texts for this monster
	_4byte,
	_4byte,
	_4byte,
	
	// short unused3;
	sizeof(short),

	// short monster_class;
	// short monster_allegiance;
	// short experience_point_value;
	_2byte,
	_2byte,
	_2byte,
	
	// file_tag sounds_tags[MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SOUNDS];
	_begin_bs_array, MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SOUNDS, _4byte, _end_bs_array,

	// file_tag blocked_impact_projectile_group_tag;
	// file_tag absorbed_impact_projectile_group_tag;
	_4byte,
	_4byte,

	// file_tag ammunition_projectile_tag;
	_4byte,

	// short visiblity_type;
	_2byte,

	// short combined_power;
	// short_world_distance longest_range;
	_2byte,
	_2byte,
	
	// short cost;
	_2byte,

	// char sound_types[MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SOUNDS];
	MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SOUNDS,

	// word pad3
	sizeof(word),
	
	// file_tag entrance_projectile_group_tag;
	// file_tag local_projectile_group_tag;
	// file_tag special_ability_string_list_tag;
	// file_tag exit_projectile_group_tag;
	_4byte,
	_4byte,
	_4byte,
	_4byte,

	// short_fixed maximum_mana;
	// short_fixed mana_recharge_rate;
	_2byte,
	_2byte,
	
	// fixed_fraction berserk_system_shock;
	// fixed_fraction berserk_vitality;
	_2byte,
	_2byte,

	// short unused2[216];
	216*sizeof(short),

	// computed during postprocessing

	// short next_name_string_index;
	// short ammunition_projectile_type;
	2*sizeof(short),

	// short sound_indexes[MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SOUNDS];
	MAXIMUM_NUMBER_OF_MONSTER_DEFINITION_SOUNDS*sizeof(short),
	
	// short spelling_string_list_index; // sigular and plural spelling
	// short names_string_list_index; // common names for this monster
	// short flavor_string_list_index; // flavor texts for this monster
	// short special_ability_string_list_index;
	// short exploding_projectile_group_type;
	// short melee_impact_projectile_group_type;
	// short dying_projectile_group_type;
	// short blocked_impact_projectile_group_type;
	// short absorbed_impact_projectile_group_type;
	// short entrance_projectile_group_type, exit_projectile_group_type;
	// short collection_index; // from collection_tag
	// short object_type; // from object_tag
	// short local_projectile_group_type;
	14*sizeof(short),
	
	_end_bs_array
};



void edit_monster( tag_entry *entry )
{
	TmonsEditForm *form = new TmonsEditForm( entry );
	form->AttachWindow( KWindowMonster );
}


BEGINDISPATCH(TmonsEditForm,TTagEditForm)
	DISPATCHTABLE(KXGControlClick,TmonsEditForm::DoControlClick)
ENDDISPATCH


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


TmonsEditForm::~TmonsEditForm()
{
}


long TmonsEditForm::DoControlClick( long arg, void *ptr )
{
	switch (arg) {
		case 1: { // graphics tag
				bool use_tiki = GetFlag( 2 );
				tag type = use_tiki ? 'skmd' : '.256';
				tag newid = pick_tag_of_type( type, GetTag( 1 ) );
				if (newid) {
					SetTag( 1, type, newid );
				}
				return 0;
			} break;
		case 2: {
				bool use_tiki = !GetFlag( 2 );
				SetFlag( 2, use_tiki );
				tag type = use_tiki ? 'skmd' : '.256';
				SetTag( 1, type, GetTag( 1 ) );
				return 0;
			} break;
		default: {
			} break;
	}
	return -1;
}


void TmonsEditForm::CommitToTag()
{
	monster_definition temp;
	
	GetValues();
	byte_swap_move_be( "monster def", &temp, &this->data, sizeof(temp), 1, monster_definition_byte_swapping_data );
	set_entry_data( fEntry, &temp, sizeof(temp), false );
}


void TmonsEditForm::ReloadTag()
{
	const void *file_data;
	unsigned length;
	get_entry_data( fEntry, &file_data, &length );
	byte_swap_move_be( "monster def", &this->data, (void*)file_data, length, 1, monster_definition_byte_swapping_data );
	SetValues();
}


bool TmonsEditForm::NeedCommit()
{
	monster_definition temp;
	
	GetValues();
	byte_swap_move_be( "monster def", &temp, &this->data, sizeof(temp), 1, monster_definition_byte_swapping_data );
	
	const void *file_data;
	unsigned length;
	get_entry_data( fEntry, &file_data, &length );
	
	return (!file_data || length != sizeof(temp) || memcmp( &temp, file_data, length ) != 0);
}


void TmonsEditForm::SetValues()
{
	if (data.flags & _monster_has_tiki_model_flag) {
		SetTag( 1, 'skmd', data.collection_tag );
		SetFlag( 2, true );
	} else {
		SetTag( 1, '.256', data.collection_tag );
		SetFlag( 2, false );
	}
	
	SetShortFixed( 3, data.healing_fraction );
	
	SetFlag( 4, data.flags & _monster_floats_flag );
}


void TmonsEditForm::GetValues()
{
	data.collection_tag = GetTag( 1 );
	SET_FLAG32( data.flags, _monster_has_tiki_model_bit, GetFlag( 2 ) );
	SET_FLAG32( data.flags, _monster_floats_bit, GetFlag( 4 ) );
	data.healing_fraction = GetShortFixed( 3 );
}


