/****************************************************************************/
/*                                                                          */
/*  listbox.c                                                               */
/*                                                                          */
/*  Implementation du package listbox.pkg                                   */
/*                                                                          */
/****************************************************************************/

#include "x/Version.h"
#include "x/scolplugin.h"

#include "objstr.h"


#include <stdio.h>
#include <string.h>

#include "tests.h"
#include "objects/font.h"
#include "events.h"
#include "objects/listbox.h"
 

WNDPROC ListProc = NULL ;

int SCSlistKeyup(mmachine m, HWND list, int Key) 
{
  int k;

//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nSCSlistKeyup");
#endif
//***********************************

  /* reflex pour les fenetres windows */
  k = OBJbeginreflex(m,OBJTYPLISTBOX,(int)list,RFLLISTBOX_KEYUP) ;
  if(k==0)
    {
      if (MMpush(m,Key<<1)) return MERRMEM ;
      return OBJcallreflex(m,1) ;
    }
  if (k<0) return 0 ;
  return 1;
}

int SCSlistKeydown(mmachine m,HWND list, int scancode, int KeyData)
{
  int k ;

//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nSCSlistKeydown");
#endif
//***********************************

  /***************** reflex pour les fenetres windows *******************/
  k = OBJbeginreflex(m,OBJTYPLISTBOX,(int)list,RFLLISTBOX_KEYDOWN) ;
  if(k==0)
    {
      if(MMpush(m,scancode<<1)) return MERRMEM ;
      if(MMpush(m,KeyData<<1)) return MERRMEM ;
      return OBJcallreflex(m,2) ;
    }
  if(k<0) return 0 ;
  return 1;
}

/*********************************************************************************************/
/*                                                                                           */
/*  LRESULT CALLBACK ListProcBis ( HWND hwnd , unsigned msg , UINT wParam , LONG lParam ) ;  */
/*                                                                                           */
/* Winproc pour les list box                                                                 */
/*                                                                                           */
/*********************************************************************************************/

LRESULT CALLBACK ListProcBis ( HWND hwnd , unsigned msg , UINT wParam , LONG lParam )
{
    int c;
    switch ( msg ) 
    {
	    case WM_KEYUP :
            if ( wParam == 13 ) GRTestDefaultButton ( GetParent ( hwnd )) ;
            if ( wParam == 9 )
            {
              // To avoid the event on new focused window
              msg = 0;
              GRTestTabFocus ( hwnd , OBJTYPLISTBOX ) ;
            }
            SCSlistKeyup(mm,hwnd,(lParam>>16)&0x1ff);
            tstscoldead(215) ;

           break ;

	    case WM_KEYDOWN :
            c=convertvirtcode((int)wParam);
            if (c==0) break;
            SCSlistKeydown (mm,hwnd,(lParam>>16)&0x1ff,c);
            tstscoldead(216);

           break ;

       case WM_DROPFILES : SCOLDropFiles ( mm,hwnd,(HANDLE)wParam,OBJTYPLISTBOX,RFLLISTBOX_DROPFILE);
            break;

        default : break;
    }

    return CallWindowProc ( ListProc , hwnd , msg , wParam , lParam ) ;
}



/*****************************************************************************/
/*                                                                           */
/* HWND NewObjListBox ( PtrObjCombo Cb , char * Name , HWND Parent ) ;       */
/*                                                                           */
/*  Fonction de creation d'une liste box                                     */
/*                                                                           */
/*****************************************************************************/

HWND NewObjListBox ( PtrObjCombo Cb , char * Name , HWND Parent ) 
{
    int Flags , FF ;
    int Ex_Flag = 0 ;

    Flags = LBS_NOINTEGRALHEIGHT ; FF = Cb->Flags  ;
    
    if ( Parent != NULL ) Flags |= WS_CHILD | LBS_NOTIFY   ;
    if ( FF & LBF_VSCROLL ) Flags |= WS_VSCROLL ;    
    if ( FF & LBF_HSCROLL ) Flags |= WS_HSCROLL ;
    if ( FF & LBF_NOSELECTION ) Flags |= LBS_NOSEL ;
    if ( FF & LBF_MULTICOLUMN ) Flags |= LBS_MULTICOLUMN ;
    if ( FF & LBF_BORDER ) Flags |= WS_BORDER ;
    if ( FF & LBF_TABFOCUS  ) Flags |= WS_TABSTOP ;
    if ( FF & LBF_MULTIPLE ) Flags |= LBS_EXTENDEDSEL ;
    if ( FF & LBF_DOWN ) Ex_Flag |= WS_EX_CLIENTEDGE ;
    if ( FF & LBF_DRAGDROP ) Ex_Flag |= WS_EX_ACCEPTFILES ;


    return CreateWindowEx ( Ex_Flag , "listbox" , Name , Flags ,
                        Cb->PosX , Cb->PosY  ,
                        Cb->TailleW , Cb->TailleH ,
                        Parent , NULL ,
                        (HINSTANCE)SCgetExtra("this_inst") , NULL );
}



int GRpushListElement(mmachine m,HWND Child,int pos)
{
	int szlist;
	char *plist;

	szlist=SendMessage ( Child , LB_GETTEXTLEN ,( WPARAM ) pos,0 ) ;
	if (szlist==LB_ERR) return MMpush(m,NIL);
	plist=(char*)malloc(szlist+1);
	if (plist==NULL) return MMpush(m,NIL);
	plist[0]=0;
	SendMessage ( Child , LB_GETTEXT ,( WPARAM ) pos, ( LPARAM ) plist ) ;
	if ( Mpushstrbloc(m,plist)) return MERRMEM ;
	free(plist);
	return 0;
}

/*************************************************************************************/
/*                                                                                   */
/*  int GRCreateListBox ( mmachine m )                                               */
/*                                                                                   */
/*  correspond a la fonction magma Obj _create_list_box ( Obj Parent , I PosX ,      */
/*  I PosY , I TAilleW , I TailleH , I Flag , I MH , S Name, Channel )               */
/*                                                                                   */
/*************************************************************************************/

int GRCreateListBox ( mmachine m )
{
 int s , s2 , l ,  res ;
   PtrObjVoid O , OP ;
   PtrObjCombo Cb ;
   PtrObjWindow PW ;
   HWND Parent , HW ;
   char Name [1024 ] ;

   /**************************** DEBUG 2D *********************************/
    #ifdef TRACE2D
        MMechostr( 1 , "DBG _create_list_box\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /************************************************************************/

    /* test channel != NIL */
    if (MMget(m,6)==NIL)
    {
        MMechostr(MSKDEBUG,"_CRlist : channel is NIL\n");
        m->pp+=6;
        MMset(m,0,NIL);
        return 0;
    }
   
    strcpy ( Name , "TestListBox" ) ;

    l = ( sizeof ( struct ObjVoid ) + 3 ) >> 2 ;
    s = MMmallocCLR (m,l,TYPETAB) ;
    if ( s == NIL ) return MERRMEM ;
    if ( MMpush(m,(s<<1)+1)) return MERRMEM ;
    l = ( sizeof ( struct ObjCombo ) + 3 ) >> 2 ;
    s2 = MMmalloc ( m,l,TYPEBUF ) ;
    if ( s2 == NIL ) return MERRMEM ;
    s = MMpull(m) ;

    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;
    Cb = ( PtrObjCombo ) MMstart(m, s2 ) ;
    O->Type = OBJ_TYPE_LIST_BOX << 1 ;
    O->Buffer = ( s2 << 1 ) + 1 ;
    O->Tab = NIL ;    
    Cb->Flags = MMpull(m) >> 1 ;
    Cb->TailleH = MMpull(m) >> 1 ;
    Cb->TailleW = MMpull(m) >> 1 ;  
    Cb->PosY = MMpull(m) >> 1 ;
    Cb->PosX = MMpull(m) >> 1 ;
    O->Father = MMpull(m) ;

    /* recuperation du handler window du parent, si parent il y a */
    if ( O -> Father == NIL )
    {
        MMechostr(MSKDEBUG,"_CRlist : Parent is NIL\n");
        MMset(m,0,NIL);
        return 0;
    }
    else
    {
        OP = ( PtrObjVoid ) MMstart(m, (O->Father>>1) ) ;
        if ( OP->Type != OBJ_TYPE_WINDOW << 1 )
        {
            MMechostr ( 1 , "CreateListBox : Parent is'nt a window\n" ) ;
			MMpull(m);
            return MMpush(m,NIL) ;
        }
        PW = ( PtrObjWindow ) MMstart(m, (OP->Buffer >> 1 ) ) ;
        Parent = PW->WHandler ;
    }

    HW = NewObjListBox ( Cb , Name , Parent  ) ;    
    if ( ! HW )
    {
        MMechostr(MSKDEBUG,"_create_list_box : Error in creating the WIN Object : Check the values\n" ) ;
        MMpull(m);
		return MMpush(m,NIL) ;
    }
    Cb->WHandler = HW ;

    if ( ListProc == NULL ) ListProc = ( WNDPROC ) GetWindowLong ( HW , GWL_WNDPROC ) ;
    SetWindowLong ( HW , GWL_WNDPROC , ( long ) ListProcBis ) ;
    if ( DefaultFont != NULL ) 
      SendMessage ( HW , WM_SETFONT , ( WPARAM ) DefaultFont , ( LPARAM ) TRUE ) ;      

    ShowWindow(HW,SW_SHOW);
    UpdateWindow(HW);
    
          
    if ( MMpush ( m , s )) return MERRMEM ;
    res = OBJcreate ( m , OBJTYPLISTBOX , (int)HW,OBJTYPWINDOW,(int)Parent) ;    
    /******************************* DEBUG 2D ********************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr( 1 , "DBG _create_list_box\n" ) ;
    #endif
    /***************************************************************/

    return res ;


}           

/********************************************************************************************/
/*                                                                                          */
/*  int GRAddListItem ( mmachine m ) ;                                                      */
/*                                                                                          */
/*  correspond a la fonction ObjList _add_list_item ( ObjList , S , I )                     */
/*  laquelle ajoute un element a une listbox a une certaine position                        */
/*                                                                                          */
/********************************************************************************************/

int GRAddListItem ( mmachine m )
{
    int s , s2 , pos , res ;
    PtrObjVoid O ;
    PtrObjCombo C ;
    char Name [33000 ] ;

    /******************************* DEBUG 2D **********************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _add_list_item\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /***************************************************************************************/
    
    s2 = MMpull ( m ) ;
    pos = MMpull ( m ) >> 1 ;
    s = MMpull ( m ) ;

    if ( s2 != NIL )
    {
        strcpy ( Name , (  char * ) MMstart(m, (s2>>1 ) + 1) ) ;
        if ( s != NIL )
        {
            O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
            C = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1) ) ;        
            res = SendMessage ( C->WHandler , LB_GETCOUNT , 0 , 0 ) ;
            if ( res != LB_ERR && pos >= res ) pos = -1 ;  /* cas insertion en queue */
            SendMessage ( C->WHandler , LB_INSERTSTRING , ( WPARAM ) pos , ( LPARAM ) Name ) ;
        } else MMechostr ( MSKDEBUG , "_add_list_item : Object ListBox is NIL\n" ) ;
    } else MMechostr ( MSKDEBUG , "_ADDlist string is NIL\n" ) ;
    res = MMpush(m,s) ;


    /********************** DEBUG 2D *********************************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _add_list_item done\n" ) ;
    #endif
    /******************************************************************************************/

    return res ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRDelListItem ( mmachine m ) ;                                                      */
/*                                                                                          */
/*  correspond a la fonction ObjList _del_list_item ( ObjList , I ) ;                       */
/*  laquelle suprime un element selon sa position                                           */
/*                                                                                          */
/********************************************************************************************/

int GRDelListItem       ( mmachine m )
{
    int s , pos ; 
    PtrObjVoid O ;
    PtrObjCombo B ;

    /****************************** DEBUG 2D ************************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _del_list_item\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /****************************************************************************************/

    pos = MMpull ( m ) >> 1 ;
    s = MMpull ( m ) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        B = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1 ) ) ;
        SendMessage ( B->WHandler , LB_DELETESTRING , ( WPARAM ) pos , ( LPARAM ) 0 ) ;
    }
    pos = MMpush(m,s ) ;

    /************************** DEBUG 2D ****************************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _del_list_item done\n" ) ;
    #endif
    /****************************************************************************************/

    return pos ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRDelListString ( mmachine m ) ;                                                    */
/*                                                                                          */
/*  correspond a la fonction ObjList _del_list_string ( ObjList , S ) ;                     */
/*  laquelle supprime un element                                                            */
/*                                                                                          */
/********************************************************************************************/

int GRDelListString     ( mmachine m ) 
{
    int s , pos ;
    PtrObjVoid O ;
    PtrObjCombo L ;
    char Name [33000] ;

    /**************************** DEBUG 2D **************************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _del_list_string\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /****************************************************************************************/

    pos = MMpull ( m ) ;
    if ( pos == NIL ) return 0 ;
    else strcpy ( Name , ( char * ) MMstart(m,(pos>>1) + 1) ) ;
    s = MMpull ( m ) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        L = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1) ) ;
        pos = SendMessage ( L->WHandler , LB_FINDSTRINGEXACT , ( WPARAM )-1 , ( LPARAM ) Name ) ;
        if ( pos != LB_ERR ) SendMessage ( L->WHandler , LB_DELETESTRING , ( WPARAM ) pos , ( LPARAM ) 0 ) ;
    }
    pos = MMpush ( m , s ) ;

    /********************************* DEBUG 2D**********************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _del_list_string done\n" ) ;
    #endif
    /*****************************************************************************************/

    return pos ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRSelectListItem ( mmachine m ) ;                                                   */
/*                                                                                          */
/*  correspond a la fonction ObjList _select_list_item ( ObjList , I ) ;                    */
/*  laquelle selectionne un element d'une list box d'apres sa position                      */
/*                                                                                          */
/********************************************************************************************/

int GRSelectListItem    ( mmachine m )
{
    int s , pos ; 
    PtrObjVoid O ;
    PtrObjCombo L ;

    /*************************************** DEBUG 2D ***************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _select_list_item\n" ) ;
        FDebug2D (m )  ;
    #endif
    /****************************************************************************************/

    pos = MMpull( m ) >> 1 ;
    s = MMpull ( m ) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        L = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1) ) ;
        pos = SendMessage ( L->WHandler ,LB_SETCURSEL, (WPARAM) pos,( LPARAM ) 0);
        if ( pos == LB_ERR )
        {
            MMechostr ( 1 , "Wrong position in select_list_item\n" ) ;
            pos = NIL ;
        }
      
     }

    pos =  MMpush( m , s ) ;

    /********************************* DEBUG 2D *********************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _select_list_item done\n" ) ;
    #endif
    /**************************************************************************************/

    return pos ;

}

/********************************************************************************************/
/*                                                                                          */
/*  int GRSelectListString ( mmachine m ) ;                                                 */
/*                                                                                          */
/*  correspond a la fonction ObjList _select_list_string ( ObjList , S ) ;                  */
/* laquelle selectionne un element d'une liste box                                          */
/*                                                                                          */
/********************************************************************************************/

int GRSelectListString ( mmachine m ) 
{
    int s,k ;
    PtrObjVoid O ;
    PtrObjCombo C ;
    char * Name ;

    /********************************* DEBUG 2D *********************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _select_list_string\n" ) ;
        FDebug2D ( m ) ;
    #endif

    s = MMpull ( m ) ;
    if ( s == NIL )  return 0 ;
    Name = ( char * ) MMstart(m,(s>>1) + 1) ;
    s = MMpull( m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        C = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1) ) ;
        k=SendMessage ( C->WHandler , LB_FINDSTRINGEXACT , ( WPARAM ) -1 , ( LPARAM ) Name );
		if (k==LB_ERR) SendMessage ( C->WHandler , LB_SELECTSTRING , ( WPARAM ) -1 , ( LPARAM ) Name );
		else SendMessage ( C->WHandler ,LB_SETCURSEL, (WPARAM) k,( LPARAM ) 0);
 ;
    }
    s = MMpush( m , s ) ;

    /********************************* DEBUG 2D *********************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _select_list_string done\n" ) ;
    #endif
    /*****************************************************************************************/

    return s ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRGetListPosition ( mmachine m ) ;                                                  */
/*                                                                                          */
/*  correspond a la fonction I _get_list_item_position ( ObjList , S ) ;                    */
/*  laquelle retourne la position d'un element dans la list box                             */
/*                                                                                          */
/********************************************************************************************/

int GRGetListPosition   ( mmachine m )
{
    int s2 , s ,res ;
    char * Element ;
    PtrObjVoid O ;
    PtrObjCombo B ;

    /******************************** DEBUG 2D *********************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _get_list_position\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /***************************************************************************************/
    
     s2 = MMpull ( m ) ;
     s = MMpull ( m ) ;
     if ( s == NIL || s2 == NIL )
     {
//         MMpull ( m ) ;
         return MMpush( m , NIL ) ;
     }
     Element = ( char * ) MMstart(m,(s2>>1 ) + 1) ;
     O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
     B = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1) ) ;
     res = SendMessage ( B->WHandler , LB_FINDSTRINGEXACT , ( WPARAM ) -1 , ( LPARAM ) Element ) ;
     if ( res == LB_ERR ) res = MMpush(m,NIL ) ;
     else res = MMpush(m,res<<1) ;

     /*************************** DEBUG 2D ***************************************************/
     #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _get_list_position done\n" ) ;
    #endif
    /******************************************************************************************/
    
        return res ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRReflextListClick ( mmachine m ) ;                                                 */
/*                                                                                          */
/*  correspond a la fonction ObjList _reflex_list_click ( ObjList , fun , u0 ) ;            */
/*   qui definit le callback pour le click simple d'un element de la list box               */
/*                                                                                          */
/********************************************************************************************/

int GRReflexListClick   ( mmachine m ) 
{
    return OBJaddreflex(m,OBJTYPLISTBOX,RFLLISTBOX_CLICK) ;    
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRReflexListKeyDown ( mmachine m ) ;                                               */
/*                                                                                          */
/*  correspond a la fonction ObjList _reflex_list_keydown ( ObjList , fun , u0 ) ;          */
/*   qui definit le callback pour le clavier d'un element de la list box                    */
/*                                                                                          */
/********************************************************************************************/
//$BB
int GRReflexListKeyDown   ( mmachine m ) 
{
    return OBJaddreflex(m,OBJTYPLISTBOX,RFLLISTBOX_KEYDOWN) ;    
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRReflexListKeyUp ( mmachine m ) ;                                                 */
/*                                                                                          */
/*  correspond a la fonction ObjList _reflex_list_keydown ( ObjList , fun , u0 ) ;          */
/*   qui definit le callback pour le clavier d'un element de la list box                    */
/*                                                                                          */
/********************************************************************************************/
//$BB
int GRReflexListKeyUp   ( mmachine m ) 
{
    return OBJaddreflex(m,OBJTYPLISTBOX,RFLLISTBOX_KEYUP) ;    
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRReflexDCLick ( mmachine m ) ;                                                     */
/*                                                                                          */
/*  correspond a la fonction ObjList _reflex_list_dclick ( ObjList , fun , u0 ) ;           */
/*  qui definit le callback pour le double click d'un element de la list box                */
/*                                                                                          */
/********************************************************************************************/

int GRReflexListDClick  ( mmachine m )  
{
    return OBJaddreflex(m,OBJTYPLISTBOX,RFLLISTBOX_DCLICK) ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRReflexListDropFile ( mmachine m ) ;                                               */
/*                                                                                          */
/*  correspond a la fonction ObjListBox _CBlistDropFile (ObjList,fun,u0 ) ;                 */
/*  qui definit le callback pour le drop file du drag&drop sur une listbox                  */
/*                                                                                          */
/********************************************************************************************/

int GRReflexListDropFile ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPLISTBOX,RFLLISTBOX_DROPFILE ) ;
}


/********************************************************************************************/
/*                                                                                          */
/*  int GRDestroyList ( mmachine m ) ;                                                      */
/*                                                                                          */
/*  correspond a la fonction I _destroy_list_box ( ObjList ) ,;                             */
/* laquelle detruit un objet listbox                                                        */
/*                                                                                          */
/********************************************************************************************/

int GRDestroyList       ( mmachine m )
{
int s ;
    PtrObjVoid O ;
    HWND h ;

    /************************** DEBUG 2D ******************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _destroy_obj_list\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /*********************************************************/

    s = MMget(m,0) ;
    if ( s!=NIL) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        h = (( PtrObjCombo ) ( MMstart(m, (O->Buffer>>1 )) ))->WHandler ;
        OBJdelTH(m,OBJTYPLISTBOX,(int)h) ;
    }    

    /********************** DEBUG 2D *************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr( 1 , "DBG _destroy_obj_list Done\n" ) ;
    #endif
    /***********************************************************/

    MMset(m,0,0) ;
    return 0 ;
}

/********************************************************************************************/
/*                                                                                          */
/*  int GRGetListCount ( mmachine m ) ;                                                     */
/*                                                                                          */
/*  correspond a la fonction magma I _get_list_count ( ObjList ) ;                          */
/*  laquelle renvoi le nombre d'element d'une listbox                                       */
/*                                                                                          */
/********************************************************************************************/

int GRGetListCount ( mmachine m ) 
{
    int s , res ;
    PtrObjVoid O ;
    PtrObjCombo B ;

    /******************************** DEBUG 2D **********************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG get_list_count\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /*****************************************************************************************/

    s = MMpull(m) ;
    if ( s == NIL ) 
    {
        MMechostr ( 1 , "DBG listbox NIL\n" ) ;
        return MMpush ( m , NIL ) ;
    }
    O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
    B = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1)) ;

    res = SendMessage ( B->WHandler , LB_GETCOUNT , 0 , 0 ) ;

    if ( res == LB_ERR ) res = MMpush ( m ,NIL ) ;
    else res = MMpush(m,res<<1) ;

    /*********************************** DEBUG 2D ***********************************************/
    #ifdef TRACED2D
        MMechostr ( 1 , "DBG _get_list_count done\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /*********************************************************************************************/

    return res ;
}

/*********************************************************************/
/*                                                                   */
/* int GRPaintObjList ( mmachine m ) ;                               */
/*                                                                   */
/* correspond a la fonction magma ObjText _paint_obj_list (ObjList)  */
/* laquelle repaint un objet texte                                   */
/*                                                                   */
/*********************************************************************/

int GRPaintObjList ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    PtrObjCombo C ;
    RECT Rr ;

    /******************************* DEBUG 2D ************************/
    #ifdef TRACE2D
        MMechostr( 1 , "DBG _paint_obj_list\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /******************************************************************/

    s = MMpull(m) ;
    if ( s == NIL ) return MMpush(m,NIL ) ;

    O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
    C = ( PtrObjCombo ) MMstart(m, (O->Buffer>>1)) ;
    if ( GetUpdateRect ( C->WHandler , & Rr , TRUE ))
    {
          InvalidateRect ( C->WHandler , & Rr , TRUE ) ;
          SendMessage ( C->WHandler , WM_PAINT , 0 , 0 ) ;
    }

    s = MMpush(m,s) ;

    /************************ DEBUG 2D ***********************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _paint_obj_list done\n" ) ;
    #endif
    /*********************************************************************/

    return s ;
}



/****************************************************************************************/
/*                                                                                      */
/*  int GRSetListColumn ( mmachine m ) ;                                                */
/*                                                                                      */
/*  correspond a la fonction magma ObjList _set_list_column ObjList I                   */
/* laquelle definit la largeur d'une colonne de la list box                             */
/*                                                                                      */
/****************************************************************************************/

int GRSetListColumn ( mmachine m )
{
    int s , w ;
    PtrObjVoid O ;
    PtrObjCombo L ;


    /********************************* DEBUG 2D ******************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _set_list_column\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /***************************************************************************************/

    w = MMpull(m) >> 1 ;
    s = MMpull(m) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid) MMstart(m,(s>>1) ) ;
        L = ( PtrObjCombo)MMstart(m,(O->Buffer>>1) ) ;
        SendMessage ( L->WHandler , LB_SETCOLUMNWIDTH, ( WPARAM ) w , ( LPARAM ) 0 ) ;
    }

    s= MMpush(m,s) ;

    /********************************** DEBUG 2D ***********************************************/
    #ifdef TRACE2D
        FDebug2D ( m );
        MMechostr ( 1 , "DBG _set_list_column done\n" ) ;
    #endif
    /*********************************************************************************************/

    return s ;
}

/**************************************************************************************************/
/*                                                                                                */
/*  int GRGetListSelection ( mmachine m ) ;                                                       */
/*                                                                                                */
/* Correspond a la fonction magma _get_list_selection qui retourne la selection [I S] d'une list  */
/*                                                                                                */
/**************************************************************************************************/

int GRGetListSelection ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    PtrObjCombo L ;

    /*********************** DEBUG 2D ********************************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _get_list_selection\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /********************************************************************************************/

    s = MMpull(m);
    if ( s == NIL ) return MMpush(m,NIL);
    O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
    L = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1) ) ;
    s = SendMessage ( L->WHandler , LB_GETCURSEL , 0 , 0 ) ;
    if ( s == LB_ERR ) return MMpush(m,NIL);
    MMpush(m,s<<1);
	GRpushListElement(m,L->WHandler,s);

    MMpush(m,4);
    s = MBdeftab ( m ) ;


    /********************* DEBUG 2D ************************************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _get_list_selection done\n" );
    #endif
    /***********************************************************************************************/

    return s ;
}

/***************************************************************************************************/
/*                                                                                                 */
/*  int GRResetList ( mmachine m ) ;                                                               */
/*                                                                                                 */
/*  Cette fonction permet de vider une list box                                                    */
/*                                                                                                 */
/***************************************************************************************************/

int GRResetList ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    PtrObjCombo L ;

    /********************************* DEBUG 2D ****************************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG reset_list\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /***********************************************************************************************/

    s= MMpull(m) ;
    if ( s == NIL ) return MMpush(m,NIL) ;
    O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
    L = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1)) ;
    SendMessage ( L->WHandler , LB_RESETCONTENT , 0 , 0 );
    s = MMpush(m,s) ;

    /*********************************** DEBUG 2D ***************************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG reset_list done\n" ) ;
    #endif
    /**************************************************************************************************/

        return s ;
}

/******************************************************************************************************/ 
/*                                                                                                    */ 
/*      int GRGetListMultipleSelection ( mmachine m ) ;                                               */ 
/*      correspond a la fonction [[I S] r1] _GETlistMSel [ ObjList ]                                  */ 
/*      qui retourne la selection d'une listbox en mode multi selection                               */ 
/*                                                                                                    */ 
/******************************************************************************************************/ 

int GRGetListMultipleSelection ( mmachine m )
{
    PtrObjCombo L ;
    PtrObjVoid O ;
    HWND H ;
    int s , res , hmuch ;
    int items [ 32767 ] ;   /* ouch, j'espere que ca passera ... */ 

    /**************************** DEBUG 2D ************************************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _GETlistMSel\n");
        FDebug2D(m);
    #endif
    /**************************************************************************************************/
    
    s = MMpull(m);
    if ( s == NIL ) res = MMpush(m,NIL ) ;
    else
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1));
        L = ( PtrObjCombo ) MMstart(m,(O->Buffer>>1));
        H = L->WHandler ; 
        hmuch = SendMessage ( H , LB_GETSELCOUNT , 0 , 0 ) ;
        if ( hmuch == LB_ERR ) res = MMpush(m,NIL ) ;
        else
        {
            SendMessage (H,LB_GETSELITEMS,hmuch,( LPARAM ) items);
            res=MMpush(m,NIL) ; /* empile la fin de liste */ 

            while (hmuch)
            {
                hmuch --;               
                /* cree le doublet [ I S ] */ 
                if (MMpush(m,(items[hmuch])<<1)) return MERRMEM ;

				if (GRpushListElement(m,L->WHandler,items[hmuch])) return MERRMEM;
                if (MMpush(m,4)) return MERRMEM ;
                MBdeftab(m);

                /* inverse pour bien avoir la queue en dernier */ 
                res = MMget(m,1);
                MMset(m,1,MMget(m,0));
                MMset(m,0,res);

                /* cree le doublet [ [ I S ] r1 ] */ 
                if (MMpush(m,4)) return MERRMEM ;
                res = MBdeftab(m);


            }
        }

    }

    /************************* DEBUG 2D ***************************************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _GETlistMSel\n");
    #endif
    /**************************************************************************************************/

    return res ;
}
