/*
 * RichEdit - functions working on paragraphs of text (diParagraph).
 * 
 * Copyright 2004 by Krzysztof Foltman
 * Copyright 2006 by Phil Krylov
 *
 * 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);

static const WCHAR wszParagraphSign[] = {0xB6, 0};

void ME_MakeFirstParagraph(HDC hDC, ME_TextBuffer *text)
{
  PARAFORMAT2 fmt;
  CHARFORMAT2W cf;
  LOGFONTW lf;
  HFONT hf;
  ME_DisplayItem *para = ME_MakeDI(diParagraph);
  ME_DisplayItem *run;
  ME_Style *style;

  hf = (HFONT)GetStockObject(SYSTEM_FONT);
  assert(hf);
  GetObjectW(hf, sizeof(LOGFONTW), &lf);
  ZeroMemory(&cf, sizeof(cf));
  cf.cbSize = sizeof(cf);
  cf.dwMask = CFM_BACKCOLOR|CFM_COLOR|CFM_FACE|CFM_SIZE|CFM_CHARSET;
  cf.dwMask |= CFM_ALLCAPS|CFM_BOLD|CFM_DISABLED|CFM_EMBOSS|CFM_HIDDEN;
  cf.dwMask |= CFM_IMPRINT|CFM_ITALIC|CFM_LINK|CFM_OUTLINE|CFM_PROTECTED;
  cf.dwMask |= CFM_REVISED|CFM_SHADOW|CFM_SMALLCAPS|CFM_STRIKEOUT;
  cf.dwMask |= CFM_SUBSCRIPT|CFM_UNDERLINE;
  
  cf.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
  lstrcpyW(cf.szFaceName, lf.lfFaceName);
  cf.yHeight=lf.lfHeight*1440/GetDeviceCaps(hDC, LOGPIXELSY);
  if (lf.lfWeight>=700) /* FIXME correct weight ? */
    cf.dwEffects |= CFE_BOLD;
  cf.wWeight = lf.lfWeight;
  if (lf.lfItalic) cf.dwEffects |= CFE_ITALIC;
  if (lf.lfUnderline) cf.dwEffects |= CFE_UNDERLINE;
  if (lf.lfStrikeOut) cf.dwEffects |= CFE_STRIKEOUT;
  
  ZeroMemory(&fmt, sizeof(fmt));
  fmt.cbSize = sizeof(fmt);
  fmt.dwMask = PFM_ALIGNMENT | PFM_OFFSET | PFM_STARTINDENT | PFM_RIGHTINDENT | PFM_TABSTOPS;

  CopyMemory(para->member.para.pFmt, &fmt, sizeof(PARAFORMAT2));
  
  style = ME_MakeStyle(&cf);
  text->pDefaultStyle = style;
  
  run = ME_MakeRun(style, ME_MakeString(wszParagraphSign), MERF_ENDPARA);
  run->member.run.nCharOfs = 0;

  ME_InsertBefore(text->pLast, para);
  ME_InsertBefore(text->pLast, run);
  para->member.para.prev_para = text->pFirst;
  para->member.para.next_para = text->pLast;
  text->pFirst->member.para.next_para = para;
  text->pLast->member.para.prev_para = para;

  text->pLast->member.para.nCharOfs = 1;
}
 
void ME_MarkAllForWrapping(ME_TextEditor *editor)
{
  ME_MarkForWrapping(editor, editor->pBuffer->pFirst->member.para.next_para, editor->pBuffer->pLast);
}

void ME_MarkForWrapping(ME_TextEditor *editor, ME_DisplayItem *first, ME_DisplayItem *last)
{
  while(first != last)
  {
    first->member.para.nFlags |= MEPF_REWRAP;
    first = first->member.para.next_para;
  }
}

/* split paragraph at the beginning of the run */
ME_DisplayItem *ME_SplitParagraph(ME_TextEditor *editor, ME_DisplayItem *run, ME_Style *style)
{
  ME_DisplayItem *next_para = NULL;
  ME_DisplayItem *run_para = NULL;
  ME_DisplayItem *new_para = ME_MakeDI(diParagraph);
  ME_DisplayItem *end_run = ME_MakeRun(style,ME_MakeString(wszParagraphSign), MERF_ENDPARA);
  ME_UndoItem *undo = NULL;
  int ofs;
  ME_DisplayItem *pp;
  int end_len = (editor->bEmulateVersion10 ? 2 : 1);
  
  assert(run->type == diRun);  

  run_para = ME_GetParagraph(run);
  assert(run_para->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));

  ofs = end_run->member.run.nCharOfs = run->member.run.nCharOfs;
  next_para = run_para->member.para.next_para;
  assert(next_para == ME_FindItemFwd(run_para, diParagraphOrEnd));
  
  undo = ME_AddUndoItem(editor, diUndoJoinParagraphs, NULL);
  if (undo)
    undo->nStart = run_para->member.para.nCharOfs + ofs;
  
  /* the new paragraph will have a different starting offset, so let's update its runs */
  pp = run;
  while(pp->type == diRun) {
    pp->member.run.nCharOfs -= ofs;
    pp = ME_FindItemFwd(pp, diRunOrParagraphOrEnd);
  }
  new_para->member.para.nCharOfs = ME_GetParagraph(run)->member.para.nCharOfs+ofs;
  new_para->member.para.nCharOfs += end_len;
  
  new_para->member.para.nFlags = MEPF_REWRAP; /* FIXME copy flags (if applicable) */
  /* FIXME initialize format style and call ME_SetParaFormat blah blah */
  CopyMemory(new_para->member.para.pFmt, run_para->member.para.pFmt, sizeof(PARAFORMAT2));
  
  /* FIXME remove this as soon as nLeftMargin etc are replaced with proper fields of PARAFORMAT2 */
  new_para->member.para.nLeftMargin = run_para->member.para.nLeftMargin;
  new_para->member.para.nRightMargin = run_para->member.para.nRightMargin;
  new_para->member.para.nFirstMargin = run_para->member.para.nFirstMargin;

  new_para->member.para.bTable = run_para->member.para.bTable;
  new_para->member.para.pCells = NULL;

  /* fix paragraph properties. FIXME only needed when called from RTF reader */
  if (run_para->member.para.pCells && !run_para->member.para.bTable)
  {
    /* Paragraph does not have an \intbl keyword, so any table definition
     * stored is invalid */
    ME_DestroyTableCellList(run_para);
  }
  
  /* insert paragraph into paragraph double linked list */
  new_para->member.para.prev_para = run_para;
  new_para->member.para.next_para = next_para;
  run_para->member.para.next_para = new_para;
  next_para->member.para.prev_para = new_para;

  /* insert end run of the old paragraph, and new paragraph, into DI double linked list */
  ME_InsertBefore(run, new_para);
  ME_InsertBefore(new_para, end_run);

  /* force rewrap of the */
  run_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
  new_para->member.para.prev_para->member.para.nFlags |= MEPF_REWRAP;
  
  /* we've added the end run, so we need to modify nCharOfs in the next paragraphs */
  ME_PropagateCharOffset(next_para, end_len);
  editor->nParagraphs++;
  
  return new_para;
}

/* join tp with tp->member.para.next_para, keeping tp's style; this
 * is consistent with the original */
ME_DisplayItem *ME_JoinParagraphs(ME_TextEditor *editor, ME_DisplayItem *tp)
{
  ME_DisplayItem *pNext, *pFirstRunInNext, *pRun, *pTmp;
  int i, shift;
  ME_UndoItem *undo = NULL;
  int end_len = (editor->bEmulateVersion10 ? 2 : 1);

  assert(tp->type == diParagraph);
  assert(tp->member.para.next_para);
  assert(tp->member.para.next_para->type == diParagraph);
  
  pNext = tp->member.para.next_para;
  
  {
    /* null char format operation to store the original char format for the ENDPARA run */
    CHARFORMAT2W fmt;
    ME_InitCharFormat2W(&fmt);
    ME_SetCharFormat(editor, pNext->member.para.nCharOfs - end_len, end_len, &fmt);
  }
  undo = ME_AddUndoItem(editor, diUndoSplitParagraph, NULL);
  if (undo)
  {
    undo->nStart = pNext->member.para.nCharOfs - end_len;
    assert(pNext->member.para.pFmt->cbSize == sizeof(PARAFORMAT2));
    CopyMemory(undo->di.member.para.pFmt, pNext->member.para.pFmt, sizeof(PARAFORMAT2));
  }
  
  shift = pNext->member.para.nCharOfs - tp->member.para.nCharOfs - end_len;
  
  pRun = ME_FindItemBack(pNext, diRunOrParagraph);
  pFirstRunInNext = ME_FindItemFwd(pNext, diRunOrParagraph);
  
  assert(pRun);
  assert(pRun->type == diRun);
  assert(pRun->member.run.nFlags & MERF_ENDPARA);
  assert(pFirstRunInNext->type == diRun);
  
  /* if some cursor points at end of paragraph, make it point to the first
     run of the next joined paragraph */
  for (i=0; i<editor->nCursors; i++) {
    if (editor->pCursors[i].pRun == pRun) {
      editor->pCursors[i].pRun = pFirstRunInNext;
      editor->pCursors[i].nOffset = 0;
    }
  }

  pTmp = pNext;
  do {
    pTmp = ME_FindItemFwd(pTmp, diRunOrParagraphOrEnd);
    if (pTmp->type != diRun)
      break;
    TRACE("shifting \"%s\" by %d (previous %d)\n", debugstr_w(pTmp->member.run.strText->szData), shift, pTmp->member.run.nCharOfs);
    pTmp->member.run.nCharOfs += shift;
  } while(1);
  
  ME_Remove(pRun);
  ME_DestroyDisplayItem(pRun);

  tp->member.para.next_para = pNext->member.para.next_para;
  pNext->member.para.next_para->member.para.prev_para = tp;
  ME_Remove(pNext);
  ME_DestroyDisplayItem(pNext);

  ME_PropagateCharOffset(tp->member.para.next_para, -end_len);
  
  ME_CheckCharOffsets(editor);
  
  editor->nParagraphs--;
  tp->member.para.nFlags |= MEPF_REWRAP;
  return tp;
}

ME_DisplayItem *ME_GetParagraph(ME_DisplayItem *item) {
  return ME_FindItemBackOrHere(item, diParagraph);
}

static void ME_DumpStyleEffect(char **p, const char *name, PARAFORMAT2 *fmt, int mask)
{
  *p += sprintf(*p, "%-22s%s\n", name, (fmt->dwMask & mask) ? ((fmt->wEffects & mask) ? "yes" : "no") : "N/A");
}

void ME_DumpParaStyleToBuf(PARAFORMAT2 *pFmt, char buf[2048])
{
  /* FIXME only PARAFORMAT styles implemented */
  char *p;
  p = buf;
  p += sprintf(p, "Alignment:            %s\n",
    !(pFmt->dwMask & PFM_ALIGNMENT) ? "N/A" :
      ((pFmt->wAlignment == PFA_LEFT) ? "left" :
        ((pFmt->wAlignment == PFA_RIGHT) ? "right" :
          ((pFmt->wAlignment == PFA_CENTER) ? "center" :
            /*((pFmt->wAlignment == PFA_JUSTIFY) ? "justify" : "incorrect")*/
            "incorrect"))));

  if (pFmt->dwMask & PFM_OFFSET)
    p += sprintf(p, "Offset:               %d\n", (int)pFmt->dxOffset);
  else
    p += sprintf(p, "Offset:               N/A\n");
    
  if (pFmt->dwMask & PFM_OFFSETINDENT)
    p += sprintf(p, "Offset indent:        %d\n", (int)pFmt->dxStartIndent);
  else
    p += sprintf(p, "Offset indent:        N/A\n");
    
  if (pFmt->dwMask & PFM_STARTINDENT)
    p += sprintf(p, "Start indent:         %d\n", (int)pFmt->dxStartIndent);
  else
    p += sprintf(p, "Start indent:         N/A\n");
    
  if (pFmt->dwMask & PFM_RIGHTINDENT)
    p += sprintf(p, "Right indent:         %d\n", (int)pFmt->dxRightIndent);
  else
    p += sprintf(p, "Right indent:         N/A\n");
    
  ME_DumpStyleEffect(&p, "Page break before:", pFmt, PFM_PAGEBREAKBEFORE);
}

void ME_SetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *pFmt)
{
  PARAFORMAT2 copy;
  assert(sizeof(*para->member.para.pFmt) == sizeof(PARAFORMAT2));
  ME_AddUndoItem(editor, diUndoSetParagraphFormat, para);
  
  CopyMemory(&copy, para->member.para.pFmt, sizeof(PARAFORMAT2));

  if (pFmt->dwMask & PFM_ALIGNMENT)
    para->member.para.pFmt->wAlignment = pFmt->wAlignment;
  if (pFmt->dwMask & PFM_STARTINDENT)
    para->member.para.pFmt->dxStartIndent = pFmt->dxStartIndent;
  if (pFmt->dwMask & PFM_OFFSET)
    para->member.para.pFmt->dxOffset = pFmt->dxOffset;
  if (pFmt->dwMask & PFM_OFFSETINDENT)
    para->member.para.pFmt->dxStartIndent += pFmt->dxStartIndent;
    
  if (pFmt->dwMask & PFM_TABSTOPS)
  {
    para->member.para.pFmt->cTabCount = pFmt->cTabCount;
    memcpy(para->member.para.pFmt->rgxTabs, pFmt->rgxTabs, pFmt->cTabCount*sizeof(int));
  }
    
  /* FIXME to be continued (indents, bulleting and such) */

  if (memcmp(&copy, para->member.para.pFmt, sizeof(PARAFORMAT2)))
    para->member.para.nFlags |= MEPF_REWRAP;
}


void
ME_GetSelectionParas(ME_TextEditor *editor, ME_DisplayItem **para, ME_DisplayItem **para_end)
{
  ME_Cursor *pEndCursor = &editor->pCursors[1];
  
  *para = ME_GetParagraph(editor->pCursors[0].pRun);
  *para_end = ME_GetParagraph(editor->pCursors[1].pRun);
  if ((*para_end)->member.para.nCharOfs < (*para)->member.para.nCharOfs) {
    ME_DisplayItem *tmp = *para;

    *para = *para_end;
    *para_end = tmp;
    pEndCursor = &editor->pCursors[0];
  }
  
  /* selection consists of chars from nFrom up to nTo-1 */
  if ((*para_end)->member.para.nCharOfs > (*para)->member.para.nCharOfs) {
    if (!pEndCursor->nOffset) {
      *para_end = ME_GetParagraph(ME_FindItemBack(pEndCursor->pRun, diRun));
    }
  }
}


void ME_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
{
  ME_DisplayItem *para, *para_end;
  
  ME_GetSelectionParas(editor, &para, &para_end);
 
  do {
    ME_SetParaFormat(editor, para, pFmt);
    if (para == para_end)
      break;
    para = para->member.para.next_para;
  } while(1);
}

void ME_GetParaFormat(ME_TextEditor *editor, ME_DisplayItem *para, PARAFORMAT2 *pFmt)
{
  if (pFmt->cbSize >= sizeof(PARAFORMAT2))
  {
    CopyMemory(pFmt, para->member.para.pFmt, sizeof(PARAFORMAT2));
    return;
  }
  CopyMemory(pFmt, para->member.para.pFmt, pFmt->cbSize);  
}

void ME_GetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
{
  ME_DisplayItem *para, *para_end;
  PARAFORMAT2 tmp;
  
  ME_GetSelectionParas(editor, &para, &para_end);
  
  ME_GetParaFormat(editor, para, pFmt);
  if (para == para_end) return;
  
  do {
    ZeroMemory(&tmp, sizeof(tmp));
    tmp.cbSize = sizeof(tmp);
    ME_GetParaFormat(editor, para, &tmp);
    
    assert(tmp.dwMask & PFM_ALIGNMENT);    
    if (pFmt->wAlignment != tmp.wAlignment)
      pFmt->dwMask &= ~PFM_ALIGNMENT;
    
    assert(tmp.dwMask & PFM_STARTINDENT);
    if (pFmt->dxStartIndent != tmp.dxStartIndent)
      pFmt->dwMask &= ~PFM_STARTINDENT;
    
    assert(tmp.dwMask & PFM_OFFSET);
    if (pFmt->dxOffset != tmp.dxOffset)
      pFmt->dwMask &= ~PFM_OFFSET;
    
    assert(tmp.dwMask & PFM_TABSTOPS);    
    if (pFmt->dwMask & PFM_TABSTOPS) {
      if (pFmt->cTabCount != tmp.cTabCount)
        pFmt->dwMask &= ~PFM_TABSTOPS;
      else
      if (memcmp(pFmt->rgxTabs, tmp.rgxTabs, tmp.cTabCount*sizeof(int)))
        pFmt->dwMask &= ~PFM_TABSTOPS;
    }
    
    if (para == para_end)
      return;
    para = para->member.para.next_para;
  } while(1);
}
