/*
 * RichEdit - functions dealing with editor object
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "editor.h"

WINE_DEFAULT_DEBUG_CHANNEL(richedit);

void ME_EmptyUndoStack(ME_TextEditor *editor)
{
  ME_DisplayItem *p, *pNext;
  
  if (editor->nUndoMode == umIgnore)
    return;
  
  TRACE("Emptying undo stack\n");

  p = editor->pUndoStack;
  editor->pUndoStack = editor->pUndoStackBottom = NULL;
  editor->nUndoStackSize = 0;
  while(p) {
    pNext = p->next;
    ME_DestroyDisplayItem(p);    
    p = pNext;
  } 
  p = editor->pRedoStack;
  editor->pRedoStack = NULL;
  while(p) {
    pNext = p->next;
    ME_DestroyDisplayItem(p);    
    p = pNext;
  } 
}

ME_UndoItem *ME_AddUndoItem(ME_TextEditor *editor, ME_DIType type, const ME_DisplayItem *pdi) {
  if (editor->nUndoMode == umIgnore)
    return NULL;
  else if (editor->nUndoLimit == 0)
    return NULL;
  else
  {
    ME_DisplayItem *pItem = ALLOC_OBJ(ME_UndoItem);
    switch(type)
    {
    case diUndoPotentialEndTransaction:
        /* only should be added for manually typed chars, not undos or redos */
        assert(editor->nUndoMode == umAddToUndo);
        /* intentional fall-through to next case */
    case diUndoEndTransaction:
      break;
    case diUndoSetParagraphFormat:
      assert(pdi);
      pItem->member.para = pdi->member.para;
      pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2);
      *pItem->member.para.pFmt = *pdi->member.para.pFmt;
      break;
    case diUndoInsertRun:
      assert(pdi);
      pItem->member.run = pdi->member.run;
      pItem->member.run.strText = ME_StrDup(pItem->member.run.strText);
      ME_AddRefStyle(pItem->member.run.style);
      if (pdi->member.run.ole_obj)
      {
        pItem->member.run.ole_obj = ALLOC_OBJ(*pItem->member.run.ole_obj);
        ME_CopyReObject(pItem->member.run.ole_obj, pdi->member.run.ole_obj);
      }
      else pItem->member.run.ole_obj = NULL;
      break;
    case diUndoSetCharFormat:
      break;
    case diUndoDeleteRun:
    case diUndoJoinParagraphs:
      break;
    case diUndoSplitParagraph:
    {
      ME_DisplayItem *prev_para = pdi->member.para.prev_para;
      assert(pdi->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
      pItem->member.para.pFmt = ALLOC_OBJ(PARAFORMAT2);
      pItem->member.para.pFmt->cbSize = sizeof(PARAFORMAT2);
      pItem->member.para.pFmt->dwMask = 0;
      *pItem->member.para.pFmt = *pdi->member.para.pFmt;
      pItem->member.para.border = pdi->member.para.border;
      pItem->member.para.nFlags = prev_para->member.para.nFlags & ~MEPF_CELL;
      pItem->member.para.pCell = NULL;
      break;
    }
    default:
      assert(0 == "AddUndoItem, unsupported item type");
      return NULL;
    }
    pItem->type = type;
    pItem->prev = NULL;
    if (editor->nUndoMode == umAddToUndo || editor->nUndoMode == umAddBackToUndo)
    {
      if (editor->pUndoStack
          && editor->pUndoStack->type == diUndoPotentialEndTransaction)
      {
          editor->pUndoStack->type = diUndoEndTransaction;
      }
      if (editor->nUndoMode == umAddToUndo)
        TRACE("Pushing id=%s to undo stack, deleting redo stack\n", ME_GetDITypeName(type));
      else
        TRACE("Pushing id=%s to undo stack\n", ME_GetDITypeName(type));

      pItem->next = editor->pUndoStack;
      if (type == diUndoEndTransaction || type == diUndoPotentialEndTransaction)
        editor->nUndoStackSize++;
      if (editor->pUndoStack)
        editor->pUndoStack->prev = pItem;
      else
        editor->pUndoStackBottom = pItem;
      editor->pUndoStack = pItem;
      
      if (editor->nUndoStackSize > editor->nUndoLimit)
      { /* remove oldest undo from stack */
        ME_DisplayItem *p = editor->pUndoStackBottom;
        while (p->type !=diUndoEndTransaction)
          p = p->prev; /*find new stack bottom */
        editor->pUndoStackBottom = p->prev;
          editor->pUndoStackBottom->next = NULL;
        do
        {
          ME_DisplayItem *pp = p->next;
          ME_DestroyDisplayItem(p);
          p = pp;
        } while (p);
        editor->nUndoStackSize--;
      }
      /* any new operation (not redo) clears the redo stack */
      if (editor->nUndoMode == umAddToUndo) {
        ME_DisplayItem *p = editor->pRedoStack;
        while(p)
        {
          ME_DisplayItem *pp = p->next;
          ME_DestroyDisplayItem(p);
          p = pp;
        }
        editor->pRedoStack = NULL;
      }
    }
    else if (editor->nUndoMode == umAddToRedo)
    {
      TRACE("Pushing id=%s to redo stack\n", ME_GetDITypeName(type));
      pItem->next = editor->pRedoStack;
      if (editor->pRedoStack)
        editor->pRedoStack->prev = pItem;
      editor->pRedoStack = pItem;
    }
    else
      assert(0);
    return (ME_UndoItem *)pItem;
  }
}

/**
 * Commits preceding changes into a transaction that can be undone together.
 *
 * This should be called after all the changes occur associated with an event
 * so that the group of changes can be undone atomically as a transaction.
 *
 * This will have no effect the undo mode is set to ignore changes, or if no
 * changes preceded calling this function before the last time it was called.
 *
 * This can also be used to conclude a coalescing transaction (used for grouping
 * typed characters).
 */
void ME_CommitUndo(ME_TextEditor *editor) {
  if (editor->nUndoMode == umIgnore)
    return;
  
  assert(editor->nUndoMode == umAddToUndo);
  
  /* no transactions, no need to commit */
  if (!editor->pUndoStack)
    return;

  /* no need to commit empty transactions */
  if (editor->pUndoStack->type == diUndoEndTransaction)
    return;
    
  if (editor->pUndoStack->type == diUndoPotentialEndTransaction)
  {
      /* Previous transaction was as a result of characters typed,
       * so the end of this transaction is confirmed. */
      editor->pUndoStack->type = diUndoEndTransaction;
      return;
  }

  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
  ME_SendSelChange(editor);
}

/**
 * Groups supsequent changes with previous ones for an undo if coalescing.
 *
 * Has no effect if the previous changes were followed by a ME_CommitUndo. This
 * function will only have an affect if the previous changes were followed by
 * a call to ME_CommitCoalescingUndo, which allows the transaction to be
 * continued.
 *
 * This allows multiple consecutively typed characters to be grouped together
 * to be undone by a single undo operation.
 */
void ME_ContinueCoalescingTransaction(ME_TextEditor *editor)
{
  ME_DisplayItem* p;

  if (editor->nUndoMode == umIgnore)
    return;

  assert(editor->nUndoMode == umAddToUndo);

  p = editor->pUndoStack;

  if (p && p->type == diUndoPotentialEndTransaction) {
    assert(p->next); /* EndTransactions shouldn't be at bottom of undo stack */
    editor->pUndoStack = p->next;
    editor->pUndoStack->prev = NULL;
    editor->nUndoStackSize--;
    ME_DestroyDisplayItem(p);
  }
}

/**
 * Commits preceding changes into a undo transaction that can be expanded.
 *
 * This function allows the transaction to be reopened with
 * ME_ContinueCoalescingTransaction in order to continue the transaction.  If an
 * undo item is added to the undo stack as a result of a change without the
 * transaction being reopened, then the transaction will be ended, and the
 * changes will become a part of the next transaction.
 *
 * This is used to allow typed characters to be grouped together since each
 * typed character results in a single event, and each event adding undo items
 * must be committed.  Using this function as opposed to ME_CommitUndo allows
 * multiple events to be grouped, and undone together.
 */
void ME_CommitCoalescingUndo(ME_TextEditor *editor)
{
  if (editor->nUndoMode == umIgnore)
    return;

  assert(editor->nUndoMode == umAddToUndo);

  /* no transactions, no need to commit */
  if (!editor->pUndoStack)
    return;

  /* no need to commit empty transactions */
  if (editor->pUndoStack->type == diUndoEndTransaction)
    return;
  if (editor->pUndoStack->type == diUndoPotentialEndTransaction)
    return;

  ME_AddUndoItem(editor, diUndoPotentialEndTransaction, NULL);
  ME_SendSelChange(editor);
}

static void ME_PlayUndoItem(ME_TextEditor *editor, ME_DisplayItem *pItem)
{
  ME_UndoItem *pUItem = (ME_UndoItem *)pItem;

  if (editor->nUndoMode == umIgnore)
    return;
  TRACE("Playing undo/redo item, id=%s\n", ME_GetDITypeName(pItem->type));

  switch(pItem->type)
  {
  case diUndoPotentialEndTransaction:
  case diUndoEndTransaction:
    assert(0);
  case diUndoSetParagraphFormat:
  {
    ME_Cursor tmp;
    ME_DisplayItem *para;
    ME_CursorFromCharOfs(editor, pItem->member.para.nCharOfs, &tmp);
    para = ME_FindItemBack(tmp.pRun, diParagraph);
    ME_AddUndoItem(editor, diUndoSetParagraphFormat, para);
    *para->member.para.pFmt = *pItem->member.para.pFmt;
    para->member.para.border = pItem->member.para.border;
    break;
  }
  case diUndoSetCharFormat:
  {
    ME_Cursor start, end;
    ME_CursorFromCharOfs(editor, pUItem->nStart, &start);
    end = start;
    ME_MoveCursorChars(editor, &end, pUItem->nLen);
    ME_SetCharFormat(editor, &start, &end, &pItem->member.ustyle->fmt);
    break;
  }
  case diUndoInsertRun:
  {
    ME_Cursor tmp;
    ME_CursorFromCharOfs(editor, pItem->member.run.nCharOfs, &tmp);
    ME_InsertRunAtCursor(editor, &tmp, pItem->member.run.style,
                         pItem->member.run.strText->szData,
                         pItem->member.run.strText->nLen,
                         pItem->member.run.nFlags);
    break;
  }
  case diUndoDeleteRun:
  {
    ME_Cursor tmp;
    ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
    ME_InternalDeleteText(editor, &tmp, pUItem->nLen, TRUE);
    break;
  }
  case diUndoJoinParagraphs:
  {
    ME_Cursor tmp;
    ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
    /* the only thing that's needed is paragraph offset, so no need to split runs */
    ME_JoinParagraphs(editor, tmp.pPara, TRUE);
    break;
  }
  case diUndoSplitParagraph:
  {
    ME_Cursor tmp;
    ME_DisplayItem *this_para, *new_para;
    BOOL bFixRowStart;
    int paraFlags = pItem->member.para.nFlags & (MEPF_ROWSTART|MEPF_CELL|MEPF_ROWEND);
    ME_CursorFromCharOfs(editor, pUItem->nStart, &tmp);
    if (tmp.nOffset)
      tmp.pRun = ME_SplitRunSimple(editor, tmp.pRun, tmp.nOffset);
    assert(pUItem->eol_str);
    this_para = tmp.pPara;
    bFixRowStart = this_para->member.para.nFlags & MEPF_ROWSTART;
    if (bFixRowStart)
    {
      /* Re-insert the paragraph before the table, making sure the nFlag value
       * is correct. */
      this_para->member.para.nFlags &= ~MEPF_ROWSTART;
    }
    new_para = ME_SplitParagraph(editor, tmp.pRun, tmp.pRun->member.run.style,
                                 pUItem->eol_str, paraFlags);
    if (bFixRowStart)
      new_para->member.para.nFlags |= MEPF_ROWSTART;
    assert(pItem->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
    *new_para->member.para.pFmt = *pItem->member.para.pFmt;
    new_para->member.para.border = pItem->member.para.border;
    if (pItem->member.para.pCell)
    {
      ME_DisplayItem *pItemCell, *pCell;
      pItemCell = pItem->member.para.pCell;
      pCell = new_para->member.para.pCell;
      pCell->member.cell.nRightBoundary = pItemCell->member.cell.nRightBoundary;
      pCell->member.cell.border = pItemCell->member.cell.border;
    }
    break;
  }
  default:
    assert(0 == "PlayUndoItem, unexpected type");
  }
}

BOOL ME_Undo(ME_TextEditor *editor) {
  ME_DisplayItem *p;
  ME_UndoMode nMode = editor->nUndoMode;
  
  if (editor->nUndoMode == umIgnore)
    return FALSE;
  assert(nMode == umAddToUndo || nMode == umIgnore);
  
  /* no undo items ? */
  if (!editor->pUndoStack)
    return FALSE;
    
  /* watch out for uncommitted transactions ! */
  assert(editor->pUndoStack->type == diUndoEndTransaction
        || editor->pUndoStack->type == diUndoPotentialEndTransaction);
  
  editor->nUndoMode = umAddToRedo;
  p = editor->pUndoStack->next;
  ME_DestroyDisplayItem(editor->pUndoStack);
  editor->pUndoStack = p;
  do {
    p->prev = NULL;
    ME_PlayUndoItem(editor, p);
    editor->pUndoStack = p->next;
    ME_DestroyDisplayItem(p);
    p = editor->pUndoStack;
  } while(p && p->type != diUndoEndTransaction);
  if (p)
    p->prev = NULL;
  ME_MoveCursorFromTableRowStartParagraph(editor);
  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
  ME_CheckTablesForCorruption(editor);
  editor->nUndoStackSize--;
  editor->nUndoMode = nMode;
  ME_UpdateRepaint(editor);
  return TRUE;
}

BOOL ME_Redo(ME_TextEditor *editor) {
  ME_DisplayItem *p;
  ME_UndoMode nMode = editor->nUndoMode;
  
  assert(nMode == umAddToUndo || nMode == umIgnore);
  
  if (editor->nUndoMode == umIgnore)
    return FALSE;
  /* no redo items ? */
  if (!editor->pRedoStack)
    return FALSE;
    
  /* watch out for uncommitted transactions ! */
  assert(editor->pRedoStack->type == diUndoEndTransaction);
  
  editor->nUndoMode = umAddBackToUndo;
  p = editor->pRedoStack->next;
  ME_DestroyDisplayItem(editor->pRedoStack);
  editor->pRedoStack = p;
  do {
    p->prev = NULL;
    ME_PlayUndoItem(editor, p);
    editor->pRedoStack = p->next;
    ME_DestroyDisplayItem(p);
    p = editor->pRedoStack;
  } while(p && p->type != diUndoEndTransaction);
  if (p)
    p->prev = NULL;
  ME_MoveCursorFromTableRowStartParagraph(editor);
  ME_AddUndoItem(editor, diUndoEndTransaction, NULL);
  ME_CheckTablesForCorruption(editor);
  editor->nUndoMode = nMode;
  ME_UpdateRepaint(editor);
  return TRUE;
}
