/*ProfiPacket - packet radio terminal program
  Copyright (C) 1999  Alexander Feigl

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  Author:

  Alexander Feigl
  Burachstraße 51

  D-88250 Weingarten

  Mail : Alexander.Feigl@gmx.de
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define __far
#include <libraries/mui.h>

#include "Editor.h"
#include "EditorPrivate.h"                                                                 

#include <graphics/scale.h>
#include <exec/memory.h>


#include <clib/muimaster_protos.h>
#include <clib/alib_protos.h>
#include <clib/utility_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/keymap_protos.h>

#ifdef __GNUC__


extern void *SysBase;
extern void *IntuitionBase;
extern void *UtilityBase;
extern void *GfxBase;
extern void *KeymapBase;
extern void *MUIMasterBase;

#define NO_INLINE_STDARG
#include <inline/muimaster.h>
#include <inline/exec.h>
#include <inline/intuition.h>
#include <inline/utility.h>
#include <inline/graphics.h>
/*#include <inline/keymap.h>*/
#endif

#include <devices/inputevent.h>

#include <exec/memory.h>




__far const unsigned char ConvertAmiga2PC[256]=
                       {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                        0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
                        0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
                        0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
                        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
                        0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
                        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
                        0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
                        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
                        0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
                        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
                        0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
                        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
                        0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
                        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
                        0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0xAD,0x9B,0x9C,0x20,0x9D,0xB3,0x15,
                        0x20,0x63,0xA6,0xAE,0xAA,0xC4,0x72,0xDF,
                        0xF8,0xF1,0xFD,0x33,0x20,0xE6,0x14,0xFA,
                        0x20,0x31,0xA7,0xAF,0xAC,0xAB,0x20,0xA8,
                        0x85,0xA0,0x83,0x41,0x8E,0x8F,0x92,0x80,
                        0x8A,0x90,0x88,0x89,0x8D,0xA1,0x8C,0x8B,
                        0x44,0xA5,0x95,0xA2,0x93,0x4F,0x99,0x78,
                        0x4F,0x97,0xA3,0x96,0x9A,0x59,0x50,0xE1,
                        0x85,0xA0,0x83,0x61,0x84,0x86,0x91,0x87,
                        0x8A,0x82,0x88,0x89,0x8D,0xA1,0x8C,0x8B,
                        0x64,0xA4,0x95,0xA2,0x93,0x6F,0x94,0xF6,
                        0x6F,0x97,0xA3,0x96,0x81,0x79,0x70,0x98};

__far const unsigned char ConvertPC2Amiga[256]=
                       {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
                        0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
                        0x10,0x11,0x12,0x13,0xB6,0xA7,0x16,0x17,
                        0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
                        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
                        0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
                        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
                        0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
                        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
                        0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,
                        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
                        0x58,0x59,0x5A,0x5B,0x5C,0x5D,0x5E,0x5F,
                        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
                        0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
                        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
                        0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
                        0xC7,0xFC,0xE9,0xE2,0xE4,0xE0,0xE5,0xE7,
                        0xEA,0xEB,0xE8,0xEF,0xEE,0xEC,0xC4,0xC5,
                        0xC9,0xE6,0xC6,0xF4,0xF6,0xF2,0xFB,0xF9,
                        0xFF,0xD6,0xDC,0xA2,0xA3,0xA5,0x20,0x66,
                        0xE1,0xED,0xF3,0xFA,0xF1,0xD1,0xAA,0xBA,
                        0xBF,0x20,0xAC,0xBD,0xBC,0xA1,0xAB,0xBB,
                        0x20,0x7F,0x20,0xA6,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0xDF,0x20,0x20,0x20,0x20,0xB5,0x20,
                        0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
                        0x20,0xB1,0x20,0x20,0x20,0x20,0xF7,0x20,
                        0xB0,0xB7,0xB7,0x20,0x6E,0xB2,0x20,0x20};





ULONG _New(struct IClass *cl, Object *obj,struct opSet *msg);
ULONG _Dispose(struct IClass *cl, Object *obj, Msg msg);
ULONG _Set(struct IClass *cl,Object *obj,Msg msg);
ULONG _AskMinMax(struct IClass *cl,Object *obj,struct MUIP_AskMinMax *msg);
ULONG _Draw(struct IClass *cl,Object *obj, struct MUIP_Draw *msg);
ULONG _HandleEvent(struct IClass *cl,Object *obj, struct MUIP_HandleInput *msg);


void MouseToCursor(struct Class_Data *data,
                            unsigned long MouseX,unsigned long MouseY,
                              signed long *CursorX,signed long *CursorY);


unsigned int WrapEditor(struct Class_Data *data,unsigned long WrapLine,
                        unsigned long WrapColumn);

unsigned int BackwrapEditor(struct Class_Data *data,struct EditorBuffer *edbuf);


static void DragMark_RefreshSub(struct Class_Data *data,struct EditorBuffer *edbuf,
                                signed long x1,signed long y1,
                                signed long x2,signed long y2);


void MouseToCursor(struct Class_Data *data,
                            unsigned long MouseX,unsigned long MouseY,
                              signed long *CursorX,signed long *CursorY)
{
 unsigned long relx,rely,gfxline,clickline,clickcolumn;
 struct LineInfo linf;
 struct EditorBuffer *edbuf;

 clickcolumn=0;

 *CursorX=-1;
 *CursorY=-1;
 if (data->ValidDisplay==FALSE) return;
 if ( (MouseX<data->GfxLeft) ||
      (MouseX>data->GfxRight) ||
      (MouseY<data->GfxTop) ||
      (MouseY>data->GfxBottom) ) return;
 relx=MouseX-data->GfxLeft;
 rely=MouseY-data->GfxTop;
 gfxline=rely/data->FontYSize;
 edbuf=data->Buffers[data->DisplayPage];
 relx+=edbuf->HeadColumn;
 clickline=edbuf->HeadLine+gfxline;
 if ((clickline+1)>edbuf->BufferLineCache)
  {
   if (edbuf->BufferLineCache==0) return;
   clickline=edbuf->BufferLineCache-1;
   clickcolumn=8100;
  }

 if ( (GetLineInfo(data,&linf,clickline))==FALSE) return;
 
 if (clickcolumn==8100)
  {
   if (linf.CharLen!=0)
    {
     clickcolumn=linf.CharLen-1;
    }
    else
    {
     clickcolumn=0;
    }
  }
  else
  {
   clickcolumn=OffsetToColumnMouse(data,&linf,relx);
  }
 *CursorX=clickcolumn;
 *CursorY=clickline; 
}


void ClearMark(struct Class_Data *data)
{
 struct EditorBuffer *edbuf;
 edbuf=data->Buffers[data->DisplayPage];
 if (edbuf->MarkStartColumn==-1) return;

 if (data->ValidDisplay!=FALSE) 
  {
   if (data->Refresh==0) data->Refresh=1;
   DragMark_RefreshSub(data,edbuf,edbuf->MarkStartColumn,edbuf->MarkStartLine,
                     edbuf->MarkStopColumn,edbuf->MarkStopLine);
  }
 edbuf->MarkStartColumn=-1;
 edbuf->MarkStartLine=-1;
 edbuf->MarkStopColumn=-1;
 edbuf->MarkStopLine=-1;



}

void StopMark(struct Class_Data *data)
{
 if (data->AuxEventActive!=FALSE)
   {
    DoMethod(_win(data->RootObject),MUIM_Window_RemEventHandler,
             &data->AuxEventHandler);
    data->AuxEventActive=FALSE;
    }
 data->MarkStartX=-1;
 data->MarkStartY=-1;
}

void SetMark(struct Class_Data *data,unsigned long markx,
             unsigned long marky)
{
 if (data->AuxEventActive==FALSE)
   {
    DoMethod(_win(data->RootObject),MUIM_Window_AddEventHandler,
             &data->AuxEventHandler);
    data->AuxEventActive=TRUE;
    }
 data->MarkStartX=markx;
 data->MarkStartY=marky;
 data->MarkTicks=0;
}

void DragMark(struct Class_Data *data,unsigned long markx,
             unsigned long marky)
{
 signed long x1,x2,y1,y2;
 struct EditorBuffer *edbuf;


 edbuf=data->Buffers[data->DisplayPage]; 

 x1=edbuf->MarkStartColumn;
 x2=edbuf->MarkStopColumn;
 y1=edbuf->MarkStartLine;
 y2=edbuf->MarkStopLine;
 
 if ( (data->MarkStartX==markx) && (data->MarkStartY==marky) ) return;

 if ( (data->MarkStartY<marky) || 
      (
       (data->MarkStartY==marky) && (data->MarkStartX<markx)   
      ) )
  {
   edbuf->MarkStartColumn=data->MarkStartX;
   edbuf->MarkStartLine=data->MarkStartY;
   edbuf->MarkStopColumn=markx;
   edbuf->MarkStopLine=marky;   
  }
  else
  {
   edbuf->MarkStopColumn=data->MarkStartX;
   edbuf->MarkStopLine=data->MarkStartY;
   edbuf->MarkStartColumn=markx;
   edbuf->MarkStartLine=marky;
  }
 if (data->Refresh==0) data->Refresh=1;

 if (x1==-1)
  {
   DragMark_RefreshSub(data,edbuf,
                       edbuf->MarkStartColumn,edbuf->MarkStartLine,
                       edbuf->MarkStopColumn,edbuf->MarkStopLine);
  }
  else
  {
   if ( (edbuf->MarkStartLine<y1) ||  (
        (edbuf->MarkStartLine==y1) && (edbuf->MarkStartColumn<x1) ) )
    {
     DragMark_RefreshSub(data,edbuf,edbuf->MarkStartColumn,edbuf->MarkStartLine,
                         x1,y1);
    }
   if ( (edbuf->MarkStartLine>y1) ||  (
        (edbuf->MarkStartLine==y1) && (edbuf->MarkStartColumn>x1) ) )
    {
     DragMark_RefreshSub(data,edbuf,x1,y1,
                         edbuf->MarkStartColumn,edbuf->MarkStartLine);
    }

   if ( (edbuf->MarkStopLine<y2) ||  (
        (edbuf->MarkStopLine==y2) && (edbuf->MarkStopColumn<x2) ) )
    {
     DragMark_RefreshSub(data,edbuf,edbuf->MarkStopColumn,edbuf->MarkStopLine,
                         x2,y2);
    }
   if ( (edbuf->MarkStopLine>y2) ||  (
        (edbuf->MarkStopLine==y2) && (edbuf->MarkStopColumn>x2) ) )
    {
     DragMark_RefreshSub(data,edbuf,x2,y2,
                         edbuf->MarkStopColumn,edbuf->MarkStopLine);
    }
  }
}

static void DragMark_RefreshSub(struct Class_Data *data,struct EditorBuffer *edbuf,
                                signed long x1,signed long y1,
                                signed long x2,signed long y2)
{ 
 signed long i;
 signed long rl,rlo,rc;
 signed long ml;
 if (data->ValidDisplay==FALSE) return;
 ml=data->GfxLines;
 rlo=edbuf->HeadLine;
 for (i=y1;i<=y2;++i)
  {
   rl=i-rlo;
   if ( (rl<0) || (rl>=ml) ) continue;
   if ( i==y1) 
    {
     rc=x1;
    }
    else
    {
     rc=0;
    }
   if ( (data->RefreshLine[rl]==-1) || 
        (data->RefreshLine[rl]>rc) ) data->RefreshLine[rl]=rc;
  }
}

ULONG _HandleEvent(struct IClass *cl,Object *obj, struct MUIP_HandleInput *msg)
{
        struct Class_Data *data = INST_DATA(cl, obj);

        struct IntuiMessage *imsg;

        unsigned int eatme=FALSE;
        
        Object *mywin;
        Object *storage;

        mywin=_win(obj);
        get(mywin,MUIA_Window_ActiveObject,&storage);
        if ( (storage!=NULL) && (storage!=obj) )
         {
          return(0);
         }
        mywin=_win(obj);
        get(mywin,MUIA_Window_DefaultObject,&storage);
        if ( (storage!=NULL) && (storage!=obj) )
         {
          return(0);
         }


        imsg=msg->imsg;
        if (imsg!=NULL)
         {
          if (imsg->Class & IDCMP_INACTIVEWINDOW)
           {
            if (data->AltAsciiStatus!=-1)
             {
              data->AltAsciiStatus=-1;
              SetAttrs(obj,MUIA_Editor_AltAsciiMode,FALSE,TAG_DONE);
             }
            if (data->MarkStartX!=-1) StopMark(data);           
           }

          if (imsg->Class & IDCMP_INTUITICKS) while (1)
           {
            struct EditorBuffer *edbuf;
            signed long dx,dy,ox,oy,og;
            if (data->ValidDisplay==FALSE) break;
            edbuf=data->Buffers[data->DisplayPage];

            dx=imsg->MouseX;
            dx-=data->GfxLeft;
            dy=imsg->MouseY;
            dy-=data->GfxTop;
            ox=0;oy=0;
            if (dx<0) {ox=0-dx;} else
             {if (dx>data->GfxWidth) ox=dx-data->GfxWidth;}
            if (dy<0) {oy=0-dy;} else
             {if (dy>data->GfxHeight) oy=dy-data->GfxHeight;}
            og=ox+oy;
            og=  (og+(data->FontYSize/2)) / data->FontYSize;

            data->MarkTicks+=og;
            if (data->MarkTicks<4) break;
            data->MarkTicks=0;
            if (dy<0)
             {
              if (edbuf->HeadLine>0)
               {
                edbuf->HeadLine--;
                ScrollEditor(data,1);
                break;
               }
             }
             else
             {
              if (dy>=data->GfxHeight)
               {
                if (edbuf->HeadLine+data->GfxLines<edbuf->BufferLineCache)
                 {
                  edbuf->HeadLine++;
                  ScrollEditor(data,-1);
                  break;
                 }
               }
             }

            if ( (dx<0) )
             {
              if (edbuf->HeadColumn!=0)
               {
                if (edbuf->HeadColumn<(data->GfxWidth/20))
                 {
                  edbuf->HeadColumn=0;
                 }
                 else
                 {
                  edbuf->HeadColumn-=(data->GfxWidth/20);
                 }
                CompleteRefresh(data);
               }
             }
             else
             {
              if (dx>=data->GfxWidth)
               {
                edbuf->HeadColumn+=(data->GfxWidth/20);
                CompleteRefresh(data);
               }
             }

            break;
           }

          if (imsg->Class & IDCMP_MOUSEMOVE) while (1)
           {
            signed long cx,cy;
            if (data->ValidDisplay==FALSE) break;
            if ( (imsg->MouseY<data->GfxTop) ||
                 (imsg->MouseX<data->GfxLeft) ||
                 (imsg->MouseY>data->GfxBottom) ||
                 (imsg->MouseX>data->GfxRight) ) break;
            MouseToCursor(data,imsg->MouseX,imsg->MouseY,&cx,&cy);
            if (cx!=-1) DragMark(data,cx,cy);
            break;
           }

          if (imsg->Class & IDCMP_MOUSEBUTTONS) while (1)
           {
            if (data->Markable==FALSE) break;
            if  (
                 (imsg->Code != IECODE_LBUTTON) &&
                 (imsg->Code != IECODE_LBUTTON+0x80) ) break;
            
            if (imsg->Code==IECODE_LBUTTON)
             {
              signed long cx,cy;
              if (data->ValidDisplay==FALSE) break;
              if ( (imsg->MouseY<data->GfxTop) ||
                   (imsg->MouseX<data->GfxLeft) ||
                   (imsg->MouseY>data->GfxBottom) ||
                   (imsg->MouseX>data->GfxRight) ) break;
              ClearMark(data);
              MouseToCursor(data,imsg->MouseX,imsg->MouseY,&cx,&cy);
              if (cx!=-1) SetMark(data,cx,cy);           
             }
             else
             {
              if (imsg->Code==(IECODE_LBUTTON+0x80))
               {
                if (data->MarkStartX==-1) break;
                StopMark(data);
               }
             }
            break;
           }
          if (imsg->Class & IDCMP_RAWKEY) while (1)
           {
            struct InputEvent iev;
            struct EditorBuffer *edbuf; 
            unsigned long keykey=0,keyqua=0;
            unsigned short makealt=FALSE;
            signed long keysize;
            signed long i;
            signed long disp,redis=-1;

            edbuf=data->Buffers[data->DisplayPage];


            /* Key analysis */

            if ( (imsg->Qualifier&IEQUALIFIER_LSHIFT) || 
                 (imsg->Qualifier&IEQUALIFIER_RSHIFT) ||
                 (imsg->Qualifier&IEQUALIFIER_CAPSLOCK) )               
                keyqua|=1;

            if (imsg->Qualifier&IEQUALIFIER_CONTROL)   
                keyqua|=2;
            
            if ( (imsg->Qualifier&IEQUALIFIER_LALT) ||
                 (imsg->Qualifier&IEQUALIFIER_RALT) )
                keyqua|=4;

            if ( (imsg->Qualifier&IEQUALIFIER_LCOMMAND) ||
                 (imsg->Qualifier&IEQUALIFIER_RCOMMAND) )
                keyqua|=8;
 
            if (imsg->Qualifier&IEQUALIFIER_NUMERICPAD)
                keyqua|=16;

            if (data->NotifyPrPa!=FALSE) 
             {
              if ( (imsg->Code==0x42) &&
                   (imsg->Qualifier&IEQUALIFIER_LCOMMAND) )
               {
                SetAttrs(obj,MUIA_Editor_NotifyPrPa,1,TAG_DONE);
                eatme=TRUE;
                break;
               }
              if ( (imsg->Code==0x37) && (keyqua==4) )
               {
                SetAttrs(obj,MUIA_Editor_NotifyPrPa,2,TAG_DONE);
                eatme=TRUE;
                break;
               }
             }
            
              
            if ( (imsg->Code>=0x4c) && (imsg->Code<=0x4f) )
             {
              keykey=imsg->Code-0x4b;
             }
          
            if (imsg->Code==0x5f) break;
      
            if (imsg->Code==0x41) keykey=5;
            if (imsg->Code==0x46) keykey=6;
          

            if ( (imsg->Code>=0x50) && (imsg->Code<=0x59) )
             {
              keykey=imsg->Code-0x46;
              /* 10=F1 11=F2 ... */
             }

              /*  1= CsrUp   2=CsrDwn   3=CsrRight   4=CsrLeft */
              /*  5= Backsp  6=Del                             */
              /* 10= F1     11=F2       ...                    */
    
            /* Alt ascii handling*/

            if ( ( imsg->Code==0x64 ) && (data->AltAscii!=FALSE) )
             {
              data->AltAsciiStatus=345;
              SetAttrs(obj,MUIA_Editor_AltAsciiMode,TRUE,TAG_DONE);
              eatme=TRUE;
              break;
             }           

            if ( ( imsg->Code==0xe4) && (data->AltAsciiStatus!=-1) )
             {
              if (data->AltAsciiStatus>255)
               {
                data->AltAsciiStatus=-1;
                SetAttrs(obj,MUIA_Editor_AltAsciiMode,FALSE,TAG_DONE);
                eatme=TRUE;
                break;                 
               }
              makealt=TRUE;              
             }  

            if ( (imsg->Code==0x34) && (imsg->Qualifier&IEQUALIFIER_RCOMMAND)
                 && (data->Markable!=FALSE) && (data->Type==0) )
             {
              ClipboardPaste(data);
              eatme=TRUE;
              break;
             }
            
            if ( (imsg->Code==0x33) && (imsg->Qualifier&IEQUALIFIER_RCOMMAND)
                 && (data->Markable!=FALSE) && (edbuf->MarkStartColumn!=-1) )
             {
              ClipboardCopy(data);
              eatme=TRUE;
              break;
             }
            /* Non-Num lock cursor handling */

            if ( ( data->InputMask & MUIV_Editor_InputMask_NumericPad) &&
                 ( keyqua == 16) && (data->AltAsciiStatus==-1 ) )
             {
              if ( (data->NumLockStatus==FALSE ) || 
                   ( imsg->Code==0x5a) )
               {
                switch (imsg->Code)
                 {
                  case 0x5a:        /* Num lock key */
                    if (data->NumLock!=FALSE)
                     {
                      SetAttrs(obj,MUIA_Editor_NumLockStatus,!data->NumLockStatus,
                               TAG_DONE);
                      eatme=TRUE;                      
                     }
                    break;
                  case 0x3d:        /* Home key */
                    keykey=1;
                    keyqua=4;
                    break;
                  case 0x3e:        /* Up key */
                    keykey=1; 
                    keyqua=0; 
                    break;
                  case 0x3f:        /* PgUp key */
                    keykey=1;
                    keyqua=1;
                    break;
                  case 0x2d:        /* Left Key */
                    keykey=4;
                    keyqua=0;
                    break;
                   case 0x2f:       /* Right key */
                    keykey=3;
                    keyqua=0;
                    break;
                   case 0x1d:       /* End key */
                    keykey=2;
                    keyqua=4;
                    break;
                   case 0x1e:       /* Down key */
                    keykey=2;
                    keyqua=0;
                    break;
                   case 0x1f:       /* Pgdown key */
                    keykey=2; 
                    keyqua=1;
                    break;
                   case 0x0f:       /* Insert mode */
                    SetAttrs(obj,MUIA_Editor_InsertMode,!data->InsertMode,
                             TAG_DONE);
                    eatme=TRUE;       
                    break;     
                   case 0x3c:       /* Del */
                    keykey=6;
                    keyqua=0;
                    break;                                                    
                 } 
                 
                if (eatme==TRUE) break;
               }
             }
           
            /* Key filter handling */

            {
             unsigned short filterme=TRUE;
             switch (keykey)
              {
               case 0:
               case 5:
               case 6:
                 if (data->Type==0) filterme=FALSE;
                 break;
               
               case 1:
               case 2:
               case 3:
               case 4:
                 if ( (keyqua==0) && 
                      (data->InputMask & MUIV_Editor_InputMask_Cursor) )
                    filterme=FALSE;
                 if ( (keyqua==1) &&
                      (data->InputMask & MUIV_Editor_InputMask_CursorPage) )
                    filterme=FALSE;
                 if ( (keyqua==4) &&
                      (data->InputMask & MUIV_Editor_InputMask_CursorLimit ) )
                    filterme=FALSE;
                 break;
               default:
                 if ( (keyqua==0) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeys) )
                    filterme=FALSE;
                 if ( (keyqua==1) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysShift) )
                    filterme=FALSE;
                 if ( (keyqua==2) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysCtrl) )
                    filterme=FALSE;
                 if ( (keyqua==4) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysAlt) )
                    filterme=FALSE;
                 if ( (keyqua==8) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysAmiga) )
                    filterme=FALSE;
                 if ( data->Type!=0) break;
                 if ( (keyqua==6) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysFColor) )
                    filterme=FALSE;
                 if ( (keyqua==3) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysBColor) )
                    filterme=FALSE;
                 if ( (keyqua==10) &&
                      (data->InputMask & MUIV_Editor_InputMask_FKeysStyle) )
                    filterme=FALSE;
                 break;

              }
             if (filterme) break;
            }

            if ( (edbuf->InputLine==-1) && (data->Interactive!=FALSE) &&
                 (keykey<10) )
             {
              edbuf->InputLine=edbuf->CursorLine;
              edbuf->InputColumn=edbuf->CursorColumn;
             }
 

            /* Cursor up / Cursor down handling */

            if ( (keykey==1) || (keykey==2) )
             {
              unsigned long MaxLine,MinLine,MinColumn;
              unsigned long PageLines;

              keyqua&=0xf;

              if ( (keyqua!=0) && (keyqua!=1) && (keyqua!=4) ) break;
            
              eatme=TRUE;

              MaxLine= (65536*16384);
              MinLine= 0;
              MinColumn=0;
              if ( (data->Interactive==TRUE) && (edbuf->InputLine!=-1) )
               {
                MinLine=edbuf->InputLine;
                MinColumn=edbuf->InputLine;
               }
              if (data->FreeMoving==FALSE)
               {
                if (edbuf->BufferLineCache!=0)
                 {
                  MaxLine=edbuf->BufferLineCache-1;
                 }
                 else
                 {
                  MaxLine=0;
                 }
               }

              if (data->ValidDisplay==FALSE)
               {
                break;
               }

              PageLines=data->GfxLines;

              if (keykey==2)
               {
                
                switch (keyqua)
                 {
                  case 0:
                    {
        
                     if ( (data->Type!=0) && 
                          (edbuf->HeadLine+PageLines < MaxLine) )
                      {
                       edbuf->HeadLine++;
                       ScrollEditor(data,-1);
                       break;
                      }

                     /* Handling of EDTYPE 0 down free/locked */

                     if ( (data->Type==0) && 
                          (edbuf->CursorLine+1) <= MaxLine )
                      {
                       edbuf->CursorLine++;
                       redis=-2;
                       if (CacheClear(data)==FALSE)
                        {
                         DisplayBeep(NULL);
                        }                       
                      }
                     break;
                    }
                  case 1:
                    {
                     if (data->Type!=0) 
                      {
                       if (edbuf->HeadLine+2*PageLines <=MaxLine)
                        {
                         edbuf->HeadLine+=PageLines;
                        } 
                        else
                        {
                         if (MaxLine<PageLines)
                          {
                           edbuf->HeadLine=0;
                          }
                          else
                          {
                           edbuf->HeadLine=MaxLine-PageLines+1;
                          }
                        }
                       CompleteRefresh(data);
                       break;
                      }
                     /* Handling of EDTYPE 0 down free/locked */
                     if (data->Type==0)
                      {
                       if ( (edbuf->CursorLine+PageLines) <= MaxLine) 
                        {
                         edbuf->CursorLine+=PageLines;                         
                        }
                        else
                        {
                         edbuf->CursorLine=MaxLine;
                        }
                       redis=-2;
                       if (CacheClear(data)==FALSE)
                        {
                         DisplayBeep(NULL);
                        }                       
                       
                      }

                     break;
                    }
                  case 4:
                    {
                     if (data->Type!=0)
                      {
                       if (MaxLine<PageLines)
                        {
                         edbuf->HeadLine=0;
                        }
                        else
                        {
                         edbuf->HeadLine=MaxLine-PageLines+1;
                        }
                       CompleteRefresh(data);
                       break;
                      }
                    
                     /* Handling of EDTYPE 0 down free/locked */

                     if (data->Type==0)
                      {
                       if (edbuf->BufferLineCache==0) break;
                       edbuf->CursorLine=edbuf->BufferLineCache-1;
                       redis=-2;
                       if (CacheClear(data)==FALSE)
                        {
                         DisplayBeep(NULL);
                        }                       

                      }
                     break;
                    }
                 }                
               }
              
              if (keykey==1) 
               {
                if (edbuf->CursorLine==MinLine) break;
                switch (keyqua)
                 {
                  case 0:
                    {
                     if (data->Type==0)
                      {
                       edbuf->CursorLine--;
                       redis=-2;
                       if (CacheClear(data)==FALSE)
                        {
                         DisplayBeep(NULL);
                        }
                       break;
                      }
                      else
                      {
                       if (edbuf->HeadLine==MinLine) break;
                       ScrollEditor(data,1);
                       edbuf->HeadLine--;
                       break;
                      } 
                    }
                  case 1:
                    {
                     if (data->Type==0)
                      {
                       if (edbuf->CursorLine >= (MinLine+PageLines))
                        {
                         edbuf->CursorLine-=PageLines;               
                        }
                        else
                        {
                         edbuf->CursorLine=MinLine;
                        }
                       redis=-2;
                       if (CacheClear(data)==FALSE)
                        {
                         DisplayBeep(NULL);
                        }
                       break;
                      }
                      else
                      {
                       if (edbuf->HeadLine >= (MinLine+PageLines))
                        {
                         edbuf->HeadLine-=PageLines;               
                        }
                        else
                        {
                         edbuf->HeadLine=MinLine;
                        }
                       CompleteRefresh(data); 
                       break;
                      }
                    }
                  case 4:
                    {
                     if (data->Type==0)
                      {
                       edbuf->CursorLine=MinLine;
                       redis=-2;
                       if (CacheClear(data)==FALSE)
                        {
                         DisplayBeep(NULL);
                        }
                       break;
                      }
                      else
                      {
                       edbuf->HeadLine=0;
                       CompleteRefresh(data);
                       break;
                      }
                    }
                 }

                if (edbuf->CursorLine<MinLine)
                 {
                  edbuf->InputLine=-1;
                  edbuf->InputColumn=-1;
                 }
                if ( (edbuf->CursorLine==MinLine)
                    && (edbuf->CursorColumn<MinColumn) )
                 {
                  edbuf->CursorColumn=MinColumn;
                 }
               
               }                            

              /* Check for overcursor*/
              {
               struct LineInfo linf;
               if  ( GetLineInfo(data,&linf,edbuf->CursorLine) ==FALSE)
                  {
                   edbuf->CursorColumn=0;
                  }
                  else
                  {
                   if (edbuf->CursorColumn>linf.CharLen)
                    {
                     edbuf->CursorColumn=linf.CharLen;
                    }
                  }
              }
             
             }


            /* Cursor left / Cursor right handling for EDTYPE=0*/

            if ( (data->Type==0) && ( (keykey==3) || (keykey==4 ) ) )
             {
              unsigned long MinColumn;
              keyqua&=0xf;
              if ( (keyqua!=0) && (keyqua!=1) && (keyqua!=4) ) break;
            
              eatme=TRUE;

              if (CacheSet(data,edbuf->CursorLine)==FALSE)
               {
                DisplayBeep(NULL);
                break;
               }
             
              MinColumn=0; 

              if ( (data->Interactive!=FALSE) &&
                   (edbuf->CursorLine==edbuf->InputLine) )
               {
                MinColumn=edbuf->InputColumn;
               }

              if (keykey==3)
               {
                if (edbuf->CursorColumn==data->CachedTextLen) break;
                switch (keyqua)
                 {
                  case 0:
                    {
                     edbuf->CursorColumn++;
                     redis=-2;
                     break;
                    }
                  case 1:
                    {
                     while ( ( (edbuf->CursorColumn+1) < data->CachedTextLen ) &&
                             data->CachedChar[edbuf->CursorColumn]!=' ' )
                      {
                       edbuf->CursorColumn++;
                      }
                     edbuf->CursorColumn++;
                     redis=-2;
                     break;
                    }
                  case 4:
                    {
                     edbuf->CursorColumn=data->CachedTextLen;
                     redis=-2;
                     break;
                    }
                 }                
               }
              
              if (keykey==4) 
               {
                if (edbuf->CursorColumn==MinColumn) break;
                switch (keyqua)
                 {
                  case 0:
                    edbuf->CursorColumn--;
                    redis=-2;
                    break;
                  case 1:
                    edbuf->CursorColumn--;
                    while ( (edbuf->CursorColumn>MinColumn) && 
                            (data->CachedChar[edbuf->CursorColumn-1]!=' ' ) )
                     {
                      edbuf->CursorColumn--;
                     }
                    redis=-2;
                    break;
                  case 4:
                    edbuf->CursorColumn=MinColumn;
                    redis=-2;
                    break;
                 }
               }                            
             }

            /* Cursor left / Cursor right handling for EDTYPE!=0*/

            if ( (data->Type!=0) && ( (keykey==3) || (keykey==4 ) ) )
             {
              keyqua&=0xf;
              if ( (keyqua!=0) && (keyqua!=1) && (keyqua!=4) ) break;
            
              if (data->ValidDisplay==FALSE) break;

              eatme=TRUE;

             

              if (keykey==3)
               {
                switch (keyqua)
                 {
                  case 0:
                    {
                     edbuf->HeadColumn+=data->GfxWidth/2;
                     CompleteRefresh(data);
                     break;
                    }
                  case 1:
                    {
                     edbuf->HeadColumn+=data->GfxWidth/2;
                     CompleteRefresh(data);
                     break;
                    }
                  case 4:
                    {
                     break;
                    }
                 }                
               }
              
              if (keykey==4) 
               {
                if (edbuf->HeadColumn==0) break;
                switch (keyqua)
                 {
                  case 0:
                    if (edbuf->HeadColumn>(data->GfxWidth/20))
                     {
                      edbuf->HeadColumn-=(data->GfxWidth/20);                    
                     }
                     else
                     {
                      edbuf->HeadColumn=0;
                     }
                    CompleteRefresh(data);
                    break;
                  case 1:
                    if (edbuf->HeadColumn>(data->GfxWidth/2))
                     {
                      edbuf->HeadColumn-=(data->GfxWidth/2);                    
                     }
                     else
                     {
                      edbuf->HeadColumn=0;
                     }
                    CompleteRefresh(data);
                    break;
                  case 4:
                    edbuf->HeadColumn=0;
                    CompleteRefresh(data);
                    break;
                 }
               }                            
             }


            /* Function key handling */


            if (keykey>=10) 
             {
              unsigned long ForegroundColor;
              unsigned long BackgroundColor;
              unsigned long TextStyle;
              struct StyleInfo *mystyle;
              unsigned long AppendStyle;

              eatme=TRUE;
              if (CacheSet(data,edbuf->CursorLine)==FALSE)
               {
                DisplayBeep(NULL);
                break;
               }

              AppendStyle=0;
              mystyle=&data->CachedStyle[0];

              
              for (i=0;i<data->CachedStyleInfo;++i)
               {
                if (data->CachedStyle[i].StartColumn>edbuf->CursorColumn) break;
                mystyle=&data->CachedStyle[i];
                AppendStyle=i;                        
               }

              ForegroundColor=mystyle->ForegroundColor;
              BackgroundColor=mystyle->BackgroundColor;
              TextStyle=mystyle->TextStyle;

              if (keyqua==0)
               {
                unsigned long pkey;
                pkey=keykey-10+MUIV_Editor_NotifyFKey_StdBase;
                SetAttrs(obj,MUIA_Editor_NotifyFKey,pkey,TAG_DONE);
               }

              if (keyqua==1)
               {
                unsigned long pkey;
                pkey=keykey-10+MUIV_Editor_NotifyFKey_ShiftBase;
                SetAttrs(obj,MUIA_Editor_NotifyFKey,pkey,TAG_DONE);
               }
              if (keyqua==2)
               {        
                unsigned long pkey;
                pkey=keykey-10+MUIV_Editor_NotifyFKey_CtrlBase;
                SetAttrs(obj,MUIA_Editor_NotifyFKey,pkey,TAG_DONE);
               }
              if (keyqua==4)
               {
                unsigned long pkey;
                pkey=keykey-10+MUIV_Editor_NotifyFKey_AltBase;
                SetAttrs(obj,MUIA_Editor_NotifyFKey,pkey,TAG_DONE);
               }

              if (keyqua==8)
               {
                unsigned long pkey;
                pkey=keykey-10+MUIV_Editor_NotifyFKey_AmigaBase;
                SetAttrs(obj,MUIA_Editor_NotifyFKey,pkey,TAG_DONE);
               }


              if (keyqua==6)
               {
                if (keykey>=18) break;
                ForegroundColor=keykey-10;  
               }
              if (keyqua==3)
               {
                if (keykey>=18) break;
                BackgroundColor=keykey-10;      
               }
              if (keyqua==10)
               {
                if (keykey>=14) break;
                if (keykey==10) TextStyle=0;
                if (keykey==11) TextStyle^=1;
                if (keykey==12) TextStyle^=2;
                if (keykey==13) TextStyle^=4;
               }

              if ( (ForegroundColor==mystyle->ForegroundColor) &&
                   (BackgroundColor==mystyle->BackgroundColor) &&
                   (TextStyle==mystyle->TextStyle) ) break;

              if ( mystyle->StartColumn==edbuf->CursorColumn)
               {
                mystyle->ForegroundColor=ForegroundColor;
                mystyle->BackgroundColor=BackgroundColor;
                mystyle->TextStyle=TextStyle;
               }
               else
               {
                if (data->CachedStyleInfo==128) break;
                mystyle++;
                AppendStyle++;
                for (i=(data->CachedStyleInfo-1);i>=AppendStyle;--i)
                 {
                  data->CachedStyle[i+1]=data->CachedStyle[i];
                 }
                ++data->CachedStyleInfo;
                mystyle->ForegroundColor=ForegroundColor;
                mystyle->BackgroundColor=BackgroundColor;
                mystyle->TextStyle=TextStyle;
                mystyle->Pad1=0;
                mystyle->StartColumn=edbuf->CursorColumn;
               }
              redis=edbuf->CursorColumn;
             }

            /* Backspace /DEL handling */

            if ( (keykey==5) || (keykey==6) ) 
             {
              unsigned long remcol;
              unsigned long i;
              unsigned char *mems,*memd;

              eatme=TRUE;
              if (CacheSet(data,edbuf->CursorLine)==FALSE)
               {
                DisplayBeep(NULL);
                break;
               }
              
              if (keykey==5)
               {
                if (edbuf->CursorColumn==0)  
                 { 
                  if ( (edbuf->CursorLine==0) || 
                       (data->LineWrap==FALSE) ) break;
                  eatme=TRUE;
                  ClearMark(data);
                  BackwrapEditor(data,edbuf);
                  break;
                 }
                remcol=edbuf->CursorColumn-1;
               }
               else
               {
                if (edbuf->CursorColumn>=data->CachedTextLen) break;
                remcol=edbuf->CursorColumn;
               }

              if ( (edbuf->CursorLine==edbuf->InputLine) &&
                   (remcol<edbuf->InputColumn) )
               {
                if (data->Interactive!=FALSE)
                 {
                  break;
                 }
                 else
                 {
                  edbuf->InputColumn=remcol;
                 }
               }
              memd=&data->CachedChar[remcol];
              mems=memd+1;
              for (i=remcol+1;i<data->CachedTextLen;++i)
               {
                *(memd++)=*(mems++);
               }
              data->CachedTextLen--;
              redis=remcol; 

               {
                unsigned short movingsi=FALSE,hitsi=FALSE;
                for (i=0;i<data->CachedStyleInfo;++i)
                 {
                  if (movingsi!=FALSE)
                   {
                    data->CachedStyle[i]=data->CachedStyle[i+1];
                   }
                  if (data->CachedStyle[i].StartColumn==remcol)
                   {
                    hitsi=TRUE;
                   }
                  if (data->CachedStyle[i].StartColumn>remcol)
                   {
                    data->CachedStyle[i].StartColumn--;
                    if ( 
                        (data->CachedStyle[i].StartColumn==remcol) &&
                        (hitsi!=FALSE) )
                     {
                      i--;
                      i--;
                      data->CachedStyleInfo--;
                      movingsi=TRUE;             
                     }

                   }
                 }
               }
              if (keykey==5) edbuf->CursorColumn--;
             }





            /* Rawkey handling */

            if ( keykey==0 )
               {

                if (makealt==FALSE)
                 {
                  iev.ie_NextEvent=NULL;
                  iev.ie_Class=IECLASS_RAWKEY;
                  iev.ie_SubClass=0;
                  iev.ie_Code=imsg->Code;
                  iev.ie_Qualifier=imsg->Qualifier;
                  iev.ie_EventAddress=imsg->IAddress;
                  iev.ie_TimeStamp.tv_secs=imsg->Seconds;
                  iev.ie_TimeStamp.tv_micro=imsg->Micros;
                  keysize=MapRawKey(&iev,data->DisplayCache,80,0);
                  if ( (keysize==-1) || (keysize==0) ) break;
                  if ( (data->DisplayCache[0]==0x9b) || 
                       (data->DisplayCache[0]==0x09) ) break;
                 }
                 else
                 {
                  keysize=1;
                  data->DisplayCache[0]=data->AltAsciiStatus;
                  data->AltAsciiStatus=-1;
                  SetAttrs(obj,MUIA_Editor_AltAsciiMode,FALSE,TAG_DONE);             
                 }
                eatme=TRUE;

                ClearMark(data);


                if (data->AltAsciiStatus!=-1)
                 {
                  if ( ((keyqua&16) ==0) || 
                       (data->DisplayCache[0]<'0') ||
                       (data->DisplayCache[0]>'9') )
                   {
                    data->AltAsciiStatus=-1;
                    SetAttrs(obj,MUIA_Editor_AltAsciiMode,FALSE,TAG_DONE);
                    break;
                   }
                  if (data->AltAsciiStatus==345) data->AltAsciiStatus=0;
                  data->AltAsciiStatus*=10;
                  data->AltAsciiStatus+=data->DisplayCache[0]-'0';
                  if (data->AltAsciiStatus>255)
                   {
                    data->AltAsciiStatus=-1;
                    SetAttrs(obj,MUIA_Editor_AltAsciiMode,FALSE,TAG_DONE);
                   }
                  break;
                 }

                if ( (data->DisplayCache[0]==0x0d) &&
                     (makealt==FALSE) )
                 {
                  if (CacheClear(data)==FALSE)
                   {
                    DisplayBeep(NULL);
                    break;
                   }

                  if (data->LineWrap!=FALSE)
                   {
                    if 
                       (WrapEditor(data,edbuf->CursorLine,edbuf->CursorColumn)==FALSE)
                      {
                       break;
                      }
                   }


                  if ( ((edbuf->InputLine==-1) || (edbuf->CursorLine<edbuf->InputLine )) && (data->Interactive==FALSE) )
                   {
                    edbuf->InputLine=edbuf->CursorLine;
                    edbuf->InputColumn=0;
                   }

                  if (data->AskInputStream!=FALSE) 
                    Put_InputStream(data);
                  if (data->AskInputANSI!=FALSE)
                    Put_InputANSI(data);

                 
                  edbuf->CursorLine++;
                  edbuf->CursorColumn=0;
                  edbuf->InputLine=-1;
                  edbuf->InputColumn=-1;
                  Handle_Jobs(data);
                  redis=-2;                 
                 }

                 else

                 {
                  if (CacheSet(data,edbuf->CursorLine)==FALSE)
                   {
                    DisplayBeep(NULL);
                    break;
                   }



                  /* Inserting keystrokes */

                  if ( 
                       ( 
                        (data->CachedTextLen+keysize>4096) &&
                        (data->InsertMode!=FALSE) ) ||
                        (edbuf->CursorColumn+keysize>4096)                      
                     )
                   {
                    DisplayBeep(NULL);
                    break;
                   }       
             
                  if (edbuf->InputLine==-1)
                   {
                    edbuf->InputLine=edbuf->CursorLine;
                    if (data->Interactive!=FALSE)
                     {
                      edbuf->InputColumn=edbuf->CursorColumn;
                     }
                     else
                     {
                      edbuf->InputColumn=0;
                     }
                   }

                  /* Making insert mode insert step */
 

                  if (data->InsertMode!=FALSE)
                   {
                    for (i=0;i<data->CachedStyleInfo;++i)
                     {
                      if (data->CachedStyle[i].StartColumn>edbuf->CursorColumn)
                       {
                        data->CachedStyle[i].StartColumn+=keysize; 
                       }
                     }

                    for (i=(data->CachedTextLen-1);i>=(edbuf->CursorColumn);--i)
                     {
                      data->CachedChar[i+keysize]=data->CachedChar[i];
                     }
                   }

                  if ( (data->PCFontKey==FALSE) || (makealt==TRUE) )
                    {
                     for (i=0;i<keysize;++i)
                      {
                       data->CachedChar[edbuf->CursorColumn+i]=
                             data->DisplayCache[i];
                      } 
                    }
                    else
                    {
                     for (i=0;i<keysize;++i)
                      {
                       data->CachedChar[edbuf->CursorColumn+i]=
                             ConvertAmiga2PC[data->DisplayCache[i]];
                      } 
                    }
                  redis=edbuf->CursorColumn;
                  edbuf->CursorColumn+=keysize;
                  if (data->InsertMode==FALSE)
                   {
                    if (edbuf->CursorColumn>data->CachedTextLen) 
                     {
                      data->CachedTextLen=edbuf->CursorColumn;
                     }
                   }
                   else
                   {
                    data->CachedTextLen+=keysize;
                   }
                  if ( (data->WordWrap!=0) && 
                       (edbuf->CursorColumn>=data->WordWrap) )
                   {
                    unsigned wherewrap;

                    disp=edbuf->CursorLine-edbuf->HeadLine;
                    if ( (disp>=0) && (redis!=-1) &&( 
                      (disp<128) && (disp>=0) &&
                       ( (data->ValidDisplay==FALSE) || (disp<data->GfxLines) ) ) )
                     {
                      data->CursorFollow=TRUE;
                      if ( (data->RefreshLine[disp]==-1) ||
                             (data->RefreshLine[disp]>redis) )
                        {
                         data->RefreshLine[disp]=redis;
                        }              
                      if (data->Refresh==0) data->Refresh=1;
                     }

                    redis=-1;

                    wherewrap=data->WordWrap-1;
                    while ( (wherewrap!=0) && 
                            (data->CachedChar[wherewrap]!=' ') )
                     {
                      --wherewrap;
                     }
                    if (wherewrap!=0)
                     {
                      wherewrap++;
                      if 
                         (WrapEditor(data,edbuf->CursorLine,wherewrap)==FALSE)
                        {
                         break;
                        }
                      if (CacheSet(data,edbuf->CursorLine)==FALSE)
                       {
                        DisplayBeep(NULL);
                        break;
                       }
                      data->CachedTextLen--;
                      if (CacheClear(data)==FALSE)
                       {
                        DisplayBeep(NULL);
                        break;
                       }
                       {                                   
                        struct LineInfo linf;
                        if ( GetLineInfo(data,&linf,edbuf->CursorLine+1)==FALSE)
                         {
                          edbuf->CursorLine=edbuf->BufferLineCache-1;
                          CompleteRefresh(data);
                         }
                         else
                         {
                          edbuf->CursorLine++;
                          edbuf->CursorColumn=linf.CharLen;
                         }
 
                       }

                      

                       

                     }                        
                   }

                 }
               }

              
              
            /* Manage redisplaying */

            if (redis==-2)
             {
              data->CursorFollow=TRUE;
              if (data->Refresh==0) data->Refresh=1;
              redis=-1;
             }


            /* Look twice at Wordwrapping copied*/
            disp=edbuf->CursorLine-edbuf->HeadLine;
            if ( (disp>=0) && (redis!=-1) &&( 
               (disp<128) && (disp>=0) &&
                ( (data->ValidDisplay==FALSE) || (disp<data->GfxLines) ) ) )
             {
              data->CursorFollow=TRUE;
              if ( (data->RefreshLine[disp]==-1) ||
                     (data->RefreshLine[disp]>redis) )
                {
                 data->RefreshLine[disp]=redis;
                }              
              if (data->Refresh==0) data->Refresh=1;
             }

             {
              struct LineInfo linf;
              if ( GetLineInfo(data,&linf,edbuf->CursorLine)==FALSE)
               {
                edbuf->CursorLine=edbuf->BufferLineCache-1;
                CompleteRefresh(data);
               }

             }

            break;
           } 
         }
        if (data->Refresh!=0)
          {
           MUI_Redraw (obj,MADF_DRAWUPDATE);
          }
        
        return (eatme?MUI_EventHandlerRC_Eat:0);


}


