/*
 * RichEdit - functions working on paragraphs of text (diParagraph).
 * 
 * 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);

static 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;

  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;
  
  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 += 1;
  
  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;
  
  /* 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, 1);
  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;

  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-1, 1, &fmt);
  }
  undo = ME_AddUndoItem(editor, diUndoSplitParagraph, NULL);
  if (undo)
  {
    undo->nStart = pNext->member.para.nCharOfs-1;
    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 - 1;
  
  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, -1);
  
  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;
    
  /* 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_SetSelectionParaFormat(ME_TextEditor *editor, PARAFORMAT2 *pFmt)
{
  int nFrom, nTo;
  ME_DisplayItem *para, *para_end, *run;
  int nOffset;
  
  ME_GetSelection(editor, &nFrom, &nTo);
  if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
    nTo--;
  
  ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
  para = ME_GetParagraph(run);
  ME_RunOfsFromCharOfs(editor, nTo, &run, &nOffset);
  para_end = ME_GetParagraph(run);
  
  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)
{
  int nFrom, nTo;
  ME_DisplayItem *para, *para_end, *run;
  int nOffset;
  PARAFORMAT2 tmp;
  
  ME_GetSelection(editor, &nFrom, &nTo);
  if (nTo>nFrom) /* selection consists of chars from nFrom up to nTo-1 */
    nTo--;
  
  ME_RunOfsFromCharOfs(editor, nFrom, &run, &nOffset);
  para = ME_GetParagraph(run);
  ME_RunOfsFromCharOfs(editor, nTo, &run, &nOffset);
  para_end = ME_GetParagraph(run);
  
  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;
    
    if (para == para_end)
      return;
    para = para->member.para.next_para;
  } while(1);
}
