/*
 * RichEdit - Caret and selection functions.
 *
 * Copyright 2004 by Krzysztof Foltman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include "editor.h"

WINE_DEFAULT_DEBUG_CHANNEL(richedit);

void ME_GetSelection(ME_TextEditor *editor, int *from, int *to)
{
  *from = ME_GetCursorOfs(editor, 0);
  *to =   ME_GetCursorOfs(editor, 1);
  
  if (*from > *to)
  {
    int tmp = *from;
    *from = *to;
    *to = tmp;    
  }
}

int ME_GetTextLength(ME_TextEditor *editor)
{
  return ME_CharOfsFromRunOfs(editor, ME_FindItemBack(editor->pBuffer->pLast, diRun), 0);   
}

void ME_SetSelection(ME_TextEditor *editor, int from, int to)
{
  if (from == 0 && to == -1)
  {
    editor->pCursors[1].pRun = ME_FindItemFwd(editor->pBuffer->pFirst, diRun); 
    editor->pCursors[1].nOffset = 0; 
    editor->pCursors[0].pRun = ME_FindItemBack(editor->pBuffer->pLast, diRun); 
    editor->pCursors[0].nOffset = 0; 
    ME_Repaint(editor);
    ME_ClearTempStyle(editor);
    return;
  }
  if (from == -1)
  {
    editor->pCursors[1] = editor->pCursors[0]; 
    ME_Repaint(editor);
    ME_ClearTempStyle(editor);
    return;
  }
  if (from>to)
  {
    int tmp = from;
    from = to;
    to = tmp;
  }
  ME_RunOfsFromCharOfs(editor, from, &editor->pCursors[1].pRun, &editor->pCursors[1].nOffset);
  ME_RunOfsFromCharOfs(editor, to, &editor->pCursors[0].pRun, &editor->pCursors[0].nOffset);  
}

void ME_MoveCaret(ME_TextEditor *editor)
{
  HDC hDC = GetDC(editor->hWnd);
  ME_Context c;

  ME_Cursor *pCursor = &editor->pCursors[0];
  ME_DisplayItem *pCursorRun = pCursor->pRun;
  ME_DisplayItem *pSizeRun = pCursor->pRun;
  
  ME_InitContext(&c, editor, hDC);
  assert(!pCursor->nOffset || !editor->bCaretAtEnd);
  
  if (pCursorRun->type == diRun) {
    ME_DisplayItem *row = ME_FindItemBack(pCursorRun, diStartRowOrParagraph);
    if (row) {
      ME_DisplayItem *run = pCursorRun;
      ME_DisplayItem *para;
      SIZE sz = {0, 0};
      if (!pCursor->nOffset && !editor->bCaretAtEnd)
      {
        ME_DisplayItem *prev = ME_FindItemBack(pCursorRun, diRunOrStartRow);
        if (prev->type == diRun)
          pSizeRun = prev;
      }
      assert(row->type == diStartRow); /* paragraph -> run without start row ?*/
      para = ME_FindItemBack(row, diParagraph);
      if (editor->bCaretAtEnd && !pCursor->nOffset && 
          run == ME_FindItemFwd(row, diRun))
      {
        ME_DisplayItem *tmp = ME_FindItemBack(row, diRunOrParagraph);
        if (tmp->type == diRun)
        {
          row = ME_FindItemBack(tmp, diStartRow);
          pSizeRun = run = tmp;
          sz = ME_GetRunSize(&c, &run->member.run, ME_StrLen(run->member.run.strText));
        }
      }
      if (pCursor->nOffset && !(run->member.run.nFlags & MERF_SKIPPED)) {
        sz = ME_GetRunSize(&c, &run->member.run, pCursor->nOffset);
      }
      CreateCaret(editor->hWnd, NULL, 0, pSizeRun->member.run.nAscent+pSizeRun->member.run.nDescent);
      SetCaretPos(run->member.run.pt.x+sz.cx,
        para->member.para.nYPos+row->member.row.nBaseline+pSizeRun->member.run.pt.y-pSizeRun->member.run.nAscent-GetScrollPos(editor->hWnd, SB_VERT));
    } else {
      assert(0 == "Wrapped paragraph run without a row?");
      CreateCaret(editor->hWnd, NULL, 0, 10);
      SetCaretPos(0,0);
    }
  }  
  else {
    assert(0 == "Cursor not on a run");
    CreateCaret(editor->hWnd, NULL, 0, 10); /* FIXME use global font */
    SetCaretPos(0,0);
  }
  ME_DestroyContext(&c);
  ReleaseDC(editor->hWnd, hDC);
}

void ME_ShowCaret(ME_TextEditor *ed)
{
  ME_MoveCaret(ed);
  ShowCaret(ed->hWnd);
}

void ME_HideCaret(ME_TextEditor *ed)
{
  HideCaret(ed->hWnd);
  DestroyCaret();
}

void ME_InternalDeleteText(ME_TextEditor *editor, int nOfs, 
  int nChars)
{
  ME_Cursor c;
  int shift = 0;
  
  while(nChars > 0)
  {
    ME_Run *run;
    ME_CursorFromCharOfs(editor, nOfs, &c);
    run = &c.pRun->member.run;
    if (run->nFlags & MERF_ENDPARA) {
      if (!ME_FindItemFwd(c.pRun, diParagraph))
      {
        return;
      }
      ME_JoinParagraphs(editor, ME_GetParagraph(c.pRun));
      /* ME_SkipAndPropagateCharOffset(p->pRun, shift); */
      ME_CheckCharOffsets(editor);
      nChars--;
      continue;
    }
    else
    {
      ME_Cursor cursor;
      int nIntendedChars = nChars;
      int nCharsToDelete = nChars;
      int i;
      int loc = c.nOffset;
      
      ME_FindItemBack(c.pRun, diParagraph)->member.para.nFlags |= MEPF_REWRAP;
      
      cursor = c;
      ME_StrRelPos(run->strText, loc, &nChars);
      /* nChars is the number of characters that should be deleted from the
         FOLLOWING runs (these AFTER cursor.pRun)
         nCharsToDelete is a number of chars to delete from THIS run */
      nCharsToDelete -= nChars;
      shift -= nCharsToDelete;
      TRACE("Deleting %d (intended %d-remaning %d) chars at %d in '%s' (%d)\n", 
        nCharsToDelete, nIntendedChars, nChars, c.nOffset, 
        debugstr_w(run->strText->szData), run->strText->nLen);

      if (!c.nOffset && ME_StrVLen(run->strText) == nCharsToDelete)
      {
        /* undo = reinsert whole run */
        /* nOfs is a character offset (from the start of the document
           to the current (deleted) run */
        ME_UndoItem *pUndo = ME_AddUndoItem(editor, diUndoInsertRun, c.pRun);
        if (pUndo)
          pUndo->di.member.run.nCharOfs = nOfs;
      }
      else
      {
        /* undo = reinsert partial run */
        ME_UndoItem *pUndo = ME_AddUndoItem(editor, diUndoInsertRun, c.pRun);
        if (pUndo) {
          ME_DestroyString(pUndo->di.member.run.strText);
          pUndo->di.member.run.nCharOfs = nOfs;
          pUndo->di.member.run.strText = ME_MakeStringN(run->strText->szData+c.nOffset, nCharsToDelete);
        }
      }
      TRACE("Post deletion string: %s (%d)\n", debugstr_w(run->strText->szData), run->strText->nLen);
      TRACE("Shift value: %d\n", shift);
      ME_StrDeleteV(run->strText, c.nOffset, nCharsToDelete);
      
      /* update cursors (including c) */
      for (i=-1; i<editor->nCursors; i++) {
        ME_Cursor *pThisCur = editor->pCursors + i; 
        if (i == -1) pThisCur = &c;
        if (pThisCur->pRun == cursor.pRun) {
          if (pThisCur->nOffset > cursor.nOffset) {
            if (pThisCur->nOffset-cursor.nOffset < nCharsToDelete)
              pThisCur->nOffset = cursor.nOffset;
            else
              pThisCur->nOffset -= nCharsToDelete;
            assert(pThisCur->nOffset >= 0);
            assert(pThisCur->nOffset <= ME_StrVLen(run->strText));
          }
          if (pThisCur->nOffset == ME_StrVLen(run->strText))
          {
            pThisCur->pRun = ME_FindItemFwd(pThisCur->pRun, diRunOrParagraphOrEnd);
            assert(pThisCur->pRun->type == diRun);
            pThisCur->nOffset = 0;
          }
        }
      }
      
      /* c = updated data now */
      
      if (c.pRun == cursor.pRun)
        ME_SkipAndPropagateCharOffset(c.pRun, shift);
      else
        ME_PropagateCharOffset(c.pRun, shift);

      if (!ME_StrVLen(cursor.pRun->member.run.strText))
      {
        TRACE("Removing useless run\n");
        ME_Remove(cursor.pRun);
        ME_DestroyDisplayItem(cursor.pRun);
      }
      
      shift = 0;
      /*
      ME_CheckCharOffsets(editor);
      */
      continue;
    }
  }
}

void ME_DeleteTextAtCursor(ME_TextEditor *editor, int nCursor, 
  int nChars)
{  
  assert(nCursor>=0 && nCursor<editor->nCursors);
  ME_InternalDeleteText(editor, ME_GetCursorOfs(editor, nCursor), nChars);
}

static WCHAR wszSpace[] = {' ', 0};

/* FIXME this is temporary, just to have something to test how bad graphics handler is */
void ME_InsertGraphicsFromCursor(ME_TextEditor *editor, int nCursor)
{
  ME_Cursor *pCursor = &editor->pCursors[nCursor];
  ME_DisplayItem *pItem = NULL;
  ME_DisplayItem *pNewRun = NULL;
  ME_Style *pStyle = ME_GetInsertStyle(editor, nCursor);
  ME_UndoItem *pUndo;
  
  /* FIXME no no no */
  if (ME_IsSelection(editor))
    ME_DeleteSelection(editor);

  pUndo = ME_AddUndoItem(editor, diUndoDeleteRun, NULL);
  if (pUndo) {
    pUndo->nStart = pCursor->nOffset + pCursor->pRun->member.run.nCharOfs + ME_GetParagraph(pCursor->pRun)->member.para.nCharOfs;
    pUndo->nLen = 1;
  }
  if (pCursor->nOffset)
  {
    ME_SplitRunSimple(editor, pCursor->pRun, pCursor->nOffset);
  }
  pItem = pCursor->pRun;
  pNewRun = ME_MakeRun(pStyle, ME_MakeStringN(wszSpace, 1), MERF_GRAPHICS);
  pNewRun->member.run.nCharOfs = pCursor->pRun->member.run.nCharOfs;
  ME_InsertBefore(pCursor->pRun, pNewRun);
  ME_PropagateCharOffset(pItem, 1);
  ME_CheckCharOffsets(editor);
  ME_SendSelChange(editor);
}

void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, 
  const WCHAR *str, int len, ME_Style *style)
{
  const WCHAR *pos;
  ME_Cursor *p = NULL;

  assert(style);
  editor->bCaretAtEnd = FALSE;

  ME_AddRefStyle(style);
  
  /* FIXME really HERE ? */
  if (ME_IsSelection(editor))
    ME_DeleteSelection(editor);

  assert(nCursor>=0 && nCursor<editor->nCursors);
  if (len == -1)
    len = lstrlenW(str);
  pos = str;
  /* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
  while(pos-str < len && *pos != '\r' && *pos != '\n')
    pos++;
  /* handle EOLs */
  if (pos-str < len) {   
    ME_DisplayItem *tp, *end_run;
    ME_Paragraph *para;
    ME_Style *tmp_style;
    if (pos!=str)
      ME_InsertTextFromCursor(editor, nCursor, str, pos-str, style);
    p = &editor->pCursors[nCursor];
    tp = ME_FindItemBack(p->pRun, diParagraph);
    para = &tp->member.para;
    assert(tp);
    if (p->nOffset) {
      ME_SplitRunSimple(editor, p->pRun, p->nOffset);
      p = &editor->pCursors[nCursor];
    }
    tmp_style = ME_GetInsertStyle(editor, nCursor);
    /* ME_SplitParagraph increases style refcount */
    tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style);
    p->pRun = ME_FindItemFwd(tp, diRun);
    end_run = ME_FindItemBack(tp, diRun);
    ME_ReleaseStyle(end_run->member.run.style);
    end_run->member.run.style = tmp_style;
    p->nOffset = 0;
    if(pos-str < len && *pos =='\r')
      pos++;
    if(pos-str < len && *pos =='\n')
      pos++;
    if(pos-str < len) {
      ME_InsertTextFromCursor(editor, nCursor, pos, len-(pos-str), style);
    }
    ME_ReleaseStyle(style);
    return;
  }
  p = &editor->pCursors[nCursor];
  if (style) {
    ME_DisplayItem *pNewRun = NULL;

    assert(p->pRun->type == diRun);
    pNewRun = ME_MakeRun(style, ME_MakeStringN(str, len), 0); /* addrefs style */
    ME_InsertRun(editor, ME_CharOfsFromRunOfs(editor, p->pRun, p->nOffset), pNewRun);
    ME_DestroyDisplayItem(pNewRun);
    ME_ReleaseStyle(style);
    return;
  } else {
    assert(0);
  }
}

BOOL ME_ArrowLeft(ME_TextEditor *editor, ME_Cursor *p)
{
  if (p->nOffset) {
    p->nOffset = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, -1);
    return TRUE;
  }
  else
  {
    ME_DisplayItem *pRun = ME_FindItemBack(p->pRun, diRunOrParagraph);
    assert(pRun);
    if (pRun->type == diRun) {
      p->pRun = pRun;
      assert(p->pRun->type == diRun);
      assert(pRun->member.run.strText->nLen);
      p->nOffset = pRun->member.run.strText->nLen;
      if (p->nOffset) {
        p->nOffset = ME_StrRelPos2(pRun->member.run.strText, p->nOffset, -1);
        return TRUE;
      }
      else
        assert(0);
    }
    if (pRun->type == diParagraph)
    {
      if (pRun->member.para.prev_para->type == diTextStart)
        return FALSE;
      assert(pRun->member.para.prev_para->type == diParagraph);
      pRun = ME_FindItemBack(pRun, diRunOrParagraph);
      /* every paragraph ought to have at least one run */
      assert(pRun && pRun->type == diRun);
      assert(pRun->member.run.nFlags & MERF_ENDPARA);
      p->pRun = pRun;
      p->nOffset = 0;
      return TRUE;
    }
    assert(0);
  }
  return FALSE;
}

BOOL ME_ArrowRight(ME_TextEditor *editor, ME_Cursor *p)
{
  int new_ofs = ME_StrRelPos2(p->pRun->member.run.strText, p->nOffset, 1);
  if (new_ofs<p->pRun->member.run.strText->nLen) {
    p->nOffset = new_ofs;
  }
  else
  {
    ME_DisplayItem *pRun = ME_FindItemFwd(p->pRun, diRun);
    if (pRun) {
      p->pRun = pRun;
      assert(p->pRun->type == diRun);
      p->nOffset = 0;
    }
  }
  return TRUE;
}

int ME_GetCursorOfs(ME_TextEditor *editor, int nCursor)
{
  ME_Cursor *pCursor = &editor->pCursors[nCursor];
  
  return ME_GetParagraph(pCursor->pRun)->member.para.nCharOfs
    + pCursor->pRun->member.run.nCharOfs + pCursor->nOffset;
}

int ME_FindPixelPos(ME_TextEditor *editor, int x, int y, ME_Cursor *result, BOOL *is_eol)
{
  ME_DisplayItem *p = editor->pBuffer->pFirst->member.para.next_para;
  int rx = 0;
  
  if (is_eol)
    *is_eol = 0;

  while(p != editor->pBuffer->pLast)
  {
    if (p->type == diParagraph)
    {
      int ry = y - p->member.para.nYPos;
      if (ry < 0)
      {
        result->pRun = ME_FindItemFwd(p, diRun);
        result->nOffset = 0;
        return 0;
      }
      if (ry >= p->member.para.nHeight)
      {
        p = p->member.para.next_para;
        continue;
      }
      p = ME_FindItemFwd(p, diStartRow);
      y = ry;
      continue;
    }
    if (p->type == diStartRow)
    {
      int ry = y - p->member.row.nYPos;
      if (ry < 0)
        return 0;
      if (ry >= p->member.row.nHeight)
      {
        p = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd);
        if (p->type != diStartRow)
          return 0;
        continue;
      }
      p = ME_FindItemFwd(p, diRun);
      continue;
    }
    if (p->type == diRun)
    {
      ME_DisplayItem *pp;
      rx = x - p->member.run.pt.x;
      if (rx < 0)
        rx = 0;
      if (rx >= p->member.run.nWidth) /* not this run yet... find next item */
      {
        pp = p;
        do {
          p = p->next;
          if (p->type == diRun)
          {
            rx = x - p->member.run.pt.x;
            goto continue_search;
          }
          if (p->type == diStartRow)
          {
            p = ME_FindItemFwd(p, diRun);
            if (is_eol)
              *is_eol = 1;
            rx = 0; /* FIXME not sure */
            goto found_here;
          }
          if (p->type == diParagraph || p->type == diTextEnd)
          {
            rx = 0; /* FIXME not sure */
            p = pp;
            goto found_here;
          }
        } while(1);
        continue;
      }
    found_here:
      if (p->member.run.nFlags & MERF_ENDPARA)
        rx = 0;
      result->pRun = p;
      result->nOffset = ME_CharFromPointCursor(editor, rx, &p->member.run);
      if (editor->pCursors[0].nOffset == p->member.run.strText->nLen && rx)
      {
        result->pRun = ME_FindItemFwd(editor->pCursors[0].pRun, diRun);
        result->nOffset = 0;
      }
      return 1;
    }
    assert(0);
  continue_search:
    ;
  }
  result->pRun = ME_FindItemBack(p, diRun);
  result->nOffset = 0;
  assert(result->pRun->member.run.nFlags & MERF_ENDPARA);
  return 0;
}

void ME_LButtonDown(ME_TextEditor *editor, int x, int y)
{
  ME_Cursor tmp_cursor;
  int is_selection = 0;
  
  editor->nUDArrowX = -1;
  
  y += GetScrollPos(editor->hWnd, SB_VERT);  

  tmp_cursor = editor->pCursors[0];
  is_selection = ME_IsSelection(editor);

  ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd);
  
  if (GetKeyState(VK_SHIFT)>=0)
  {
    editor->pCursors[1] = editor->pCursors[0];
  }
  else
  {
    if (!is_selection) {
      editor->pCursors[1] = tmp_cursor;
      is_selection = 1;
    }
  }
  HideCaret(editor->hWnd);
  ME_MoveCaret(editor);
  if (is_selection)
    ME_Repaint(editor);
  ShowCaret(editor->hWnd);
  ME_ClearTempStyle(editor);
  ME_SendSelChange(editor);
}

void ME_MouseMove(ME_TextEditor *editor, int x, int y)
{
  ME_Cursor tmp_cursor;
  
  y += GetScrollPos(editor->hWnd, SB_VERT);  

  tmp_cursor = editor->pCursors[0];
  if (!ME_FindPixelPos(editor, x, y, &editor->pCursors[0], &editor->bCaretAtEnd))
    /* return */;
  
  if (tmp_cursor.pRun == editor->pCursors[0].pRun && 
      tmp_cursor.nOffset == editor->pCursors[0].nOffset)
    return;
  
  HideCaret(editor->hWnd);
  ME_MoveCaret(editor);
  ME_Repaint(editor);
  ShowCaret(editor->hWnd);
  ME_SendSelChange(editor);
}

static ME_DisplayItem *ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, 
                                int x, int *pOffset, int *pbCaretAtEnd)
{
  ME_DisplayItem *pNext, *pLastRun;
  pNext = ME_FindItemFwd(pRow, diRunOrStartRow);
  assert(pNext->type == diRun);
  pLastRun = pNext;
  *pbCaretAtEnd = FALSE;
  do {
    int run_x = pNext->member.run.pt.x;
    int width = pNext->member.run.nWidth;
    if (x < run_x)
    {
      if (pOffset) *pOffset = 0;
      return pNext;
    }
    if (x >= run_x && x < run_x+width)
    {
      int ch = ME_CharFromPointCursor(editor, x-run_x, &pNext->member.run);
      ME_String *s = pNext->member.run.strText;
      if (ch < s->nLen) {
        if (pOffset)
          *pOffset = ch;
        return pNext;          
      }
    }
    pLastRun = pNext;
    pNext = ME_FindItemFwd(pNext, diRunOrStartRow);
  } while(pNext && pNext->type == diRun);
  
  if ((pLastRun->member.run.nFlags & MERF_ENDPARA) == 0)
  {
    pNext = ME_FindItemFwd(pNext, diRun);
    if (pbCaretAtEnd) *pbCaretAtEnd = 1;
    if (pOffset) *pOffset = 0;
    return pNext;
  } else {
    if (pbCaretAtEnd) *pbCaretAtEnd = 0;
    if (pOffset) *pOffset = 0;
    return pLastRun;
  }
}

static int ME_GetXForArrow(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *pRun = pCursor->pRun;
  int x;

  if (editor->nUDArrowX != -1)
    x = editor->nUDArrowX;
  else {
    if (editor->bCaretAtEnd)
    {
      pRun = ME_FindItemBack(pRun, diRun);
      assert(pRun);
      x = pRun->member.run.pt.x + pRun->member.run.nWidth;
    }
    else {
      x = pRun->member.run.pt.x;
      x += ME_PointFromChar(editor, &pRun->member.run, pCursor->nOffset);
    }
    editor->nUDArrowX = x;
  }
  return x;
}

void ME_ArrowUp(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *pRun = pCursor->pRun;
  ME_DisplayItem *pItem, *pItem2;
  int x = ME_GetXForArrow(editor, pCursor);
  
  if (editor->bCaretAtEnd && !pCursor->nOffset)
  {
    pRun = ME_FindItemBack(pRun, diRun);
    if (!pRun)
      return;
  }
  
  /* start of this row */
  pItem = ME_FindItemBack(pRun, diStartRow);
  assert(pItem);
  /* start of the previous row */
  pItem2 = ME_FindItemBack(pItem, diStartRow);
  /* no previous row = the first line of the first paragraph */
  if (!pItem2) /* can't go up - don't go BOL (as in MS richedit) */
    return;
  /* FIXME
  ME_WrapTextParagraph(editor, ME_FindItemBack(pItem2, diParagraph));
  */
  pCursor->pRun = ME_FindRunInRow(editor, pItem2, x, &pCursor->nOffset, &editor->bCaretAtEnd);
}

void ME_ArrowDown(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *pRun = pCursor->pRun;
  ME_DisplayItem *pItem;
  int x = ME_GetXForArrow(editor, pCursor);
  if (!pCursor->nOffset && editor->bCaretAtEnd)
  {
    pRun = ME_FindItemBack(pRun, diRun);
/*    x = pRun->member.run.pt.x + pRun->member.run.nWidth; */
  }
  /* start of the next row */
  pItem = ME_FindItemFwd(pRun, diStartRow);
  /* FIXME If diParagraph is before diStartRow, wrap the next paragraph?
  */
  if (!pItem)
  {
    /* next row not found - ignore */
    return;
  }
  pCursor->pRun = ME_FindRunInRow(editor, pItem, x, &pCursor->nOffset, &editor->bCaretAtEnd);
  assert(pCursor->pRun);
  assert(pCursor->pRun->type == diRun);
}

void ME_ArrowHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diStartRow);
  if (pRow) {
    ME_DisplayItem *pRun;
    if (editor->bCaretAtEnd && !pCursor->nOffset) {
      pRow = ME_FindItemBack(pRow, diStartRow);
      if (!pRow)
        return;
    }
    pRun = ME_FindItemFwd(pRow, diRun);
    if (pRun) {
      pCursor->pRun = pRun;
      pCursor->nOffset = 0;
    }
  }
  editor->bCaretAtEnd = FALSE;
}

void ME_ArrowCtrlHome(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *pRow = ME_FindItemBack(pCursor->pRun, diTextStart);
  if (pRow) {
    ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun);
    if (pRun) {
      pCursor->pRun = pRun;
      pCursor->nOffset = 0;
    }
  }
}

void ME_ArrowEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *pRow;
  
  if (editor->bCaretAtEnd && !pCursor->nOffset)
    return;
  
  pRow = ME_FindItemFwd(pCursor->pRun, diStartRowOrParagraphOrEnd);
  assert(pRow);
  if (pRow->type == diStartRow) {
    /* FIXME WTF was I thinking about here ? */
    ME_DisplayItem *pRun = ME_FindItemFwd(pRow, diRun);
    assert(pRun);
    pCursor->pRun = pRun;
    pCursor->nOffset = 0;
    editor->bCaretAtEnd = 1;
    return;
  }
  pCursor->pRun = ME_FindItemBack(pRow, diRun);
  assert(pCursor->pRun && pCursor->pRun->member.run.nFlags & MERF_ENDPARA);
  pCursor->nOffset = 0;
  editor->bCaretAtEnd = FALSE;
}
      
void ME_ArrowCtrlEnd(ME_TextEditor *editor, ME_Cursor *pCursor)
{
  ME_DisplayItem *p = ME_FindItemFwd(pCursor->pRun, diTextEnd);
  assert(p);
  p = ME_FindItemBack(p, diRun);
  assert(p);
  assert(p->member.run.nFlags & MERF_ENDPARA);
  pCursor->pRun = p;
  pCursor->nOffset = 0;
  editor->bCaretAtEnd = FALSE;
}

BOOL ME_IsSelection(ME_TextEditor *editor)
{
  return memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor))!=0;
}

int ME_GetSelCursor(ME_TextEditor *editor, int dir)
{
  int cdir = ME_GetCursorOfs(editor, 0) - ME_GetCursorOfs(editor, 1);
  
  if (cdir*dir>0)
    return 0;
  else
    return 1;
}
      
BOOL ME_CancelSelection(ME_TextEditor *editor, int dir)
{
  int cdir;
  
  if (GetKeyState(VK_SHIFT)<0)
    return FALSE;
  if (!memcmp(&editor->pCursors[0], &editor->pCursors[1], sizeof(ME_Cursor)))
    return FALSE;
  
  cdir = ME_GetCursorOfs(editor, 0) - ME_GetCursorOfs(editor, 1);
  
  if (cdir*dir>0)
    editor->pCursors[1] = editor->pCursors[0];
  else
    editor->pCursors[0] = editor->pCursors[1];
  ME_Repaint(editor);
  return TRUE;
}

void ME_RepaintSelection(ME_TextEditor *editor, ME_Cursor *pTempCursor)
{
  ME_Cursor old_anchor = editor->pCursors[1];
  
  if (GetKeyState(VK_SHIFT)>=0) /* cancelling selection */
  {
    /* any selection was present ? if so, it's no more, repaint ! */
    editor->pCursors[1] = editor->pCursors[0];
    if (memcmp(pTempCursor, &old_anchor, sizeof(ME_Cursor))) {
      ME_Repaint(editor);
      return;
    }
    return;
  }
  else
  {
    if (!memcmp(pTempCursor, &editor->pCursors[1], sizeof(ME_Cursor))) /* starting selection */
    {
      editor->pCursors[1] = *pTempCursor;
    }
  }

  ME_Repaint(editor);
}

void ME_DeleteSelection(ME_TextEditor *editor)
{
  int from, to;
  ME_GetSelection(editor, &from, &to);
  ME_DeleteTextAtCursor(editor, ME_GetSelCursor(editor,-1), to-from);
}

ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor)
{
  ME_Style *style;
  int from, to;
  ME_Cursor c;
  
  ME_GetSelection(editor, &from, &to);
  ME_CursorFromCharOfs(editor, from, &c);
  if (from != to) {
    style = c.pRun->member.run.style;
    ME_AddRefStyle(style); /* ME_GetInsertStyle has already done that */
  }
  else
    style = ME_GetInsertStyle(editor, 0);
  return style;
}

void ME_SendSelChange(ME_TextEditor *editor)
{
  SELCHANGE sc;
  if (!(editor->nEventMask & ENM_SELCHANGE))
    return;
  sc.nmhdr.hwndFrom = editor->hWnd;
  sc.nmhdr.idFrom = GetWindowLongW(editor->hWnd, GWLP_ID);
  sc.nmhdr.code = EN_SELCHANGE;
  SendMessageW(editor->hWnd, EM_EXGETSEL, 0, (LPARAM)&sc.chrg);
  sc.seltyp = SEL_EMPTY;
  if (sc.chrg.cpMin != sc.chrg.cpMax)
    sc.seltyp |= SEL_TEXT;
  if (sc.chrg.cpMin < sc.chrg.cpMax+1) /* wth were RICHEDIT authors thinking ? */
    sc.seltyp |= SEL_MULTICHAR;
  SendMessageW(GetParent(editor->hWnd), WM_NOTIFY, sc.nmhdr.idFrom, (LPARAM)&sc);
}

BOOL ME_ArrowKey(ME_TextEditor *editor, int nVKey, int nCtrl)
{
  int nCursor = 0;
  ME_Cursor *p = &editor->pCursors[nCursor];
  ME_Cursor tmp_curs = *p;
  
  switch(nVKey) {
    case VK_UP:
      ME_ArrowUp(editor, p);
      ME_ClearTempStyle(editor);
      ME_RepaintSelection(editor, &tmp_curs);
      ME_SendSelChange(editor);
      return TRUE;
    case VK_DOWN:
      ME_ArrowDown(editor, p);
      ME_ClearTempStyle(editor);
      ME_RepaintSelection(editor, &tmp_curs);
      ME_SendSelChange(editor);
      return TRUE;
  }
  
  editor->nUDArrowX = -1;
  switch(nVKey) {
    case VK_BACK: { /* FIXME backspace and delete aren't the same, they act different wrt paragraph style of the merged paragraph */
      if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY)
        return FALSE;
      if (ME_IsSelection(editor))
      {
        editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */
        ME_DeleteSelection(editor);
        ME_UpdateRepaint(editor);
        return TRUE;
      }
      if (ME_ArrowLeft(editor, p)) {
        editor->bCaretAtEnd = FALSE; /* FIXME or maybe not */
        ME_ClearTempStyle(editor);
        ME_MoveCaret(editor);
        ME_DeleteTextAtCursor(editor, nCursor, 1);
        ME_UpdateRepaint(editor);
      }
      return TRUE;
    }
    case VK_DELETE: {
      if (GetWindowLongW(editor->hWnd, GWL_STYLE) & ES_READONLY)
        return FALSE;
      /* editor->bCaretAtEnd = 0; FIXME or maybe not */
      if (ME_IsSelection(editor))
      {
        ME_DeleteSelection(editor);
        ME_ClearTempStyle(editor);
        ME_UpdateRepaint(editor);
        return TRUE;
      }
      ME_DeleteTextAtCursor(editor, nCursor, 1);
      ME_ClearTempStyle(editor);
      ME_UpdateRepaint(editor);
      return TRUE;
    }
    case VK_HOME: {
      if (GetKeyState(VK_CONTROL)<0)
        ME_ArrowCtrlHome(editor, p);
      else
        ME_ArrowHome(editor, p);
      editor->bCaretAtEnd = 0;
      ME_ClearTempStyle(editor);
      ME_RepaintSelection(editor, &tmp_curs);
      ME_SendSelChange(editor);
      return TRUE;
    }
    case VK_END: 
      if (GetKeyState(VK_CONTROL)<0)
        ME_ArrowCtrlEnd(editor, p);
      else
        ME_ArrowEnd(editor, p);
      ME_ClearTempStyle(editor);
      ME_RepaintSelection(editor, &tmp_curs);
      ME_SendSelChange(editor);
      return TRUE;
    case VK_LEFT:
      editor->bCaretAtEnd = 0;
      if (ME_CancelSelection(editor, -1))
        return TRUE;
      ME_ArrowLeft(editor, p);
      ME_RepaintSelection(editor, &tmp_curs);
      ME_ClearTempStyle(editor);
      ME_SendSelChange(editor);
      return TRUE;
    case VK_RIGHT:
      editor->bCaretAtEnd = 0;
      if (ME_CancelSelection(editor, +1))
        return TRUE;
      ME_ArrowRight(editor, p);
      ME_RepaintSelection(editor, &tmp_curs);
      ME_ClearTempStyle(editor);
      ME_SendSelChange(editor);
      return TRUE;
  }
  return FALSE;
}
