
#include <intuition/intuition.h>
#include <intuition/classes.h>
#include <intuition/classusr.h>
#include <intuition/imageclass.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/gadtools_protos.h>

#include <stdio.h>
#include <ctype.h>

#include "project.h"

extern void ComputeFont( UWORD , UWORD );

extern UWORD ComputeX( UWORD );
extern UWORD ComputeY( UWORD );

struct Window	      *CListeWnd = NULL;
struct Gadget	      *CListeGList = NULL;
struct Gadget	      *CListeGadgets[3];

UWORD CListeGTypes[] = {
	LISTVIEW_KIND,
	BUTTON_KIND,
	BUTTON_KIND
};

struct NewGadget CListeNGad[] = {
	3, 5, 267, 160, NULL , NULL, 1, PLACETEXT_ABOVE, NULL, NULL,
	19 , 165 , 100 , 15 , (UBYTE *)"Edit" , NULL , 2 , PLACETEXT_IN , NULL , NULL,
	155 , 165 , 100 , 15 , (UBYTE *)"Cancel" , NULL , 3 , PLACETEXT_IN , NULL , NULL,
};

ULONG CListeGTags[] = {
	(GT_Underscore), '_', (GTLV_ShowSelected), NULL, (TAG_DONE),
	(GT_Underscore), '_', (TAG_DONE),
	(GT_Underscore), '_', (TAG_DONE),
};

int OpenCListeWindow( char *title )
{
	struct NewGadget	ng;
	struct Gadget	*g;
	UWORD		lc, tc;
	UWORD		wleft = 205, wtop = 140, ww=274, wh=185;

	ComputeFont( 140 , 274 );

	ww = ComputeX( 274 );
	wh = ComputeY( 185 );

	if (( wleft + ww + OffX + Scr->WBorRight ) > Scr->Width ) wleft = Scr->Width - ww;
	if (( wtop + wh + OffY + Scr->WBorBottom ) > Scr->Height ) wtop = Scr->Height - wh;

	if ( ! ( g = CreateContext( &CListeGList )))
		return( 1L );

	for( lc = 0, tc = 0; lc < 3; lc++ ) {

		CopyMem((char * )&CListeNGad[ lc ], (char * )&ng, (long)sizeof( struct NewGadget ));

		ng.ng_VisualInfo = VisualInfo;
		ng.ng_TextAttr	 = Font;
		ng.ng_LeftEdge = OffX + ComputeX( ng.ng_LeftEdge );
		ng.ng_TopEdge = OffY + ComputeY( ng.ng_TopEdge );
		ng.ng_Width = ComputeX( ng.ng_Width );
		ng.ng_Height = ComputeY( ng.ng_Height);

		if ( !lc )
		    ng.ng_GadgetText = title;
		CListeGadgets[ lc ] = g = CreateGadgetA((ULONG)CListeGTypes[ lc ], g, &ng, ( struct TagItem * )&CListeGTags[ tc ] );

		while( CListeGTags[ tc ] ) tc += 2;
		tc++;

		if ( NOT g )
			return( 2L );
	}

	if ( ! ( CListeWnd = OpenWindowTags( NULL,
				WA_Left,	wleft,
				WA_Top, 	wtop,
				WA_Width,	ww + OffX + Scr->WBorRight,
				WA_Height,	wh + OffY + Scr->WBorBottom,
				WA_IDCMP,	LISTVIEWIDCMP|IDCMP_REFRESHWINDOW|IDCMP_VANILLAKEY|IDCMP_RAWKEY,
				WA_Flags,	WFLG_SMART_REFRESH,
				WA_Gadgets,	CListeGList,
				WA_Activate,	TRUE,
				WA_PubScreen,	     Scr,
				TAG_DONE )))
	return( 4L );

	GT_RefreshWindow( CListeWnd, NULL );

	return( 0L );
}

void CloseCListeWindow( void )
{
	if ( CListeWnd        ) {
		CloseWindow( CListeWnd );
		CListeWnd = NULL;
	}

	if ( CListeGList      ) {
		FreeGadgets( CListeGList );
		CListeGList = NULL;
	}
}


void UpDateList( long select ) {
  long topsel;

    GT_SetGadgetAttrs( CListeGadgets[0] , CListeWnd , NULL , GTLV_Selected , select , TAG_DONE );
    topsel = select-5;
    if ( topsel<0 )
	topsel = 0;
    GT_SetGadgetAttrs( CListeGadgets[0] , CListeWnd , NULL , GTLV_Top , topsel , TAG_DONE );
}

/****************************************************************
***	Affiche une liste ou choisir un élément 	      ***
****************************************************************/

struct Node *ChooseInList( char *title , struct List *liste , long x , long y ) {
  BOOL			done=FALSE;
  struct IntuiMessage	*m;
  ULONG 		sec=-1,mic;
  int			n;
  struct Node		*wn=NULL;
  long			select;

    SleepWinC( );
    if ( !OpenCListeWindow( title ) ) {
	GT_SetGadgetAttrs( CListeGadgets[0] , CListeWnd , NULL , GTLV_Labels , (long)liste , TAG_DONE );
	while ( !done ) {
	    Wait( 1 << CListeWnd->UserPort->mp_SigBit );
	    while( m = GT_GetIMsg( CListeWnd->UserPort )) {
		GT_ReplyIMsg( m );
		switch ( m->Class ) {
		  case IDCMP_CLOSEWINDOW:
		    wn = NULL;
		    done = TRUE;
		    break;
		  case IDCMP_GADGETUP:
		    n = ((struct Gadget *)m->IAddress)->GadgetID;
		    switch( n ) {
		      case 1:
			select = n = m->Code;
			wn = liste->lh_Head;
			while( wn->ln_Succ && n-- ) {
			    wn = wn->ln_Succ;
			}
			if ( sec != -1 && DoubleClick( sec , mic , m->Seconds , m->Micros ) )
			    done = TRUE;
			sec = m->Seconds;
			mic = m->Micros;
			break;
		      case 3:
			wn = NULL;
		      case 2:
			done = TRUE;
			break;
		    }
		    break;
		case	IDCMP_RAWKEY:
		    switch( m->Code ) {
		      case CURSORUP:
			if ( !wn ) {
			    wn = liste->lh_Head;
			    select = 0;
			    while( wn->ln_Succ->ln_Succ ) {
				wn = wn->ln_Succ;
				select++;
			    }
			} else {
			    if ( wn->ln_Pred->ln_Pred ) {
				wn = wn->ln_Pred;
				select--;
			    }
			}
			UpDateList( select );
			break;
		      case CURSORDOWN:
			if ( !wn ) {
			    wn = liste->lh_Head;
			    select = 0;
			} else {
			    if ( wn->ln_Succ->ln_Succ ) {
				wn = wn->ln_Succ;
				select++;
			    }
			}
			UpDateList( select );
			break;
			}
		    break;

		  case IDCMP_VANILLAKEY:
		    switch( m->Code ) {
		      case 27:
			wn = NULL;
		      case 13:
			done = TRUE;
			break;
		      default:
			if ( isalpha( m->Code ) )
			{
			  struct ModuleNode *bn;
			  BOOL found = FALSE;
			  long sel = 0;

			    bn = liste->lh_Head;
			    m->Code = tolower( m->Code );
			    while( bn->node.ln_Succ && !found ) {
				if ( tolower(*bn->node.ln_Name) == m->Code ) {
				    found = TRUE;
				    break;
				}
				sel++;
				bn = bn->node.ln_Succ;
			    }
			    if ( found ) {
				wn = bn;
				select = sel;
				UpDateList( sel );
			    }
			}
			break;
		    }
		}
	    }
	}
	CloseCListeWindow( );
    }
    AwakeWinC( );
    return( wn );
}
