/********************************************************************************************************/ 
/*                                                                                                      */ 
/*          Fichier winpkg11.c                                                                          */ 
/*                                                                                                      */ 
/*          Ce fichier comprend le code pour les objet arbre et lest liste de bitmaps                   */ 
/*                                                                                                      */ 
/********************************************************************************************************/ 

#include "x/Version.h"
#include "x/scolplugin.h"

#include <stdio.h>
#include <string.h>

#include "objstr.h"
#include "tests.h"
#include "objects/listbox.h"


WNDPROC TreeProc = NULL ;




void CheckDragAndDrop ( mmachine m , HWND hwnd , int x , int y ) 
{
    int p ,k ;
    PtrObjVoid O ;
    PtrObjTree Tree ;
    TV_HITTESTINFO tvh ;

    //MMechostr (1,"CheckDragAndDrop\r\n");
    p = OBJfindTH(m,OBJTYPTREE,(int)hwnd);   
    p = MMfetch(m,p,OFFOBJMAG);
    O=(PtrObjVoid) MMstart(m,(p>>1));
    Tree=(PtrObjTree) MMstart(m,(O->Buffer>>1));
    if ( Tree->Dragged )
    {
        //MMechostr (1,"CheckDragAndDrop step 1\r\n");
        ImageList_EndDrag () ;
        UpdateWindow ( hwnd ) ;
        k=OBJbeginreflex(m,OBJTYPTREE,(int)hwnd,RFLTREE_DRAG);
        if(k==0)
        {
           
            tvh.pt.x = x ;
            tvh.pt.y = y ;
            TreeView_HitTest ( hwnd , &tvh) ;
            MMpush(m,(( int ) Tree->Dragged)<<1);
            MMpush(m,((int) tvh.hItem)<<1);
            OBJcallreflex(m,2);
        }
        InvalidateRect(hwnd,NULL,FALSE);
        UpdateWindow ( hwnd ) ;
       
    }    
    Tree->Dragged = NULL ;
}


void CheckDragAndDropMove ( HWND hwnd , int Bstat )
{
    int p  ;
    PtrObjVoid O ;
    PtrObjTree Tree ;
    POINT P ;
    RECT R ;
    
    p = OBJfindTH(mm,OBJTYPTREE,(int)hwnd);   
    p = MMfetch(mm,p,OFFOBJMAG);
    O=(PtrObjVoid) MMstart(mm,(p>>1));
    Tree=(PtrObjTree) MMstart(mm,(O->Buffer>>1));  
    if ( Tree->Dragged != NULL )
    { 
           
        if ( (Bstat & MK_LBUTTON) == 0 )
        {
            //MMechostr ( 1 , "Passage tree move drag fix" ) ;
            ImageList_DragLeave ( Tree->WHandler ) ;
            ImageList_EndDrag () ;
            //TreeView_Select(hwnd , Tree->Dragged , 0 ) ;
            Tree->Dragged = NULL ;
        }
        else
        {
            
            GetCursorPos ( &P ) ;
            GetWindowRect ( hwnd , &R ) ;
            P.x -= R.left ;
            P.y -= R.top ;
            

            TreeView_Select(hwnd , Tree->Dragged , TVGN_CARET ) ; 
            UpdateWindow ( hwnd ) ;
            ImageList_DragLeave ( Tree->WHandler);  
            if (!ImageList_DragMove ( P.x,P.y )) MMechostr (1,"(DBG) CheckDragAndDropMove failed\n");
            ImageList_DragEnter ( Tree->WHandler,P.x,P.y ) ;
            
        }      
        TreeView_Select(hwnd , Tree->Dragged , TVGN_CARET ) ; 
        UpdateWindow ( hwnd ) ;
    }

}



/****************************************************************************/ 
/*                                                                          */ 
/*  void SCStreeMenu(mmachine m,HWND Parent,int Code,int Control,HWND Child)*/ 
/*                                                                          */ 
/*  gestion des menu ( menu contextuels ) dans les arbres                   */ 
/*                                                                          */ 
/****************************************************************************/ 

int SCStreeMenu (mmachine m,HWND Parent, int Code, int Control, HWND Child)
{
    int k ;
  /***********************************************************************************/ 
  /*          Reflex selection dans un menu                                          */ 
  /***********************************************************************************/ 
  if (Child == 0 ) k=OBJbeginreflex(m,OBJTYPMENUITEM,Control,RFLMENUITEM_SELECT) ; else k = 1 ;
  if ( k == 0 )
    {
    #ifdef TRACE_EVENT
          MMechostr( 1 , "execute reflex event menu item\n" ) ;
    #endif
      return OBJcallreflex(m,0) ;
    }
  if ( k < 0 ) return -1 ;
  return 0 ;
}


/****************************************************************************/ 
/*                                                                          */ 
/*  void SCStreeClick ( mmachine m , HWND tree, int X , int Y )             */ 
/*                                                                          */ 
/*      Gestion du click dans un arbre                                      */ 
/*                                                                          */ 
/****************************************************************************/ 

void SCStreeClick(mmachine m, HWND tree, int x , int y , int bt )
{
    int p ,k ;
    PtrObjVoid O ;
    PtrObjTree Tree ;
    TV_HITTESTINFO tvh ;

    p = OBJfindTH(m,OBJTYPTREE,(int)tree);   
    p = MMfetch(m,p,OFFOBJMAG);
    O=(PtrObjVoid) MMstart(m,(p>>1));
    Tree=(PtrObjTree) MMstart(m,(O->Buffer>>1));
    k=OBJbeginreflex(m,OBJTYPTREE,(int)tree,RFLTREE_CLICK);
    if(k==0)
    {
           
            tvh.pt.x = x ;
            tvh.pt.y = y ;
            TreeView_HitTest ( tree , &tvh) ;  
            if (tvh.hItem == NULL) MMpush(m,NIL) ; else MMpush(m,((int) tvh.hItem)<<1);
            MMpush(m,x<<1);
            MMpush(m,y<<1);
            MMpush(m,bt<<1);
 
            OBJcallreflex(m,4);
    }   
}


/****************************************************************************/ 
/*                                                                          */ 
/*  void SCStreeKeyup ( mmachine m , HWND tree, int key )                   */ 
/*                                                                          */ 
/*      Gestion du click dans un arbre                                      */ 
/*                                                                          */ 
/****************************************************************************/ 

int SCStreeKeyup(mmachine m, HWND tree, int Key) 
{
  int k;

//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nSCStreeKeyup");
#endif
//***********************************

  /* reflex pour les fenetres windows */
  k = OBJbeginreflex(m,OBJTYPTREE,(int)tree,RFLTREE_KEYUP) ;
  if(k==0)
    {
      if (MMpush(m,Key<<1)) return MERRMEM ;
      return OBJcallreflex(m,1) ;
    }
  if (k<0) return 0 ;
  return 1;

}

int SCStreeKeydown(mmachine m,HWND tree, int scancode, int KeyData)
{
  int k ;

//***********************************
#if DEBUG_LIB2DOS
MMechostr (0, "\nSCStreeKeydown");
#endif
//***********************************

  /***************** reflex pour les fenetres windows *******************/
  k = OBJbeginreflex(m,OBJTYPTREE,(int)tree,RFLTREE_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;
}

void SCStreeDoubleClick ( mmachine m , HWND tree, int x , int y )
{
    int p ,k ;
    PtrObjVoid O ;
    PtrObjTree Tree ;
    TV_HITTESTINFO tvh ;

    p = OBJfindTH(m,OBJTYPTREE,(int)tree);   
    p = MMfetch(m,p,OFFOBJMAG);
    O=(PtrObjVoid) MMstart(m,(p>>1));
    Tree=(PtrObjTree) MMstart(m,(O->Buffer>>1));
    k=OBJbeginreflex(m,OBJTYPTREE,(int)tree,RFLTREE_DCLICK);
    if(k==0)
    {
           
            tvh.pt.x = x ;
            tvh.pt.y = y ;
            TreeView_HitTest ( tree , &tvh) ;  
            if (tvh.hItem == NULL) MMpush(m,NIL) ; else MMpush(m,((int) tvh.hItem)<<1);
            MMpush(m,x<<1);
            MMpush(m,y<<1);
            OBJcallreflex(m,3);
    }
    
   
}



/**********************************************************************************************/
/*                                                                                            */
/*  LRESULT CALLBACK TreeProcBis ( HWND hwnd , unsigned msg , UINT wParam , LONG lParam )     */
/*                                                                                            */
/*      WinProc pour les arbres                                                               */
/*                                                                                            */
/**********************************************************************************************/

LRESULT CALLBACK TreeProcBis ( HWND hwnd , unsigned msg , UINT wParam , LONG lParam )
{
    int c , k ;

    switch (msg)
    {

    case WM_COMMAND :
        
        SCStreeMenu (mm,hwnd,HIWORD(wParam),LOWORD(wParam),(HWND)lParam);                     
        tstscoldead(208);
        break ;

    case WM_LBUTTONUP :        

        k=1;
        
        CheckDragAndDrop ( mm, hwnd , LOWORD(lParam) , HIWORD (lParam ) ) ;       
        tstscoldead(209);
 
        break ;
  
    case WM_LBUTTONDBLCLK : SCStreeDoubleClick (mm,hwnd,LOWORD(lParam),HIWORD(lParam));
        break ;


    case WM_RBUTTONDOWN :  
     
		//SetCapture(hwnd);
        k=2;
        SCStreeClick(mm,hwnd,LOWORD(lParam),HIWORD(lParam),k);
        tstscoldead(210);
        break ;

    case WM_MOUSEMOVE :
        //MMechostr ( 1 ,"Deplace souris tree wparam = %d\r\n",wParam);
        CheckDragAndDropMove ( hwnd , wParam ) ;
        tstscoldead(211) ;

       break ;

	case WM_KEYUP :
        //MMechostr ( 1 ,"keyup tree wparam = %d\r\n",wParam);
        SCStreeKeyup(mm,hwnd,(lParam>>16)&0x1ff);
        tstscoldead(213) ;

       break ;

	case WM_KEYDOWN :
        c=convertvirtcode((int)wParam);
        if (c==0) break;
        SCStreeKeydown (mm,hwnd,(lParam>>16)&0x1ff,c);
        tstscoldead(214);

       break ;
   
    }   
    return CallWindowProc ( TreeProc , hwnd , msg , wParam , lParam );
}

/**********************************************************************************/
/*                                                                                */
/*      HWND NewObjTree  ( PtrObjTree * T , HWND Parent ) ;                       */
/*      Cree un nouvel arbre window                                               */
/*                                                                                */
/**********************************************************************************/

HWND NewObjTree ( PtrObjTree T , HWND Parent )
{
    int FlagEx , Flag ;

	INITCOMMONCONTROLSEX x;

	x.dwSize=sizeof(INITCOMMONCONTROLSEX);
	x.dwICC=ICC_TREEVIEW_CLASSES;

    InitCommonControlsEx (&x) ;
//    InitCommonControls () ;

   Flag = WS_VISIBLE | WS_CHILD | TVS_HASLINES   ;
   FlagEx = 0 ;

   if (T->Flags & TV_DOWN ) FlagEx |= WS_EX_CLIENTEDGE ;
   if (T->Flags & TV_BORDER ) Flag |= WS_BORDER ;
   if (T->Flags & TV_HSCROLL ) Flag |= WS_HSCROLL ;
   if (T->Flags & TV_VSCROLL ) Flag |= WS_VSCROLL ;
   if (T->Flags & TV_BUTTON ) Flag |= TVS_LINESATROOT | TVS_HASBUTTONS ;
   
   return CreateWindowEx ( FlagEx , WC_TREEVIEW , "" ,
        Flag ,
        T->PosX , T->PosY , T->TailleW , T->TailleH ,
        Parent , (HMENU) 0 , (HINSTANCE)SCgetExtra("this_inst") , NULL ) ;
}





/********************************************************************************************************/
/*                                                                                                      */
/*      int GRCreateTree ( mmachine m )                                                                 */
/*      correspond a la fonction scol ObjTree _CRtree ( Chn ObjWin I I I I I ) ;                        */
/*                                                                                                      */
/********************************************************************************************************/

int GRCreateTree ( mmachine m ) 
{
    int f , x , y , w , h , s , s2 , l , res ;
    PtrObjVoid O ; 
    PtrObjWindow W ;
    PtrObjTree T ;
    HWND Parent ;

    /************************ DEBUG 2D *******************************/
    #ifdef TRACE2D
            MMechostr ( 1 , "DBG _CRtree\n" ) ;
            FDebug2D ( m )  ;
    #endif
    /*****************************************************************/
    f = MMpull(m)>> 1 ;
    h = MMpull(m)>> 1 ;
    w = MMpull(m)>> 1 ;
    y = MMpull(m)>> 1 ;
    x = MMpull(m)>> 1 ;
    s = MMpull(m) ;
    if ( s == NIL )
    {
        MMechostr (1,"_CRtree : Parent is NIL\n" );
        MMpull(m); /* depile channel */ 
        return MMpush(m,NIL);
    }
    O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
    W = ( PtrObjWindow ) MMstart(m,(O->Buffer>>1)) ;
    Parent = W->WHandler ;

    /* creation de la zone memoire de l'objet general */
    l = ( sizeof ( struct ObjVoid ) + 3 ) >> 2 ;
    s = MMmallocCLR (m,l,TYPETAB) ;
    if ( s == NIL )
    {
        MMechostr(MSKDEBUG,"_create_edit_text : Error in alloc MAGMA Memory\n" ) ;         
        return MERRMEM ;
    }    
    if ( MMpush(m,(s<<1)+1)) return MERRMEM ;
    /* on rempile l'addresse au cas ou il y aurait un GC par la suite */

    /* creation de la zone memoire pour les donnees relatives aux objets textes */
    l = ( sizeof ( struct ObjTree ) + 3 ) >> 2 ;
    s2 = MMmalloc ( m,l,TYPEBUF ) ;
    if ( s2 == NIL )
    {
        MMechostr(MSKDEBUG,"_create_edit_text : Error in alloc MAGMA Memory\n" ) ;
        return MERRMEM ;
    }


    T = ( PtrObjTree ) MMstart(m, s2 ) ;
    s = MMpull (m ) ; /* recupere l'addresse de l'objet de base */
    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;

    O -> Type             = OBJ_TYPE_TREE << 1  ;        
    O->Buffer = (s2<<1)+1 ;
    O->Tab = NIL ;
    T -> Flags          = f ;
    T -> TailleH        = h ;
    T -> TailleW        = w ;
    T -> PosY           = y ;
    T -> PosX           = x ;
    T -> Dragged        = NULL ;

    T->WHandler = NewObjTree ( T ,  Parent ) ;
    if ( !T->WHandler )
    {

        MMechostr (1,"_CRtree : Error in creating the WIN95 Object - Check the values\n" ) ;
        MMset(m,0,NIL) ;
        return 0 ;
    }
    if ( TreeProc == NULL ) TreeProc = ( WNDPROC ) GetWindowLong ( T->WHandler , GWL_WNDPROC ) ;
    SetWindowLong ( T->WHandler , GWL_WNDPROC , ( long ) TreeProcBis ) ;
  

    ShowWindow( T->WHandler, SW_SHOW) ;
    UpdateWindow(T->WHandler );

    MMpush(m,s) ;
    res = OBJcreate(m,OBJTYPTREE,(int)T->WHandler,OBJTYPWINDOW,(int)Parent) ;
       

    /********************** DEBUG 2D *********************************/
    #ifdef TRACE2D
            FDebug2D ( m );
            MMechostr (1,"DBG _CRtree done\n" );
    #endif
    /*****************************************************************/

    return res ;
}

/****************************************************************************************/
/*                                                                                      */
/*      int GRAddTreeChild ( mmachine m )                                                    */
/*      correspond a la fonction scol :                                                 */
/*      ObjTreeItem _ADDtree (ObjTree arbre,ObjTreeItem parent,I flag, S label  )       */
/*                                                                                      */
/****************************************************************************************/

int GRAddTreeChild ( mmachine m )
{
    int s,flag,hp,so,ns ;
    char * Ts ;
    PtrObjVoid O  ;
    PtrObjTree T ;
    TV_INSERTSTRUCT tvi ;

    /******************* DEBUG 2D **************************************/
    #ifdef TRACE2D
        MMechostr (1,"DBG _ADDtree\n");
        FDebug2D(m);
    #endif
    /********************************************************************/

    s = MMpull(m);
    if ( s==NIL ) Ts=NULL ;
    else Ts = ( char * ) MMstart(m,(s>>1)+1);
    flag = MMpull(m) >> 1 ;
    hp = MMpull(m);
    so = MMpull(m);

    if (so==NIL) ns = NIL ;
    else 
    {
        O = ( PtrObjVoid ) MMstart(m,(so>>1));
        T = ( PtrObjTree )MMstart(m,(O->Buffer>>1)) ;       
        tvi.item.mask = TVIF_TEXT   ;
        tvi.item.pszText = Ts ;
        if ( Ts == NULL ) tvi.item.cchTextMax = 0 ;
        else tvi.item.cchTextMax = strlen ( Ts ) ;
        if (hp==NIL ) tvi.hParent = TVI_ROOT ; 
        else tvi.hParent = ( HTREEITEM ) (hp >>1);
        
        if ( flag & TREE_INSERT_FIRST ) tvi.hInsertAfter = TVI_FIRST ;
        else if ( flag & TREE_INSERT_SORT ) tvi.hInsertAfter = TVI_SORT ;
        else tvi.hInsertAfter = TVI_LAST ;

        ns = ( int ) TreeView_InsertItem ( T->WHandler,&tvi);
        UpdateWindow ( T->WHandler ) ;
    }

    s = MMpush(m,ns<<1);


    /*************** DEBUG 2D ****************************************/
    #ifdef TRACE2D
        FDebug2D (m);
        MMechostr (1,"DBG _ADDtree Done\n");
    #endif
    /*****************************************************************/

    return s;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRSetTreeBitmap ( mmachine m );                                                     */
/*      correspond a la fonction ObjTree _SETtreeBitmaps ( ObjTree , ObjBitmapList ) ;          */
/*                                                                                              */
/************************************************************************************************/

int GRSetTreeBitmap ( mmachine m )
{
    int st , sl ;
    PtrObjVoid OT , OL ;
    PtrObjTree T ;
    PtrObjListBitmap L ;


    /******************************* DEBUG 2D *********************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _SETtreeBitmaps\n" );
        FDebug2D(m);
    #endif
    /***************************************************************************************/

    sl = MMpull(m) ;
    st = MMpull(m) ; 

    if (sl != NIL && st != NIL )
    {
        OL = ( PtrObjVoid ) MMstart(m,(sl>>1)) ;
        OT = ( PtrObjVoid ) MMstart(m,(st>>1)) ;
        L = ( PtrObjListBitmap ) MMstart(m,(OL->Buffer>>1)) ;
        T = ( PtrObjTree ) MMstart(m,(OT->Buffer>>1));
        TreeView_SetImageList(T->WHandler, L->WHandler, TVSIL_NORMAL); 
        OT->Tab= sl ;
    }

    st = MMpush(m,st);


    
    /*************************** DEBUG 2D ***************************************************/
    #ifdef TRACE2D
            FDebug2D(m);
            MMechostr(MSKDEBUG,"(DBG) _SETtreeBitmaps done\n");
    #endif
    /**************************************************************************************/

    return st ;
}

/************************************************************************************************/
/*                                                                                              */
/*  int GRSetTreeItemBitmap ( mmachine m ) ;                                                    */
/*  correspond a la fonction ObjTree _SETtreeItemBitmap(ObjTree,ObjTreeItem,I idx)              */
/*  laquelle selectionne les 2 bitmaps pour une selection de l'arbre                            */
/*                                                                                              */
/************************************************************************************************/

int GRSetTreeItemBitmap ( mmachine m )
{
    int idx1,idx2 , hit , s ;
    TV_ITEM tvi ;
    PtrObjVoid O ;
    PtrObjTree T ;

    /******************** DEBUG 2D ************************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "(DBG) _SETtreeItemBitmap\n");
        FDebug2D(m);
    #endif
    /*****************************************************************************/

        idx2=MMpull(m)>>1;
        idx1=MMpull(m)>>1;
        hit=MMpull(m)>>1 ;
        s=MMpull(m);

        if(idx1 < 0 || idx2 < 0 )
            MMechostr(MSKDEBUG,"(ERROR) _SETtreeItemBitmap : Index is outside the list.\n");
        else if ( s == NIL )
            MMechostr(MSKDEBUG,"(ERROR) _SETtreeItemBitmap : ObjTree is NIL.\n");
        else if ( hit == NIL )
            MMechostr(MSKDEBUG,"(ERROR) _SETtreeItemBitmap : ObjTreeItem is NIL\n");
        else 
        {
            tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE ;
            tvi.hItem = ( HTREEITEM ) hit ;
            tvi.iImage = idx1 ;
            tvi.iSelectedImage = idx2 ;
            O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
            T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1)) ;

            TreeView_SetItem ( T->WHandler, &tvi ) ;
            UpdateWindow ( T->WHandler );
        }

        s = MMpush(m,s);
    /************************ DEBUG 2D ********************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _SETtreeItemBitmap done\n");
    #endif
    /******************************************************************************/

    return s;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRGetTreeChild ( mmachine m ) ;                                                     */
/*      correspond ala fonction ObjTreeItem _GETtreeChild ( ObjTree , ObjTreeItem )             */
/*                                                                                              */
/************************************************************************************************/

int GRGetTreeChild ( mmachine m )
{
    int hp , s , res ;
    PtrObjVoid O ;
    PtrObjTree T ;

    /*************************************** DEBUG 2D *******************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _GETtreeChild\n");
        FDebug2D(m);
    #endif
    /********************************************************************************************/

    hp = MMpull(m) ;
    s = MMpull(m) ;

    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1)) ;
        if (hp==NIL) res = ( int ) TreeView_GetChild ( T->WHandler, NULL ) ;
        else res = ( int ) TreeView_GetChild ( T->WHandler , ( HTREEITEM ) (hp>>1));
        if (res == ( int ) NULL) res = NIL ; else res = res << 1  ;

    } else res = NIL ;

    res = MMpush(m,res) ;

    /******************************** DEBUG 2D ***************************************************/
    #ifdef TRACE2D
        FDebug2D( m ) ;
        MMechostr(MSKDEBUG,"(DBG) _GETtreeChild done\n" );
    #endif
    /********************************************************************************************/

    return res ;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRGetTreeBrother ( mmachine m ) ;                                                   */
/*      correspond a la fonction ObjTreeItem ( ObjTree , ObjTreeItem ) ;                        */
/*                                                                                              */
/************************************************************************************************/

int GRGetTreeBrother ( mmachine m )
{
    int s , hp , res ;
    PtrObjVoid O ;
    PtrObjTree T ;
    /*********************************** DEBUG 2D ***********************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _GETtreeBrother\n");
        FDebug2D(m);
    #endif
    /********************************************************************************************/

    hp = MMpull(m) ;
    s = MMpull(m) ;

    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1)) ;
        if ( hp == NIL ) res = ( int ) TreeView_GetChild ( T->WHandler, NULL ) ;
        else res = ( int ) TreeView_GetNextItem ( T->WHandler , ( HTREEITEM ) (hp>>1) , TVGN_NEXT ) ;
        if ( res == ( int ) NULL ) res = NIL ; else res = res << 1 ;
    } else res = NIL ;

    res = MMpush(m,res) ;

    /****************************** DEBUG 2D ***************************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _GETtreeBrother done\n");
        FDebug2D(m);
    #endif
    /*******************************************************************************************/

    return res ;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRSetTreeItemLabel ( mmachine m ) ;                                                 */
/*  correspond ala fonction ObjTree _SETtreeItemLabel ( ObjTree,ObjTreeItem,S);                 */
/*                                                                                              */
/************************************************************************************************/

int GRSetTreeItemLabel ( mmachine m )
{
    int hp , s ;
    char * name ; 
    TV_ITEM tvi ;
    PtrObjVoid O ;
    PtrObjTree T ;

    /******************************** DEBUG 2D **************************************************/
    #ifdef TRACE2D  
        MMechostr(MSKDEBUG,"(DBG) _SETtreeItemLabel\n");
        FDebug2D(m);
    #endif
    /********************************************************************************************/

    s = MMpull(m) ;
    if ( s == NIL ) name = NULL ;
    else name = ( char * ) MMstart(m,(s>>1)+1);

    hp = MMpull(m) ;
    s = MMpull(m) ;
    if ( hp != NIL && s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1));
        T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1));
        tvi.mask = TVIF_TEXT ;
        if ( name == NULL ) tvi.cchTextMax = 0 ;
        else tvi.cchTextMax = strlen ( name ) ;
        tvi.pszText = name ;
        tvi.hItem = ( HTREEITEM ) ( hp>>1) ;
        TreeView_SetItem ( T->WHandler, &tvi ) ;
        UpdateWindow ( T->WHandler );

    } else MMechostr ( 1, "(ERROR) _SETtreeItemLabel : tree or treeItem is NIL\n");

    s = MMpush(m,s) ;

    /********************************* DEBUG 2D *************************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _SETtreeItemLabel done\n");
    #endif
    /********************************************************************************************/

    return s ;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRSetTreeItemState  ( mmachine m ) ;                                                */
/*      correspond a la fonction ObjTree _SETtreeItemState ( ObjTree, ObjTreeItem , I ) ;       */
/*                                                                                              */
/************************************************************************************************/

int GRSetTreeItemState ( mmachine m ) 
{
    int state , s , hp ;
    PtrObjVoid O ;
    PtrObjTree T ;

    /******************************** DEBUG 2D ********************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _SETtreeItemState\n");
        FDebug2D(m);
    #endif
    /**************************************************************************************/

        state = MMpull(m)>>1 ;
        hp = MMpull(m);
        s = MMpull(m) ;

        if (hp!= NIL && s != NIL )
        {
            O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
            T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1)) ;
            if ( state ) TreeView_Expand ( T->WHandler , (HTREEITEM )(hp>>1),TVE_EXPAND);
            else TreeView_Expand (T->WHandler,(HTREEITEM)(hp>>1),TVE_COLLAPSE);
            UpdateWindow ( T->WHandler) ; 

        }

        s = MMpush(m,s ) ;

    /***************************** DEBUG 2D ***********************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _SETtreeItemState done\n") ;
    #endif
    /**************************************************************************************/

    return s ;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRGetTreeItemState ( mmachine m ) ;                                                 */
/*      correspond a la fonction I _GETtreeItemState ( ObjTree, ObjTreeItem ) ;                 */
/*                                                                                              */
/************************************************************************************************/

int GRGetTreeItemState ( mmachine m )
{
    int s , hp , res ;
    PtrObjVoid O ;
    PtrObjTree T ;
    TV_ITEM tvi ;

    /************************ DEBUG 2D ***************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _GETtreeItemState\n");
        FDebug2D(m);
    #endif
    /************************************************************************/

    hp = MMpull(m);
    s=MMpull(m);

    if (hp !=NIL && s != NIL )
    {
        O=(PtrObjVoid ) MMstart(m,(s>>1));
        T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1)) ;
        tvi.mask = TVIF_STATE ;
        tvi.hItem = ( HTREEITEM )(hp>>1);
        TreeView_GetItem (T->WHandler, &tvi ) ;

        if ( tvi.state & TVIS_EXPANDED ) res = 2 ; 
        else res = 0 ;
    } else res = NIL ;

    res = MMpush(m,res );

    /********************** DEBUG 2D ***************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _GETtreeitemState done\n");
    #endif
    /***********************************************************************/

    return res ;
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRReflexTreeExpand ( mmachine m ) ;                                                 */
/*      correspond a la fonction ObjTree _CBtreeExpand(ObjTree,fun[ObjTree u0 ObjTreeItem I]u0])*/
/*                                                                                              */
/************************************************************************************************/

int GRReflexTreeExpand ( mmachine m )
{
        return OBJaddreflex (m,OBJTYPTREE,RFLTREE_EXPAND ) ;
}

int GRReflexTreeSelect ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_SELECT);
}

int GRReflexTreeDrag ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_DRAG);
}

int GRReflexTreeClick ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_CLICK);
}

int GRReflexTreeUnclick ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_UNCLICK);
}

int GRReflexTreeDClick ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_DCLICK);
}

int GRReflexTreeKeyDown ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_KEYDOWN);
}

int GRReflexTreeKeyUp ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPTREE,RFLTREE_KEYUP);
}

/************************************************************************************************/
/*                                                                                              */
/*      int GRDestroyTree ( mmachine m ) ;                                                      */
/*      correspond a la fonction I _DStree ( ObjTree ) ;                                        */
/*                                                                                              */
/************************************************************************************************/

int GRDestroyTree ( mmachine m )
{
    int s ;
    PtrObjVoid O ;
    PtrObjTree T ;


    /************************** DEBUG 2D **********************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _DStree\n");
        FDebug2D(m);
    #endif
    /**********************************************************************************/

    s = MMget(m,0);
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1));
        OBJdelTH(m,OBJTYPTREE,(int)T->WHandler) ;
    }


   
    /*********************** DEBUG 2D **************************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _DStreeItem Done\n");
    #endif
    /************************************************************************************/

    MMset(m,0,0);
    return 0 ;
}


/************************************************************************************************/
/*                                                                                              */
/*  int GRDestroyTreeItem ( mmachine m ) ;                                                      */
/*  correspond a la fonction ObjTree _DStreeItem ( ObjTree , ObjTreeItem )                      */
/*                                                                                              */
/************************************************************************************************/

int GRDestroyTreeItem ( mmachine m )
{
    int s , hp ;
    PtrObjVoid O ;
    PtrObjTree T ;

    /*************************************** DEBUG 2D *******************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _DStreeItem\n");
        FDebug2D(m);
    #endif
    /********************************************************************************************/

    hp = MMpull(m) ;
    s = MMpull(m) ;

    if ( hp != NIL && s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjTree ) MMstart(m,(O->Buffer>>1) );
        TreeView_DeleteItem ( T->WHandler , ( HTREEITEM ) ( hp >> 1 )) ;
    }

    s = MMpush(m,s) ;

    /************************************ DEBUG 2D **********************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _DStreeItem done\n");
    #endif
    /********************************************************************************************/

    return s ;
}



#define CHECK(m)			if ((tmp_res=m)) return tmp_res
#define MTOI(mot)			((mot)>>1)
#define MTOP(mot)			((mot)>>1)
#define ITOM(mot)			((mot)<<1)
#define PTOM(mot)			(((mot)<<1)+1)
#define STR_SIZE(size)		(2+((size)>>2))
#define SIZE(t)				((sizeof(t)+3)>>2)
#define INVERT(m, a, b)			tmp_res=MMget(m,a);MMset(m,a,MMget(m,b));MMset(m,b,tmp_res);


int _SELtreeItem(mmachine m)
{
	int s , hp;
    PtrObjVoid O ;
    PtrObjTree T ;
	HANDLE w;

    hp	= MTOP(MMpull(m));
    s	=MTOP(MMget(m,0));
	
    if (hp !=NIL && s != NIL )
    {
        O=(PtrObjVoid ) MMstart(m,s);
        T = ( PtrObjTree ) MMstart(m,MTOP(O->Buffer)) ;
		w=T->WHandler;
		SendMessage(w,TVM_SELECTITEM,(WPARAM)TVGN_CARET,(LPARAM)( HTREEITEM )hp);
		SendMessage(w,TVM_SELECTITEM,(WPARAM)TVGN_DROPHILITE ,(LPARAM)( HTREEITEM )hp); // SH000823 - big hack
    }
	else
		MMset(m,0,NIL);
	return 0;
}

int _SELlistTabItem(mmachine m)
{
	int s , i ;
    PtrObjVoid O ;
    PtrObjListTab L ;

    i = MTOI(MMpull(m));
    s = MTOP(MMget(m,0));

    if ( s!= NIL && i!= NIL)
    {
        O = ( PtrObjVoid ) MMstart(m,(s));
        L = ( PtrObjListTab ) MMstart(m,MTOP(O->Buffer));
        SetFocus(L->WHandler);
		ListView_SetItemState ( L->WHandler ,i,LVIS_FOCUSED | LVIS_SELECTED,0x000F) ;
    }
	else 
		MMset(m,0,NIL);
    return 0;
}


