#include "tags.h"
#include "tagprivate.h"

#include "stli.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 <XTextControls.h>


// ==============================  BYTE SWAPPING DATA  ========================================


// ==============================  EDIT WINDOW  ========================================
void edit_stli( tag_entry* e )
{
	TstliEditForm* form = new TstliEditForm( e );
	form->AttachWindow( 1024 );
}

void defaultnew_stli( tag_entry *e )
{
	// nop
}

// ==============================  READ TAG DATA  ========================================
bool read_string_list_definition( string_list_definition* def, tag_entry* e )
{
	// text data is saved in Mac format (\r only), yaaf likes \n for it's text box display
	const void *data;
	int ii;
	
	if( e->length )
	{
		if( get_entry_data( e, &data, (unsigned *)&def->string_length ) )
		{
			memcpy( def->string_buffer, data, def->string_length );
			def->string_buffer[def->string_length] = '\0'; 
		
			// happy fun text formatting
			for( ii = 0; ii < def->string_length; ii++ )
			{
				if( def->string_buffer[ii] == '\r' )
					def->string_buffer[ii] = '\n';
			}
			
			return TRUE;
		}
	}
	else
	{
		def->string_length = 0;
		def->string_buffer[0] = '\0';
		return TRUE;
	}
	
	return FALSE;
}


// ==============================  SAVE TAG DATA  ========================================
bool save_string_list_definition( string_list_definition* def, tag_entry* e )
{
	// text data is saved in Mac format (\r only), yaaf likes \n for it's text box display
	int ii;
	
	// happy fun text formatting
	for( ii = 0; ii < def->string_length; ii++ )
	{
		if( def->string_buffer[ii] == '\n' )
			def->string_buffer[ii] = '\r';
	}
	
	set_entry_data( e, def->string_buffer, def->string_length, FALSE );

	// I have to assume that set_entry_data worked	
	return TRUE;
}


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


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

	return save_string_list_definition( def, e );
}


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


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

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

}


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

	return -1;
}


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


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


// ========================================  TAG NEEDS UPDATING  ==================================================
bool TstliEditForm::NeedCommit()
{
	string_list_definition original;
	int ii;
	
	GetValues();

	// get the definition from the tag
	if( !read_string_list_definition( &original, fEntry ) )
		return TRUE;

	// happy fun text formatting
	for( ii = 0; ii < original.string_length; ii++ )
	{
		if( original.string_buffer[ii] == '\r' )
			original.string_buffer[ii] = '\n';
	}
	
	if( original.string_length == def.string_length )
		return memcmp( original.string_buffer, def.string_buffer, original.string_length );
	
	return TRUE;
}


// ========================================  SET INTERFACE VALUES  ==================================================
void TstliEditForm::SetValues()
{
	XGEditText *pEdit = dynamic_cast<XGEditText *>(GetWindow()->FindViewByID( 12401 ));
	
	pEdit->SetTitle( def.string_buffer );
}


// ========================================  GET INTERFACE VALUES  ==================================================
void TstliEditForm::GetValues()
{
	XGEditText *pEdit = dynamic_cast<XGEditText *>(GetWindow()->FindViewByID( 12401 ));

	def.string_length = pEdit->GetTitleEx( def.string_buffer, MAX_STRINGLIST_SIZE );
	
	// special case thing for 0 length strings (save a NUL to the tag)
	if( def.string_length == 0 )
	{
		def.string_length = 1;
		def.string_buffer[0] = '\0';
	}
}


// misc stringlist support stuff
int count_strings_in_list( tag_entry *e )
{
	int ii;
	int count = 0;
	
	const void *tag_data;
	unsigned tag_length;
	
	get_entry_data( e, &tag_data, &tag_length );
	if( !tag_data || !tag_length )
		return -1;
	
	for( ii = 0; ii < e->length; ii++ )
	{
		if( ((char *)e->data)[ii] == '\n' )
			count++;
	}
	
	return count;
}

int get_string_at_index( tag_entry *e, int index, char *string, int max_length )
{
	int ii, jj;
	int count = index;
	int len;
	
	const void *tag_data;
	unsigned tag_length;
	
	get_entry_data( e, &tag_data, &tag_length );
	if( !tag_data || !tag_length )
		return -1;
	
	for( ii = 0; ii < e->length && count; ii++ )
	{
		if( ((char *)e->data)[ii] == '\n' )
			count--;
	}
	
	for( jj = ii; jj < e->length; jj++ )
	{
		if( ((char *)e->data)[jj] == '\n' )
			break;
	}
	
	len = ((jj - ii) > max_length) ? max_length : (jj - ii);
	memcpy( string, &((char *)e->data)[ii], len );
	string[len] = '\0';
	
	return len;
}
