#include "microdot.h"

#include "ogre.h"
#include "ogre_protos.h"

static int Done,usermode;
extern struct List brettlist;
static char *returnbrettname;

ALLOCSTATIC( returnbrettname, 160, MEMF_CLEAR )

static ULONG tics,secs;

#define GID_ULV 1
#define GID_UOK 2
#define GID_UCANCEL 3

static int multi;
static APTR resultpool;
static char **results;

static void selectentry( struct ogwin *ogw, char ch, int back )
{
	int offs = 0;
	int c, d;
	struct ogrevn *vn;

	vn = ogreLVGetEntry( ogw, GID_ULV, 0 );
	if( !vn )
		return;

	if( vn->txt[0] == '/' )
		offs = 1;

	d = ogreLVGetActive( ogw, GID_ULV ) + ( ( back ) ? - 1 : 1 );

	for( c = d; vn = ogreLVGetEntry( ogw, GID_ULV, c ); ( back ) ? c-- : c++ )
	{
		if( tolower( vn->txt[ offs ] ) == ch )
			goto found;
	}
	for( c = ( back ) ? ogreLVGetNumEntries( ogw, GID_ULV ) - 1 : 0; vn = ogreLVGetEntry( ogw, GID_ULV, c ); ( back ) ? c-- : c++ )
	{
		if( tolower( vn->txt[ offs ] ) == ch )
			goto found;
	}
	ogreLVSetActive( ogw, GID_ULV, -1 );
	return;

found:
	ogreLVSetActive( ogw, GID_ULV, c );
}

static struct user tempu;

char *douserreq( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	char *p;
	int Done = FALSE;
	struct ogrevn *vn;
	ULONG lastsecs = 0, lastmics = 0, oldval = 0, val;

	returnbrettname[0] = 0;

	ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, "Bitte UserIn auswählen:" );
	ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
	ogreAddList( ogw, 0, 0xff, NULL, GID_ULV, 60, 16, multi, NULL );
	ogreLVInit( ogw, GID_ULV );

	loaduserlist();
	ul2ogl( ogw, GID_ULV );

	ogreAddButton( ogw, 1 | OGB_ONENTER, '@', "OK", GID_UOK );
	ogreAddButton( ogw, 1 | OGB_ONESC, '\x1b', "Abbruch", GID_UCANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
	{
		freeuserlist( FALSE );
		return( NULL );
	}

	while( !Done )
	{

		im = ogreWaitIM( ogw );
		if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case GID_ULV:
					if( im->Qualifier == 1 )
						Done = 2;
					val = ogreLVGetLastActive( ogw, GID_ULV );
					if( DoubleClick( lastsecs, lastmics, im->Seconds, im->Micros ) && ( val == oldval ) && ( im->Qualifier == 2 ) )
						Done = 2;
					oldval = val;
					lastsecs = im->Seconds;
					lastmics = im->Micros;
					break;

				case GID_UOK:
					Done = 2;
					break;

				case GID_UCANCEL:
					Done = 1;
					break;
			}
		}
		else if( im->Class == IDCMP_RAWKEY && ! ( im->Code & 0x80 ) )
		{
			p = rawkeyconvert( im );

			*p = tolower( *p );

			if( *p >= 'a' && *p <= 'z' )
				selectentry( ogw, *p, im->Qualifier & QSHIFT );
		}
		ogreIMReply( ogw, im );
	}

	p = NULL;

	if( Done == 2 )
	{
		if( multi )
		{
			char **resultadder;

			resultpool = LibCreatePool( MEMF_CLEAR, 2048, 1024 );
			resultadder = results = LibAllocPooled( resultpool, ogreLVGetNumEntries( ogw, GID_ULV ) * 4 + 4 );

			vn = ogreLVGetEntry( ogw, GID_ULV, 0 );

			while( vn && vn->n.mln_Succ )
			{
				if( vn->sel )
				{
					struct muser *u = ( struct muser * ) vn->userdata;

					*resultadder = LibAllocPooled( resultpool, strlen( u->u.net ) + strlen( u->u.realname ) + 5 );
					if( u->u.realname[ 0 ] )
						sprintf( *resultadder++, "%s (%s)", u->u.net, u->u.realname );
					else
						strcpy( *resultadder++, u->u.net );
				}
				vn = ( struct ogrevn * ) vn->n.mln_Succ;
			}

		}
		else
		{
			vn = ogreLVGetEntry( ogw, GID_ULV, ogreValue( ogw, GID_ULV ) );
			if( vn )
			{
				struct muser *mu = vn->userdata;

				tempu = mu->u;
				if( mu->u.realname[0] )
					sprintf( returnbrettname, "%s (%s)", mu->u.net, mu->u.realname );
				else
					strcpy( returnbrettname, mu->u.net );
	
				p = returnbrettname;
			}
		}
	}

	freeuserlist( FALSE );

	ogreExitWindow( ogw );
	return( p );
}

int douserrequser( struct user *u )
{
	if( douserreq() )
	{
		*u = tempu;
		return( 1 );
	}
	return( 0 );
}

int brettreqshowpmboards;
char *dobrettreqtitle( char *windowtitle )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	char *p;
	int Done = FALSE;
	struct ogrevn *vn;
	ULONG lastsecs = 0, lastmics = 0, oldval = 0, val;
	struct mbrett *mb;

	returnbrettname[0] = 0;

	ogw = ogreInitWindow( scr, 0, 0, windowtitle );
	ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
	ogreAddList( ogw, 0, 0xff, NULL, GID_ULV, 60, 16, multi, NULL );
	ogreLVInit( ogw, GID_ULV );

	mb = (struct mbrett *) brettlist.lh_Head;
	while( mb->n.ln_Succ )
	{
		p = mb->b.name;
		if( p[0] == '/' && p[1] != '»' || ( brettreqshowpmboards && p[ 0 ] != '/' ) )
			ogreLVAddEntry( ogw, GID_ULV, p, FALSE, mb );
		mb = (struct mbrett *) mb->n.ln_Succ;
	}

	ogreAddButton( ogw, 1 | OGB_ONENTER, '@', "OK", GID_UOK );
	ogreAddButton( ogw, 1 | OGB_ONESC, '\x1b', "Abbruch", GID_UCANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
	{
		return( NULL );
	}

	while( !Done )
	{
		im = ogreWaitIM( ogw );
		if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case GID_ULV:
					if( im->Qualifier == 1 )
						Done = 2;
					val = ogreLVGetLastActive( ogw, GID_ULV );
					if( DoubleClick( lastsecs, lastmics, im->Seconds, im->Micros ) && ( val == oldval ) && ( im->Qualifier == 2 ) )
						Done = 2;
					oldval = val;
					lastsecs = im->Seconds;
					lastmics = im->Micros;
					break;

				case GID_UOK:
					Done = 2;
					break;

				case GID_UCANCEL:
					Done = 1;
					break;
			}
		}
		else if( im->Class == IDCMP_RAWKEY && ! ( im->Code & 0x80 ) )
		{
			p = rawkeyconvert( im );

			*p = tolower( *p );

			if( *p >= 'a' && *p <= 'z' )
				selectentry( ogw, *p, im->Qualifier & QSHIFT );
		}
		ogreIMReply( ogw, im );
	}

	p = NULL;

	if( Done == 2 )
	{
		if( multi )
		{
			char **resultadder;

			resultpool = LibCreatePool( MEMF_CLEAR, 2048, 1024 );
			resultadder = results = LibAllocPooled( resultpool, ogreLVGetNumEntries( ogw, GID_ULV ) * 4 + 4 );

			vn = ogreLVGetEntry( ogw, GID_ULV, 0 );

			while( vn && vn->n.mln_Succ )
			{
				if( vn->sel )
				{
					*resultadder = LibAllocPooled( resultpool, strlen( ( ( struct mbrett * ) vn->userdata ) -> b.name ) + 1 );
					strcpy( *resultadder++, ( ( struct mbrett * ) vn->userdata ) -> b.name );
				}
				vn = ( struct ogrevn * ) vn->n.mln_Succ;
			}

		}
		else
		{
			vn = ogreLVGetEntry( ogw, GID_ULV, ogreValue( ogw, GID_ULV ) );
			if( vn )
			{
				struct mbrett *mb = vn->userdata;
				strcpy( returnbrettname, mb->b.name );
				p = returnbrettname;
			}
		}
	}

	ogreExitWindow( ogw );
	return( p );
}

char *dobrettreq( void )
{
	return( dobrettreqtitle( "Bitte Brett auswählen..." ) );
}

char *dobrettreqmulti( void )
{
	if( results )
	{
		if( *results )
			return( *results++ );
		else
		{
			results = NULL;
			LibDeletePool( resultpool );
			return( NULL );
		}
	}

	multi = TRUE;
	dobrettreq();
	multi = FALSE;

	if( results )
		return( dobrettreqmulti() );
	return( NULL );
}

char *douserreqmulti( void )
{
	if( results )
	{
		if( *results )
			return( *results++ );
		else
		{
			results = NULL;
			LibDeletePool( resultpool );
			return( NULL );
		}
	}

	multi = TRUE;
	douserreq();
	multi = FALSE;

	if( results )
		return( douserreqmulti() );
	return( NULL );
}
