#include "gwfield.h"
#include <stdio.h>

static Field::FieldList fl;

void buildList();
void buildFakeContactList();
void extractFields( Field::FieldList );

int main()
{
	buildFakeContactList();
	// look for a field in the list
/*	if ( fl.find( NM_A_FA_MESSAGE ) != fl.end() )
		printf( "Found a field, where there was supposed to be one :)\n" );
	else
		printf( "Didn't find a field, where there was supposed to be one :(\n" );
	Field::FieldListIterator it;
	if ( (it = fl.find( NM_A_SZ_OBJECT_ID ) ) != fl.end() )
		printf( "Found a field, where there was NOT supposed to be one :(\n" );
	else
		printf( "Didn't find a field, where there wasn't supposed to be one :)\n" );*/
	//printf( "%i\n", static_cast<Field::MultiField*>(*it) );
	// dump the list
	fl.dump( true );
	
	printf( "\nNow testing find routines.\n");
	// find the field containing the contact list
	Field::MultiField * clf = dynamic_cast< Field::MultiField * >( *(fl.find( NM_A_FA_CONTACT_LIST ) ) );
	if ( clf )
	{
		Field::FieldList cl = clf->fields();
		// look for a folder in the list
		Field::FieldListIterator it = cl.find( NM_A_FA_FOLDER );
		if ( it != cl.end() )
			printf( "Found the first folder :)\n");
		else
			printf( "Didn't find the first folder, where did it go? :(\n");
		
		printf( "Looking for a second folder :)\n");
		it = cl.find( ++it, NM_A_FA_FOLDER );
		if ( it == cl.end() )
			printf( "Didn't find a second folder :)\n" );
		else
			printf( "Found a second folder, now did that get there? :(\n");
	}
	else 
		printf( "Didn't find the contact list, where did it go? :(\n");
				
	//extractFields( fl );
	return 0;
}
// test Field subclasses by creating various FieldLists and recovering the data

void buildList()
{
	// STRUCTURE
	//	fl - top list
	//		sf - faust quote
	//		mf - Multifield - participants, containing
	//			nl - nested list
	//				sf - contactlist (empty field array)
	//				sf - message body 
	
	Field::SingleField* sf = new Field::SingleField( NM_A_FA_MESSAGE, 0, NMFIELD_TYPE_UTF8, TQString::fromLatin1( "Da steh ich nun, ich armer Tor! Und bin so klug als wie zuvor..." ) );
	fl.append( sf );
	sf = new Field::SingleField( NM_A_SZ_TRANSACTION_ID, 0, NMFIELD_TYPE_UTF8, TQString::fromLatin1( "maeuschen" ) );
	fl.append( sf );
	// nested list
	Field::FieldList nl;
	sf = new Field::SingleField( NM_A_SZ_STATUS, 0, NMFIELD_TYPE_UDWORD, 123 );
	nl.append( sf );
	sf = new Field::SingleField( NM_A_SZ_MESSAGE_BODY, 0, NMFIELD_TYPE_UTF8, TQString::fromLatin1( "bla bla" ) );
	nl.append( sf );
	Field::MultiField* mf = new Field::MultiField( NM_A_FA_PARTICIPANTS, NMFIELD_METHOD_VALID, 0, NMFIELD_TYPE_ARRAY );
	mf->setFields( nl );
	fl.append( mf );
	
/*	Field::SingleField * ext = sf;
	printf( "tag: %s  flags: %i type: %i value: %s\n", ext->tag().data(), ext->flags(), ext->type(), ext->value().toString().ascii() );*/
}

void buildFakeContactList()
{
	using namespace Field;
	
	FieldList contactlist;
	// add a few contacts
	{
		const char* names[] = { "apple", "banana", "cherry", "damson", "elderberry", "framboise" };
		for ( int i = 0; i < 6; i ++ )
		{
			FieldList contact;
			Field::SingleField* sf = new Field::SingleField( NM_A_SZ_OBJECT_ID, 0, NMFIELD_TYPE_UTF8, TQString::number( i ) );
			contact.append( sf );
			sf = new Field::SingleField( NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, names[i] );
			contact.append( sf );
			MultiField* mf = new MultiField( NM_A_FA_CONTACT, NMFIELD_METHOD_VALID, 0, NMFIELD_TYPE_ARRAY, contact );
			contactlist.append( mf );
		}
	}
	// add a folder
	{
		FieldList folder;
		Field::SingleField* sf = new Field::SingleField( NM_A_SZ_OBJECT_ID, 0, NMFIELD_TYPE_UTF8, TQString::number( 1 ) );
		folder.append( sf );
		sf = new Field::SingleField( NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, "buddies" );
		folder.append( sf );
		MultiField* mf = new MultiField( NM_A_FA_FOLDER, NMFIELD_METHOD_VALID, 0, NMFIELD_TYPE_ARRAY, folder );
		contactlist.append( mf );
	}
	// add some more contacts
	{
		const char* names[] = { "aardvark", "boar", "cat" };
		for ( int i = 0; i < 3; i ++ )
		{
			FieldList contact;
			Field::SingleField* sf = new Field::SingleField( NM_A_SZ_OBJECT_ID, 0, NMFIELD_TYPE_UTF8, TQString::number( i ) );
			contact.append( sf );
			sf = new Field::SingleField( NM_A_SZ_DISPLAY_NAME, 0, NMFIELD_TYPE_UTF8, names[i] );
			contact.append( sf );
			MultiField* mf = new MultiField( NM_A_FA_CONTACT, NMFIELD_METHOD_VALID, 0, NMFIELD_TYPE_ARRAY, contact );
			contactlist.append( mf );
		}
	}
	
	
	MultiField * cl = new MultiField( NM_A_FA_CONTACT_LIST, NMFIELD_METHOD_VALID, 0, NMFIELD_TYPE_ARRAY, contactlist );
	fl.append( cl );
}

void extractFields( Field::FieldList l )
{
	Field::FieldListIterator it;
	printf ("iterating over %i fields\n", l.count() );
	for ( it = l.begin(); it != l.end() ; ++it )
	{
		printf ("field\n");
		Field::SingleField * ext = dynamic_cast<Field::SingleField *>( *it );
		if ( ext )
			printf( "tag: %s  flags: %i type: %i value: %s\n", ext->tag().data(), ext->flags(), ext->type(), ext->value().toString().ascii() );
		else
		{
			Field::MultiField* mf = dynamic_cast<Field::MultiField *>( *it );
			if ( mf )
			{
			 	printf( "found a multi value field\n" );
				extractFields( mf->fields() );
			}
		}
	}

	printf ("done\n");
}