/********************************************************************************************************/
/*                                                                                                      */
/*          Fichier richtext.c                                                                          */
/*                                                                                                      */
/*          Ce fichier comprend le code pour les objet rich edit text                                   */
/*                                                                                                      */
/********************************************************************************************************/

#include "x/Version.h"
#include "x/scolplugin.h"


#include <stdio.h>
#include <string.h>
#include <richedit.h>

#include "objstr.h"
#include "utils.h"
#include "events.h"
#include "objects/text.h"



WNDPROC RichTextProc ;

char InitRichText = 0 ;

LRESULT CALLBACK RichProc2( HWND hwnd, unsigned msg,
                                     UINT wParam, LONG lParam )
{
   
    int x , y , k ;
//    WNDCLASS wndcl;

    switch ( msg )
    {                        
        case WM_ERASEBKGND :          
//			GetClassInfo(NULL,RICHEDIT_CLASS,&wndcl);
//			MMechostr(1," erasebkbng event for rich text %x\n",wndcl.hbrBackground);
//	        return( DefWindowProc( hwnd, msg, wParam, lParam ) );
        break ;

        case WM_LBUTTONUP :
        case WM_RBUTTONUP :
            x = LOWORD (lParam ) ;
            y = HIWORD ( lParam ) ;           
    
            MMechostr ( 1 , "Search for a reflex click in rich edit text\n" ) ;
            k=OBJbeginreflex(mm,OBJTYPRICHTEXT,(int)hwnd,RFLRICHTEXT_CLICK);
            if (k==0)
            {
      
                if (MMpush(mm,x<<1)) return MERRMEM;
                if (MMpush(mm,y<<1)) return MERRMEM;
                OBJcallreflex(mm,2);
            }
            break ;           

       case WM_DROPFILES : SCOLDropFiles (mm,hwnd,(HANDLE)wParam,OBJTYPRICHTEXT,RFLRICHTEXT_DROPFILE);
            break; 

        default : break ;
           
    }
    return CallWindowProc ( RichTextProc , hwnd , msg , wParam , lParam ) ;
}




/****************************************************************************************/
/*                                                                                      */
/*  HWND NewObjRichText ( PtrObjText Txt , char * Text , HWND Parent )                  */
/*                                                                                      */
/*                                                                                      */
/*  cree un nouvelle objet d'edition de texte riche multiligne                          */
/*                                                                                      */
/****************************************************************************************/

HWND NewObjRichText ( PtrObjText Txt , char * Text , HWND Parent , int Dialog )
{
int Flags ;
int Txt_Flags ; 
int Ex_Flag = WS_EX_TRANSPARENT ; 
HWND ret ;

        Txt_Flags = Txt->Flags ;
        Flags = ES_MULTILINE | ES_WANTRETURN | WS_VISIBLE ;
        if ( Parent != NULL ) Flags |= WS_CHILD  ;
        
        if ( Txt_Flags & ET_AHSCROLL ) Flags |= ES_AUTOHSCROLL ;
        if ( Txt_Flags & ET_AVSCROLL ) Flags |= ES_AUTOVSCROLL ;
        if ( Txt_Flags & ET_ALIGN_CENTER ) Flags |= ES_CENTER ;
        if ( Txt_Flags & ET_ALIGN_LEFT ) Flags |= ES_LEFT ;
        if ( Txt_Flags & ET_ALIGN_RIGHT ) Flags |= ES_RIGHT ;
        if ( Txt_Flags & ET_LOWERCASE ) Flags |= ES_LOWERCASE ;
        if ( Txt_Flags & ET_BORDER ) Flags |= WS_BORDER ;
        if ( Txt_Flags & ET_UPBORDER ) Flags |= WS_DLGFRAME ;
        if ( Txt_Flags & ET_HSCROLL ) Flags |= WS_HSCROLL ;
        if ( Txt_Flags & ET_VSCROLL ) Flags |= WS_VSCROLL ;
        if ( Txt_Flags & ET_TABFOCUS ) Flags |= WS_TABSTOP ;
        if ( Txt_Flags & ET_SIZEBOX ) Flags |= WS_SIZEBOX ;
        if ( Txt_Flags & ET_DOWN ) Ex_Flag |= WS_EX_CLIENTEDGE ;
        if ( Txt_Flags & ET_DRAGDROP ) Ex_Flag |= WS_EX_ACCEPTFILES ;

        ReadyText ( Text ) ;
        ret=  CreateWindowEx ( Ex_Flag ,
//                        RICHEDIT_CLASS ,
                        "RichEdit" ,
                        Text , Flags , 
                        Txt->PosX , Txt->PosY ,
                        Txt->TailleW , Txt->TailleH ,
                        Parent , NULL ,
                        (HINSTANCE)SCgetExtra("this_inst") , NULL ) ;

        if ( Txt_Flags & ET_NOEDIT ) SendMessage ( ret , EM_SETREADONLY , TRUE , 0 ) ;
        return ret ;
}


/******************************************************************************************/
/*                                                                                        */
/*  void SetRichTextBold ( HWND h , int onoff , int start , int end ) ;                   */
/*  Met en gras ou non-ègras une porition d'un riche edit texte                           */
/*                                                                                        */
/******************************************************************************************/

void SetRichTextBold ( HWND h , int onoff , int start , int end ) 
{
    CHARFORMAT Fmt ;
    CHARRANGE R , R2;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_BOLD ;
    if ( onoff ) Fmt.dwEffects = CFE_BOLD ;     else Fmt.dwEffects = 0 ;
    SendMessage ( h , EM_EXGETSEL,  0 , ( LPARAM ) ( &R2 ) );
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) (&R2));

}

/****************************************************************************************/
/*                                                                                      */
/*  void SetRichTextFont ( HWND h , char * FontName ) ;                                 */
/*  Modifie la font sur une portion d'un rich edit text                                 */
/*                                                                                      */
/****************************************************************************************/

void SetRichTextFont ( HWND h , char * FontName , int start , int end ) 
{
    CHARFORMAT Fmt ;
    CHARRANGE R , R2 ;   

    /* verifie la taille du nom de la police de caractere */
    if ( strlen ( FontName ) >= LF_FACESIZE ) return ;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_FACE +CFM_CHARSET;
    strcpy ( Fmt.szFaceName , FontName ) ;
    Fmt.bCharSet = DEFAULT_CHARSET ;
    Fmt.bPitchAndFamily = DEFAULT_PITCH ;
    SendMessage ( h , EM_EXGETSEL , 0,  ( LPARAM ) ( &R2 ));
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;  
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R2));

}

/*********************************************************************************************/
/*                                                                                           */
/*      void SetRichTextUnderline ( HWND h , int onoff , int start , int end )  ;            */
/*      Souligne ou ne souligne pas une partie d'un objet texte riche                        */
/*                                                                                           */
/*********************************************************************************************/

void SetRichTextUnderline ( HWND h , int onoff , int start , int end ) 
{
    CHARFORMAT Fmt ;
    CHARRANGE R, R2 ;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_UNDERLINE ;
    if ( onoff ) Fmt.dwEffects = CFE_UNDERLINE ;     else Fmt.dwEffects = 0 ;
    SendMessage ( h , EM_EXGETSEL , 0 , ( LPARAM ) ( &R2 ));
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R2 )) ;

}

/********************************************************************************************/
/*                                                                                          */
/*          void SetRichTextHeight ( HWND h , int taille , int start , int end )  ;         */
/*          Modifie la taille d'une portion d'un riche edit texte                           */
/*                                                                                          */
/********************************************************************************************/

void SetRichTextHeight ( HWND h , int taille , int start , int end ) 
{
    CHARFORMAT Fmt ;
    CHARRANGE R,R2 ;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_SIZE ;
    Fmt.yHeight = taille * 25;
    SendMessage ( h , EM_EXGETSEL , 0 , ( LPARAM ) ( &R2 ));
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R2 )) ;

}

/********************************************************************************************/
/*                                                                                          */
/*  void SetRichTextColor ( HWND h , int Color , int start , int end ) ;                    */
/*  Modifie la couleur d'une porition d'un riche edit texte                                 */
/*                                                                                          */
/********************************************************************************************/

void SetRichTextColor ( HWND h , int Color , int start , int end )
{
    CHARFORMAT Fmt ;
    CHARRANGE R,R2 ;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_COLOR ;
    Fmt.dwEffects = 0 ;
    Fmt.crTextColor = Color ;
    SendMessage ( h , EM_EXGETSEL , 0 , ( LPARAM ) ( &R2 ));
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R )) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R2)) ;
} ;

/****************************************************************************************/
/*                                                                                      */
/*  void SetRichTextItalic ( HWND h , int onoff , int start , int end ) ;               */
/*  Met en italique ou non une porition d'un riche edit texte                           */
/*                                                                                      */
/****************************************************************************************/

void SetRichTextItalic ( HWND h , int onoff , int start , int end ) 
{
    CHARFORMAT Fmt ;
    CHARRANGE R,R2 ;


    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_ITALIC ;
    if ( onoff ) Fmt.dwEffects = CFE_ITALIC ;     else Fmt.dwEffects = 0 ;
    SendMessage ( h , EM_EXGETSEL , 0 , ( LPARAM ) (&R2)) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R2 )) ;

}

/****************************************************************************************/
/*                                                                                      */
/*  void SetRichTextStriked ( HWND h , int onoff , int start , int end ) ;              */
/*  Barre ou ne barre pas une portion d'un texte riche                                  */
/*                                                                                      */
/****************************************************************************************/

void SetRichTextStrikeout ( HWND h , int onoff , int start , int end )
{
    CHARFORMAT Fmt ;
    CHARRANGE R,R2 ;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_STRIKEOUT ;
    if ( onoff ) Fmt.dwEffects = CFE_STRIKEOUT ;     else Fmt.dwEffects = 0 ;
    SendMessage ( h , EM_EXGETSEL , 0 , ( LPARAM ) ( &R2)) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R2 ));

}

/****************************************************************************************/
/*                                                                                      */
/*  void SetRichTextOffset ( HWND h , int offset , int start , int end ) ;              */
/*  Place le decalage vertical d'un texte pour une portion d'un texte riche             */
/*                                                                                      */
/****************************************************************************************/

void SetRichTextOffset ( HWND h , int offset , int start , int end )
{
    CHARFORMAT Fmt ;
    CHARRANGE R,R2 ;

    R.cpMin = start ;
    R.cpMax = end ;
    Fmt.cbSize = sizeof ( CHARFORMAT ) ;
    Fmt.dwMask = CFM_OFFSET ;
    Fmt.yOffset = offset ;
    SendMessage ( h , EM_EXGETSEL , 0 , ( LPARAM ) (&R2));
    SendMessage ( h , EM_EXSETSEL , 0 , ( LPARAM ) ( &R ) ) ;
    SendMessage ( h , EM_SETCHARFORMAT , SCF_SELECTION , ( LPARAM ) ( &Fmt )) ;
    SendMessage ( h , EM_EXSETSEL, 0 , ( LPARAM ) (&R2));

}





int GRSetRichRTF ( mmachine m )
{
    return 0 ;
}

/********************************************************************************************************/
/*                                                                                                      */
/*      int GRGetCharFromPos ( mmachine m ) ;                                                           */
/*                                                                                                      */
/*      Cette fonction correspond a la fonction magma _GETcharFromPos ( ObjRichText I I ) laquelle      */
/*      retourne un index dans le texte a partir de coordonnéesv x y dans la fenetre, indiquant quel    */
/*      caractere a ete affichée à cette coordonnée.                                                    */
/*                                                                                                      */
/********************************************************************************************************/

int GRGetCharFromPos ( mmachine m ) 
{
    int s , r , u ;
    PtrObjVoid O ;     
    PtrObjText T ;
    POINT p ;
    char TEXT [ MAX_TEXT ] ;

    p.y = MMpull ( m ) >> 1 ;
    p.x = MMpull ( m ) >> 1 ;
    s = MMpull ( m ) ;    
    if ( s == NIL ) r = NIL ;
    else ;    
    {        
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ; 
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;    
        r = SendMessage ( T->WHandler , EM_CHARFROMPOS , 0 , ( LPARAM ) &p );    
        GetText ( T->WHandler , TEXT ) ;
        u = r ;
        for ( s = 0 ; s < u ; s ++ ) 
        if ( TEXT [ s ] == '\n' ) r -- ;
    }

    MMechostr ( 1 , "Result = index %d\n" , r ) ;
    return MMpush ( m , r << 1 ) ;
}

/*****************************************************************************/
/*                                                                           */
/*      fonction GRReflexRichText ( mmachine m ) ;                           */
/*                                                                           */
/*      Cette fonction permet de definir le callback d'une fenetre rich edit */
/*  text vis a vis de l'evenement click                                      */
/*                                                                           */
/*****************************************************************************/

int GRReflexRichText ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPRICHTEXT,RFLRICHTEXT_CLICK);
}

/*****************************************************************************/ 
/*                                                                           */ 
/* fonction GRReflexRichTextDropFile ( mmachine m ) ;                        */ 
/*                                                                           */ 
/*  Cette fonction permet de definir le callback d'une fenetre RT quand au   */ 
/* drop file de fichier sur cette fenetre                                    */ 
/*                                                                           */ 
/*****************************************************************************/ 

int GRReflexRichTextDropFile ( mmachine m )
{
    return OBJaddreflex(m,OBJTYPRICHTEXT,RFLRICHTEXT_DROPFILE);
}

/*****************************************************************************/
/*                                                                           */
/*  fonction int GRCreateRichText ( mmachine m ) ;                           */
/*                                                                           */
/*  Cette fonction C correspond a la fonction magma                          */
/*  _CRrichText                                                              */
/*  Channel Parent X Y W H Flag Text                                         */
/*                                                                           */
/*****************************************************************************/

int GRCreateRichText ( mmachine m )
{
    PtrObjVoid O , OP ;
    PtrObjText T ;
    PtrObjWindow PW ;
    int s , l , s2 , res  , dialog ;
    char Text [ MAX_TEXT ] ;
    char * I ;
    HWND Parent , HW ;
   
    /*************************** DEBUG 2D *************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG CreateRichText\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /***************************************************************************/

    /* text si channel != NIL */
    if (MMget(m,7)==NIL)
    {
        MMechostr(MSKDEBUG,"_CRrichEditText : channel is NIL\n");
        m->pp+=7;
        MMset(m,0,NIL);
        return 0;
    }

 
    s = MMpull ( m ) ;
    if ( s == NIL ) strcpy ( Text , "" ) ;
    else
    {
        I = ( char * ) MMstart(m,(s>>1)+1);
        if ( strlen ( I ) >= MAX_TEXT )
        {
            MMechostr ( 1 , "CreateRichText : String too long.\n" ) ;
            strcpy ( Text , "" ) ;
        }
        else strcpy ( Text , I ) ;
    }

    /* 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 ObjText ) + 3 ) >> 2 ;
    s2 = MMmalloc ( m,l,TYPEBUF ) ;
    if ( s2 == NIL )
    {
        MMechostr(MSKDEBUG,"_create_edit_text : Error in alloc MAGMA Memory\n" ) ;
        return MERRMEM ;
    }


    T = ( PtrObjText ) MMstart(m, s2 ) ;
    s = MMpull (m ) ; /* recupere l'addresse de l'objet de base */
    O = ( PtrObjVoid ) MMstart(m, (s>>1) ) ;

    O->Type     = OBJ_TYPE_RICH_TEXT << 1 ;   
    T -> Flags          = MMpull(m) >> 1 ;
    T -> TailleH        = MMpull(m) >> 1 ;
    T -> TailleW        = MMpull(m) >> 1 ;
    T -> PosY           = MMpull(m) >> 1 ;
    T -> PosX           = MMpull(m) >> 1 ;
    O -> Father           = MMpull(m) ;  
    O -> Buffer           = ( s2 << 1 ) + 1 ;
    O -> Tab              = NIL ;

    /* recuperation du handler window du parent, si parent il y a */
    if ( O -> Father == NIL ) Parent = NULL ;
    else
    {
        OP = ( PtrObjVoid ) MMstart(m, (O->Father>>1) ) ;
        if ( OP->Type != OBJ_TYPE_WINDOW << 1 )
        {
            MMechostr ( 1,"CreateEditText : Parent must be a window\n" ) ;
            MMpull(m);
			return MMpush(m,NIL) ;
        }
        
        PW = ( PtrObjWindow ) MMstart(m, (OP->Buffer >> 1 ) ) ;
        if ( PW->Flags & WN_DIALOG ) dialog = 1 ; else dialog = 0 ;
        Parent = PW->WHandler ;
    }
    if ( ! InitRichText )
    {
//        if ( LoadLibrary ("RICHED20.DLL") == NULL )
        if ( LoadLibrary ("RICHED32.DLL") == NULL )
        {
            MMechostr ( 1 , "Can't LOAD RICHED32.DLL\n" ) ;
            MMpull(m);
            return MMpush(m,NIL ) ;
        }
    }
    
    HW = NewObjRichText ( T , NULL , Parent , dialog ) ;    
    if ( ! HW )
    {
        MMechostr(MSKDEBUG,"_create_edit_text : Error in creating the WIN Obj - Check the values\n" ) ;
        MMpull(m);
        return MMpush(m,NIL) ;
    }
    T->WHandler = HW ;

 
  
   if ( InitRichText == 0 )
   {
        RichTextProc = ( WNDPROC ) GetWindowLong ( HW , GWL_WNDPROC ) ;
        InitRichText = 1 ;
    }
    SetWindowLong ( HW , GWL_WNDPROC , ( long ) RichProc2 ) ;   
   
   
    
    if ( MMpush(m,s)) return MERRMEM ;
 
    res = OBJcreate(m,OBJTYPRICHTEXT,(int)HW,OBJTYPWINDOW,(int)Parent) ;
 
    ReadyText ( Text ) ;
    SetText (HW,Text ) ; 
 /*   InvalidateRect(HW,NULL,TRUE);
    UpdateWindow (HW);*/


    /************************** DEBUG 2D *******************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG CreateRichText done" ) ;
    #endif
    /********************************************************************************/

    return res ;


}

/*****************************************************************************/
/*                                                                           */
/*  fonction int GRSetRichTextUnderline ( mmachine m ) ;                     */
/*                                                                           */
/*  Cette fonction C correspond a la fonction magma                          */
/*  _SETunderlineRichText ObjRichText I OnOff I Start I End -> ObjRichText   */
/*                                                                           */
/*****************************************************************************/

int GRSetRichTextUnderline ( mmachine m ) 
{
    int s , i , onoff , start , end ;
    PtrObjVoid  O;
    PtrObjText T ;
    char TEXT [ MAX_TEXT ] ;

    /*********************** DEBUG ********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG SETCOLORRICHTEXT\n" ) ;
        Fdebug2D ( m );
    #endif
    /***************************************************************************/

    end = MMpull ( m  )  >> 1;
    start = MMpull ( m ) >> 1 ;
    onoff = MMpull ( m ) >> 1 ;
    s = MMpull(m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
        GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextUnderline ( T->WHandler , onoff , start , end ) ;
    }

    s = MMpush ( m , s)  ;
    /******************** DEBUG ****************************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG SETCOLORRICHTEXT Done\n" ) ;
    #endif
    /*********************************************************************************/

    return s ;
}
 
/*****************************************************************************/
/*                                                                           */
/*  fonction int GRSetRichTextFont ( mmachine m ) ;                          */
/*                                                                           */
/*  Correspond a la fonction magma ObjRichText _set_font_rich_text           */
/*  ( ObjRichText , S fontname, I start , I end ) ;                          */
/*                                                                           */
/*****************************************************************************/

int GRSetRichTextFont ( mmachine m ) 
{
    int s , i , start , end ;
    char * police ;
    PtrObjVoid O ;
    PtrObjText T ;
    char TEXT [MAX_TEXT] ;

    /********************************** DEBUG 2D *****************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _SETfontRichText\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /*************************************************************************/

    end = MMpull ( m ) >> 1 ;
    start = MMpull ( m ) >> 1 ;
    s = MMpull ( m ) ;
    if ( s == NIL )
    {
        MMechostr ( 1 , "NIL font in _SETfontRichText\n" ) ;
        return 0 ;
    }
    police = ( char * ) MMstart(m,(s>>1) + 1) ;
    s = MMpull ( m ) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;

        GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }
        SetRichTextFont ( T->WHandler , police , start , end ) ;
    }
    s = MMpush ( m , s ) ;

    /********************************* DEBUG 2D ******************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _SETfontRichText done\n" ) ;
    #endif
    /****************************************************************************/

    return s ;
}

/*****************************************************************************/
/*                                                                           */
/*  fonction int GRSetRichTextColor ( mmachine m ) ;                         */
/*                                                                           */
/*  Cette fonction C correspond a la fonction magma                          */
/*  _SETcolorRichText ObjRichText I Color I Start I End -> ObjRichText       */
/*                                                                           */
/*****************************************************************************/

int GRSetRichTextColor ( mmachine m ) 
{
    int s , i , c , start , end ;
    PtrObjVoid  O;
    PtrObjText T ;
    char TEXT [ MAX_TEXT] ;

    /*********************** DEBUG ********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG SETCOLORRICHTEXT\n" ) ;
        Fdebug2D ( m );
    #endif
    /***************************************************************************/

    end = MMpull ( m  )  >> 1;
    start = MMpull ( m ) >> 1 ;
    c = MMpull ( m ) >> 1 ;
    s = MMpull(m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
         GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextColor ( T->WHandler , c , start , end ) ;
    }

    s = MMpush ( m , s)  ;
    /******************** DEBUG ****************************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG SETCOLORRICHTEXT Done\n" ) ;
    #endif
    /*********************************************************************************/

    return s ;
}
        
/*****************************************************************************/
/*                                                                           */
/*  int GRSetRichTextItalic ( mmachine ) ;                                   */
/*  fonction qui correspond a la fonction magma                              */
/*  ObjRichText _SETitalicRichText ( Obj , I , I , I ) ;                     */
/*                                                                           */
/*****************************************************************************/

int GRSetRichTextItalic ( mmachine m ) 
{
int s , i , c , start , end ;
    PtrObjVoid  O;
    PtrObjText T ;
    char TEXT [ MAX_TEXT] ;

    /*********************** DEBUG ********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG _SETitalicRichTextC\n" ) ;
        Fdebug2D ( m );
    #endif
    /***************************************************************************/

    end = MMpull ( m  )  >> 1;
    start = MMpull ( m ) >> 1 ;
    c = MMpull ( m ) >> 1 ;
    s = MMpull(m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
         GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextItalic ( T->WHandler , c , start , end ) ;
    }

    s = MMpush ( m , s)  ;
    /******************** DEBUG ****************************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG SETCOLORRICHITALIC Done\n" ) ;
    #endif
    /*********************************************************************************/

    return s ;
}


/*****************************************************************************/
/*                                                                           */
/*  int GRsetRichTextBold ( mmachine m ) ;                                   */
/*  fonction c qui correspond a la fonction magma                            */
/*  _SETboldRichText ( Obj , I 0/1 , I Start , I End ) ;                     */
/*                                                                           */
/*****************************************************************************/

int GRSetRichTextBold ( mmachine m ) 
{
    int s ,  i , start , end , bold ;
    PtrObjVoid O ;
    PtrObjText T ;
    char TEXT [ MAX_TEXT ] ;

    /**************** DEBUG 2D ***********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG SetBoldRichText\n" ) ;
        Fdebug2D ( m ) ;
    #endif
    /**************************************************************************/

    end = MMpull ( m ) >> 1 ;
    start = MMpull ( m ) >> 1 ;
    bold = MMpull ( m ) >> 1 ;
    s = MMpull ( m ) ;
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
        GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextBold ( T->WHandler , bold , start , end ) ;

    }

    s = MMpush( m , s ) ;

    /******************************* DEBUG 2D ************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "" ) 
    #endif
    /*****************************************************************************/

    return s ;
}


/***************************************************************************************/
/*                                                                                     */
/*  int GRSetRichTextStrikeout ( mmachine m ) ;                                        */
/*  Cette fonction correspond a la fonction magma                                      */
/*  ObjRichText _SETstrikeoutRichText ( ObjRichText , I , I , I ) ;                    */
/*                                                                                     */
/***************************************************************************************/


int GRSetRichTextStrikeout ( mmachine m ) 
{
int s , i , c , start , end ;
    PtrObjVoid  O;
    PtrObjText T ;
    char TEXT [ MAX_TEXT] ;

    /*********************** DEBUG ********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG _SETstrikeoutRichTextC\n" ) ;
        Fdebug2D ( m );
    #endif
    /***************************************************************************/

    end = MMpull ( m  )  >> 1;
    start = MMpull ( m ) >> 1 ;
    c = MMpull ( m ) >> 1 ;
    s = MMpull(m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
         GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextStrikeout ( T->WHandler , c , start , end ) ;
    }

    s = MMpush ( m , s)  ;
    /******************** DEBUG ****************************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _SETstrikeoutRichText Done\n" ) ;
    #endif
    /*********************************************************************************/

    return s ;
}

/**********************************************************************************************/
/*                                                                                            */
/*      int GRSetRichTextSize ( mmachine m ) ;                                                */
/*                                                                                            */
/*      Cette fonction correspond a la fonction magma                                         */
/*      ObjRichText _SETsizeRichText (ObjRichText,I,I,I) ; qui change la taille d'une portion */
/*  de texte dans un RT                                                                       */
/*                                                                                            */
/**********************************************************************************************/

int GRSetRichTextSize ( mmachine m )
{
    int s , i , c , start , end ;
    PtrObjVoid  O;
    PtrObjText T ;
    char TEXT [ MAX_TEXT] ;

    /*********************** DEBUG ********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG _SETsizeRichTextC\n" ) ;
        Fdebug2D ( m );
    #endif
    /***************************************************************************/

    end = MMpull ( m  )  >> 1;
    start = MMpull ( m ) >> 1 ;
    c = MMpull ( m ) >> 1 ;
    s = MMpull(m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
        GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextHeight ( T->WHandler , c , start , end ) ;
    }

    s = MMpush ( m , s)  ;
    /******************** DEBUG ****************************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _SETsizeRichText Done\n" ) ;
    #endif
    /*********************************************************************************/

    return s ;
}


/**********************************************************************************************/
/*                                                                                            */
/*  int GRSetRichTextOffset ( mmachine m ) ;                                                  */
/*  Cette fonction correspond a la fonction magma                                             */
/*  ObjRichText _SEToffsetRichText ( ObjRichText , I , I , I ) ;                              */
/*                                                                                            */
/**********************************************************************************************/

int GRSetRichTextOffset ( mmachine m ) 
{
int s , i , c , start , end ;
    PtrObjVoid  O;
    PtrObjText T ;
    char TEXT [ MAX_TEXT] ;

    /*********************** DEBUG ********************************************/
    #ifdef DEBUG2D
        MMechostr ( 1 , "DBG _SEToffsetRichTextC\n" ) ;
        Fdebug2D ( m );
    #endif
    /***************************************************************************/

    end = MMpull ( m  )  >> 1;
    start = MMpull ( m ) >> 1 ;
    c = MMpull ( m ) >> 1 ;
    s = MMpull(m ) ;
    if ( s != NIL ) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1)) ;
        GetText ( T->WHandler , TEXT ) ;
        i = 0 ;
        while ( i < start )
        {
            if ( TEXT [ i ] == '\n' ) start ++ ;       
            i ++ ;
        }
        i = 0 ;
        while ( i < end ) 
        {
            if ( TEXT [ i ] == '\n' ) end ++ ;
            i ++ ;
        }

        SetRichTextOffset ( T->WHandler , c , start , end ) ;
    }

    s = MMpush ( m , s)  ;
    /******************** DEBUG ****************************************************/
    #ifdef DEBUG2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "DBG _SEToffsetRichText Done\n" ) ;
    #endif
    /*********************************************************************************/

    return s ;
}

/****************************************************************************************/
/*                                                                                      */
/*      int GRDestroyRichText ( mmachine m ) ;                                          */
/*  correspond a la fonction magma I _DSrichTest ( ObjRichText ) ;                      */
/*                                                                                      */
/****************************************************************************************/

int GRDestroyRichText ( mmachine m ) 
{
    int s ;
    PtrObjVoid O ;
    HWND h ;

    /************************** DEBUG 2D ******************/
    #ifdef TRACE2D
        MMechostr ( 1 , "DBG _destroy_obj_richtext\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /*********************************************************/

    s = MMget(m,0) ;
    if ( s!=NIL) 
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1) ) ;
        h = (( PtrObjText ) ( MMstart(m, (O->Buffer>>1 )) ))->WHandler ;
        OBJdelTH(m,OBJTYPRICHTEXT,(int)h) ;
    }    

    /********************** DEBUG 2D *************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr( 1 , "DBG _destroy_obj_richtext Done\n" ) ;
    #endif
    /***********************************************************/

    MMset(m,0,0) ;
    return 0 ;
}


/*******************************************************************************/
/*                                                                             */
/*      int GRSetTextRichText ( mmachine m )                                   */
/*                                                                             */
/*      correspond a la fonction magma                                         */
/*      ObjRichText _SETtextRichText ( ObjRichText , S , ObjFont , I size ,    */
/*          I color , I flag ) ;                                               */
/*                                                                             */
/*******************************************************************************/

int GRSetTextRichText ( mmachine m )
{
    int flag,color,size,sf,s,i,end;
    char Text [ MAX_TEXT ] ;
    char * I ,* police ;
    PtrObjVoid O ;
    PtrObjText T ;

    /**************************** DEBUG 2D **************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"DBG _SETtextRichText\n");
        FDebug2D(m);
    #endif
    /****************************************************************************/

    flag=MMpull(m)>>1;
    color=MMpull(m)>>1;
    size=MMpull(m)>>1;
    sf=MMpull(m);
    if ( sf!=NIL) police = ( char * )MMstart(m,(sf>>1)+1);
    else police=NULL;
    s=MMpull(m);
    if(s==NIL) strcpy ( Text , "" ) ;
    else
    {
        I = ( char * ) MMstart(m,(s>>1)+1);
        if(strlen(I)>=MAX_TEXT)
        {
            MMechostr(MSKDEBUG,"_SETtextRichText : string too long\n");
            return 0;
        }
        strcpy(Text,I);
    }
    s=MMpull(m);
    if(s!=NIL)
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1));
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1));
        i = 0 ;
        end=0;
        while (Text[i]) 
        {
            end++;
            if (Text[i]=='\n') end ++ ;
            i ++ ;
        }

        SetText(T->WHandler,Text);
        SetRichTextFont(T->WHandler,police,0,end);
        SetRichTextColor(T->WHandler,color,0,end);
        SetRichTextHeight(T->WHandler,size,0,end);

        if(flag & RTF_FLAG_UNDERLINE)
        SetRichTextUnderline ( T->WHandler , 1 , 0 , end ) ;
        else SetRichTextUnderline(T->WHandler,0,0,end);

        if(flag & RTF_FLAG_STRIKED)
        SetRichTextStrikeout(T->WHandler,1,0,end);
        else SetRichTextStrikeout(T->WHandler,0,0,end);

        if(flag & RTF_FLAG_BOLD)
        SetRichTextBold(T->WHandler,1,0,end);
        else SetRichTextBold(T->WHandler,0,0,end);

        if(flag & RTF_FLAG_ITALIC)
        SetRichTextItalic(T->WHandler,1,0,end);
        else SetRichTextItalic(T->WHandler,0,0,end);

        if(flag & RTF_FLAG_OFFSET)
        SetRichTextOffset(T->WHandler,1,0,end);
        else SetRichTextOffset(T->WHandler,0,0,end);        
        
    }

    s = MMpush(m,s);

    /************************** DEBUG 2D *****************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"DBG _SETtextRichText\n");
    #endif
    /********************************************************************************/

    return s ;
}

/*************************************************************************************/
/*                                                                                   */
/*      int GRAddTextRichText ( mmachine m ) ;                                       */
/*                                                                                   */
/*  correspond a la fonction magma ObjRichText _ADDtextRichText ( ObjRichText ,      */
/*      S , ObjFont , I size , I color , I flag ) ;                                  */
/*  laquelle ajoute du texte formatte a un objet texte riche                         */
/*                                                                                   */
/*************************************************************************************/

int GRAddTextRichText ( mmachine m )
{
    int i,flag,color,size,sf,st,s,start,end,j;
    char Text [ MAX_TEXT ] ;
    char * I , * police ;
    PtrObjVoid O ;
    PtrObjText T ;
    CHARRANGE crange ;

    /**************************** DEBUG 2D **************************************/
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"DBG _ADDtextRichText\n");
        FDebug2D(m);
    #endif
    /****************************************************************************/

    flag=MMpull(m);  if (flag != NIL) flag >>= 1 ;
    color=MMpull(m); if (color != NIL) color >>=1 ;
    size=MMpull(m);  if (size!=NIL ) size>>=1 ;
    sf=MMpull(m);
    if ( sf!=NIL) police = ( char * )MMstart(m,(sf>>1)+1);
    else police=NULL;
    st=MMpull(m);
    if(st!=NIL)    
    {
        I = ( char * ) MMstart(m,(st>>1)+1);
        if(strlen(I)>=MAX_TEXT)
        {
            MMechostr(MSKDEBUG,"_ADDtextRichText : string too long\n");
            return 0;
        }
        strcpy(Text,I);
    }
    s=MMpull(m);
    if(s!=NIL && st!=NIL)
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1));
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1));
        GetText(T->WHandler,Text);
        i = 0 ;
        start=0;
        while ( Text[i] ) 
        {
            start++;
            if ( Text [ i ] == '\n' ) start ++ ;
            i ++ ;
        }
      
        if(strlen(Text)+strlen(I)>=MAX_TEXT)
           MMechostr(MSKDEBUG,"_ADDrichText : string too long\n");
        else
        {
            strcat (Text,I);
            i=0;
            end=0;
            while(Text[i])
            {
                end++;
                if(Text[i]=='\n')end++;
                i++;
            }
            crange.cpMin = start ;
            crange.cpMax = start ;
            i = 0 ; j = 0 ;
            while ( I [ i ] )
            {
                
                if ( I [ i ] == '\n' ) Text [ j ++ ] = '\r' ;
                Text [ j ++ ] = I [ i ++ ] ;
            }
            Text [ j ] = 0 ;
            SendMessage ( T->WHandler , EM_EXSETSEL , 0 , (LPARAM ) &crange ) ;

            if ( police != NULL ) SetRichTextFont(T->WHandler,police,start,start);
            if ( color!= NIL) SetRichTextColor(T->WHandler,color,start,start);
            if ( size != NIL ) SetRichTextHeight(T->WHandler,size,start,start);

            if((flag & RTF_FLAG_UNDERLINE) && flag != NIL)
            SetRichTextUnderline ( T->WHandler , 1 , start , start ) ;
            else SetRichTextUnderline (T->WHandler,0,start,start);

            if((flag & RTF_FLAG_STRIKED) && flag != NIL)
            SetRichTextStrikeout(T->WHandler,1,start,start);
            else SetRichTextStrikeout(T->WHandler,0,start,start);

            if((flag & RTF_FLAG_BOLD) && flag != NIL)
            SetRichTextBold(T->WHandler,1,start,start);
            else SetRichTextBold(T->WHandler,0,start,start);

            if((flag & RTF_FLAG_ITALIC) && flag != NIL)
            SetRichTextItalic(T->WHandler,1,start,start);
            else SetRichTextItalic(T->WHandler,0,start,start);

            if((flag & RTF_FLAG_OFFSET) && flag != NIL)
            SetRichTextOffset(T->WHandler,1,start,start);
            else SetRichTextOffset(T->WHandler,1,start,start);

            SendMessage ( T->WHandler , EM_REPLACESEL , FALSE , (LPARAM) (char *) Text );

            InvalidateRect(T->WHandler,NULL,TRUE);
            UpdateWindow (T->WHandler);

        }

    }

    s = MMpush(m,s);

    /************************** DEBUG 2D *****************************************/
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"DBG _ADDtextRichText\n");
    #endif
    /********************************************************************************/

    return s ;
}





/****************************************************************************/ 
/*                                                                          */ 
/*  GRRtfRichText ( mmachine m ) ;                                          */ 
/*                                                                          */ 
/*   correspond a _RTFtoRichText (ObjRichText,S)                            */ 
/*                                                                          */ 
/****************************************************************************/ 

GRRtfRichText ( mmachine m )
{

    int s , s2 ;
    /****************** TRACE 2D ********************************************/ 
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _RTFtoRichText\n");
        FDebug2D(m);
    #endif
    /************************************************************************/ 

    s2 = MMpull(m) ;
    s = MMpull( m ) ;

    s = MMpush(m,s ) ;

    /***************** TRACE 2D *********************************************/ 
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _RTFtoRichText done\n");
    #endif
    /************************************************************************/ 

    return s ;
}


/****************************************************************************/ 
/*                                                                          */ 
/*      int GRGetRichLineCount ( mmachine m ) ;                             */ 
/*                                                                          */ 
/*      Correspond a la fonction scol _GETrichLineCount(ObjRichText)-> I    */ 
/*  Laquelle retourne le nombre de ligne d'un objet texte riche             */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRGetRichLineCount ( mmachine m )
{
    int s , count,i;
    PtrObjVoid O ;
    PtrObjText T ;
    char Text [ MAX_TEXT ] ;

    /********************** TRACE 2D ****************************************/ 
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _GETrichLineCount\n");
        FDebug2D(m);
    #endif TRACE2D
    /************************************************************************/ 

    count = NIL ;
    s = MMpull(m);
    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1));
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1));
        GetText(T->WHandler,Text);
        i = 0 ;
        count=0;
        while ( Text[i] ) 
        {           
            if ( Text [ i ] == '\n' ) count ++ ;
            i ++ ;
        }
        s = MMpush(m,count<<1);
    }
    else s = MMpush(m,0);

    /******************* TRACE D ********************************************/ 
    #ifdef TRACED
        FDebugD(m);
        MMechostr(,"(DBG) _GETrichLineCount done\n");
    #endif
    /************************************************************************/ 

    return s ;
}

/****************************************************************************/ 
/*                                                                          */ 
/*      fun GRDelRichTextLine ( mmachine m ) ;                              */ 
/*                                                                          */ 
/*      Correspond a la fonction scol _DELlineRichText(ObjRichText,I)->ORT  */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRDelRichTextLine ( mmachine m )
{
    int s , l , la ;
    PtrObjVoid O ;
    PtrObjText T ;
    HWND HW ;
    char BUF [33000] ;
    CHARRANGE crange ;

     /************************** DEBUG 2D *****************************************/
    #ifdef TRACE2D
        MMechostr ( 1 , "(DBG) _DELlineRichText\n" ) ;
        FDebug2D ( m ) ;
    #endif
    /******************************************************************************/


    l = MMpull(m) >> 1 ;
    s = MMpull(m) ;

    if ( l  >= 0 && s != NIL )
    {
       
        O = ( PtrObjVoid ) MMstart(m, ( s>>1) ) ;
        T = ( PtrObjText ) MMstart(m, (O->Buffer>>1) ) ;        
        HW = T->WHandler ;  
        GetText(HW,BUF);
            
        la = 0 ;
        crange.cpMin = 0 ;       
        while ( BUF [ crange.cpMin ] && la != l )        
            if ( BUF [ crange.cpMin ++ ] == '\n' ) la ++ ;                                                              

        crange.cpMax = crange.cpMin ;
        while ( BUF [ crange.cpMax ] && la == l )
            if ( BUF [ crange.cpMax ++ ] == '\n' ) la ++ ;      
           
        crange.cpMin += l ;
        crange.cpMax += la ;

        SendMessage ( HW , EM_EXSETSEL , 0 , (LPARAM ) &crange ) ;
        SendMessage ( HW , EM_REPLACESEL , FALSE , (LPARAM) (char *) "" );

        InvalidateRect(HW,NULL,TRUE);
        UpdateWindow (HW);

    }

   
    s = MMpush(m,s) ;

    /*********************************** DEBUG 2D ************************************/
    #ifdef TRACE2D
        FDebug2D ( m ) ;
        MMechostr ( 1 , "(DBG) _DELlineRichText done\n" ) ;
    #endif
    /*********************************************************************************/
    return s ;
}
/****************************************************************************/ 
/*                                                                          */ 
/*  int GRSetBkgColorRichText ( mmachine m ) ;                              */ 
/*                                                                          */ 
/*  change la couleur de fond d'un objet riche texte                        */ 
/*                                                                          */ 
/****************************************************************************/ 

int GRSetBkgColorRichText ( mmachine m )
{
    int s , i ;
    PtrObjVoid O ;
    PtrObjText T ;

    /************** TRACE 2D ************************************************/ 
    #ifdef TRACE2D
        MMechostr(MSKDEBUG,"(DBG) _SETbkgColorRichText.\n");
        FDebug2D(m);
    #endif
    /************************************************************************/ 

    i = MMpull(m)>>1;
    s = MMpull(m);

    if ( s != NIL )
    {
        O = ( PtrObjVoid ) MMstart(m,(s>>1)) ;
        T = ( PtrObjText ) MMstart(m,(O->Buffer>>1));
        SendMessage(T->WHandler,EM_SETBKGNDCOLOR,0,i);
        UpdateWindow(T->WHandler);
    }

    s = MMpush(m,s);

    /************************** TRACE 2D ************************************/ 
    #ifdef TRACE2D
        FDebug2D(m);
        MMechostr(MSKDEBUG,"(DBG) _SETkbgcolorRichText done.\n");
    #endif
    /************************************************************************/ 

    return s;

}

