
#include "arti.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 artifact_definition_byte_swapping_data[]=
{
	_begin_bs_array, 1,
	
	// unsigned long flags;
	_4byte,
	
	// file_tag monster_restriction_tag; // or NONE
	// short specialization_restriction; // bow, sword, etc ... or NONE
	_4byte,
	_2byte,
	
	// short initial_charges_lower_bound, initial_charges_delta; // not displayed if zero
	_2byte, _2byte,
	
	// word pad;
	sizeof(word),
	
	// file_tag collection_tag;
	// short sequence_indexes[MAXIMUM_NUMBER_OF_ARTIFACT_SEQUENCES];
	_4byte,
	_begin_bs_array, MAXIMUM_NUMBER_OF_ARTIFACT_SEQUENCES, _2byte, _end_bs_array,
	
	// file_tag projectile_tags[MAXIMUM_NUMBER_OF_ARTIFACT_PROJECTILES];
	_begin_bs_array, MAXIMUM_NUMBER_OF_ARTIFACT_PROJECTILES, _4byte, _end_bs_array,
	
	// unsigned long bonus_monster_flags;
	// unsigned long bonus_terrain_flags;
	_4byte,
	_4byte,
	
	// short_fixed bonus_effect_modifiers[MAXIMUM_NUMBER_OF_EFFECT_MODIFIERS];
	_begin_bs_array, MAXIMUM_NUMBER_OF_EFFECT_MODIFIERS, _2byte, _end_bs_array,
		
	// struct monster_attack_definition override_attack;
	SIZEOF_STRUCT_MONSTER_ATTACK_DEFINITION, // byteswap it later

	// file_tag special_ability_string_list_tag;
	_4byte,
	
	// short unused[2];
	2*sizeof(short),
	
	// short collection_index;
	// short special_ability_string_list_index;
	// short projectile_types[MAXIMUM_NUMBER_OF_ARTIFACT_PROJECTILES];
	2*sizeof(short),
	MAXIMUM_NUMBER_OF_ARTIFACT_PROJECTILES*sizeof(short),

	_end_bs_array
};

artifact_definition default_arti =
{
	0,
	-1,
	0,
	0, 0,
	0,
	-1,
	0, 0, 0, 0,
	-1, -1, -1, -1,
	0,
	0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	// monster attack definition
	0,
	0,
	-1,
	0, 0,
	// monster attack animation
	0,
	0,
	0,
	0,
	// end monster attack animation
	0,
	0, 0,
	0,
	0,
	0,
	0,
	0,
	0,
	0,
	// end monster attack definition
	-1,
	0, 0,
	0,
	0,
	0, 0, 0, 0
};

// ==============================  EDIT WINDOW  ========================================
void edit_arti( tag_entry* e )
{
	TartiEditForm* form = new TartiEditForm( e );
	form->AttachWindow( 1001 );
}

void defaultnew_arti( tag_entry *e )
{
	artifact_definition def;
	
	byte_swap_move_be( "arti", &def, &default_arti, sizeof(artifact_definition), 1, artifact_definition_byte_swapping_data );
	set_entry_data( e, &def, sizeof(def), false );
}

void dependency_arti( tag_entry *e )
{
	artifact_definition def;
	read_artifact_definition( &def, e );
	add_tag_dependency( '.256', def.collection_tag );
	for (int i = 0; i < MAXIMUM_NUMBER_OF_ARTIFACT_PROJECTILES; ++i)
	{
		add_tag_dependency( 'proj', def.projectile_tags[i] );
	}
	add_tag_dependency( 'stli', def.special_ability_string_list_tag );
}


// ==============================  READ TAG DATA  ========================================
bool read_artifact_definition( artifact_definition* def, tag_entry* e )
{
	return load_tag_data_into_struct( "arti", e, def, SIZEOF_STRUCT_ARTIFACT_DEFINITION, 1, artifact_definition_byte_swapping_data);
}


// ==============================  SAVE TAG DATA  ========================================
bool save_artifact_definition( artifact_definition* def, tag_entry* e )
{
	return save_tag_data_from_struct( "arti", e, def, SIZEOF_STRUCT_ARTIFACT_DEFINITION, 1, artifact_definition_byte_swapping_data);
}


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


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

	return save_artifact_definition( def, e );
}


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


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

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

}

// ==============================  INPUT HANDLING  ========================================
long TartiEditForm::DoControlClick( long arg, void *ptr )
{
#ifdef __MWERKS__
	#pragma unused(ptr)
#endif
	tag_entry* e;
	tag new_id;
	
	switch( arg )
	{
		case 10101:	// Choose a tag
			new_id = pick_tag_of_type('.256', GetTag( 10101 ), fEntry);
			if(new_id != 0) SetTag( 10101, '.256', new_id );
		break; 
		
		case 10102:	// Open tag window
			e = get_entry('.256', GetTag( 10101 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;

		case 10103:	// Choose a tag
			new_id = pick_tag_of_type('mons', GetTag( 10103 ), fEntry);
			if(new_id != 0) SetTag( 10103, 'mons', new_id );
		break; 
		
		case 10104:	// Open tag window
			e = get_entry('mons', GetTag( 10103 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;

		case 10107:	// Choose a tag
			new_id = pick_tag_of_type('stli', GetTag( 10107 ), fEntry);
			if(new_id != 0) SetTag( 10107, 'stli', new_id );
		break; 
		
		case 10108:	// Open tag window
			e = get_entry('stli', GetTag( 10107 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;

		case 10111:	// Choose a tag
			new_id = pick_tag_of_type('proj', GetTag( 10111 ), fEntry);
			if(new_id != 0) SetTag( 10111, 'proj', new_id );
		break; 
		
		case 10112:	// Open tag window
			e = get_entry('proj', GetTag( 10111 ) );
			if(e) TRevengeApp::OpenItem( e );
		break;

		case 10117:	// Open Resistance Dialog (2002)
		break;

		case 10118:	// Open Attack Dialog (2000)
		break;
		
		default:
			return -1;
	}
	
	return 0;
}

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


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


// ========================================  TAG NEEDS UPDATING  ==================================================
bool TartiEditForm::NeedCommit()
{
	GetValues();
	return tag_data_needs_update( "arti", fEntry, &def, SIZEOF_STRUCT_ARTIFACT_DEFINITION, 1, artifact_definition_byte_swapping_data);
}

		
// ========================================  SET INTERFACE VALUES  ==================================================
void TartiEditForm::SetValues()
{
	int i;
	
	SetTag( 10101, '.256', def.collection_tag );
	SetTag( 10103, 'mons', def.monster_restriction_tag );

	XGPopControl* pList;
	pList = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 10105 ));
	assert(pList);
	pList->DeleteAll();
	pList->Insert(0, "None");
	pList->Insert(1, "Bow");
	pList->Insert(2, "Sword");
	pList->SetValue( def.specialization_restriction );

	SetTag( 10107, 'stli', def.special_ability_string_list_tag );

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

	SetTag( 10111, 'proj', def.projectile_tags[_artifact_projectile_tag] );

	SetFloat( 10113, def.initial_charges_lower_bound );
	SetFloat( 10114, get_upper_bound( (float)def.initial_charges_lower_bound, (float)def.initial_charges_delta ) );

	if( def.flags & _artifact_overrides_owner_attack_flag )
		SetFlag( 10115, TRUE );
	else
		SetFlag( 10115, FALSE );
	if( def.flags & _artifact_vanishes_after_last_charge_flag )
		SetFlag( 10116, TRUE );
	else
		SetFlag( 10116, FALSE );
}


// ========================================  GET INTERFACE VALUES  ==================================================
void TartiEditForm::GetValues()
{
	def.collection_tag = GetTag( 10101 );
	def.monster_restriction_tag = GetTag( 10103 );

	XGPopControl* pList;
	pList = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 10105 ));
	assert(pList);
	def.specialization_restriction = pList->GetValue();

	def.special_ability_string_list_tag = GetTag( 10107 );

	XGPopControl* pList2;
	pList2 = dynamic_cast<XGPopControl*>(GetWindow()->FindViewByID( 10109 ));
	assert(pList2);
	def.sequence_indexes[_artifact_sequence_inventory] = pList->GetValue();

	def.projectile_tags[_artifact_projectile_tag] = GetTag( 10111 );

	def.initial_charges_lower_bound = GetFloat( 10113 );
	def.initial_charges_delta = get_delta( (float)GetFloat( 10113 ), (float)GetFloat( 10114 ) );

	def.flags = 0;
	if( GetFlag( 10115 ) )
		def.flags |= _artifact_overrides_owner_attack_flag;
		
	if( GetFlag( 10116 ) )
		def.flags |= _artifact_vanishes_after_last_charge_flag;
}


