/*
 * RichEdit - RTF writer module
 *
 * Copyright 2005 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 BOOL
ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars);


static void
ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
{
  editor->pStream = ALLOC_OBJ(ME_OutStream);
  editor->pStream->stream = stream;
  editor->pStream->pos = 0;
  editor->pStream->written = 0;
  editor->pStream->nFontTblLen = 0;
  editor->pStream->nColorTblLen = 1;
}


static BOOL
ME_StreamOutFlush(ME_TextEditor *editor)
{
  LONG nStart = 0;
  LONG nWritten = 0;
  EDITSTREAM *stream = editor->pStream->stream;

  do {
    stream->dwError = stream->pfnCallback(stream->dwCookie, editor->pStream->buffer + nStart,
                                          editor->pStream->pos - nStart, &nWritten);
    if (nWritten == 0 || stream->dwError)
      return FALSE;
    editor->pStream->written += nWritten;
    nStart += nWritten;
  } while (nStart < editor->pStream->pos);
  editor->pStream->pos = 0;
  return TRUE;
}


static LONG
ME_StreamOutFree(ME_TextEditor *editor)
{
  LONG written = editor->pStream->written;

  FREE_OBJ(editor->pStream);
  editor->pStream = NULL;
  return written;
}


static BOOL
ME_StreamOutMove(ME_TextEditor *editor, BYTE *buffer, int len)
{
  ME_OutStream *pStream = editor->pStream;
  
  while (len) {
    int space = STREAMOUT_BUFFER_SIZE - pStream->pos;
    int fit = min(space, len);

    TRACE("%u:%u:%.*s\n", pStream->pos, fit, fit, buffer);
    memmove(pStream->buffer + pStream->pos, buffer, fit);
    len -= fit;
    buffer += fit;
    pStream->pos += fit;
    if (pStream->pos == STREAMOUT_BUFFER_SIZE) {
      if (!ME_StreamOutFlush(editor))
        return FALSE;
    }
  }
  return TRUE;
}


static BOOL
ME_StreamOutPrint(ME_TextEditor *editor, char *format, ...)
{
  char string[STREAMOUT_BUFFER_SIZE]; /* This is going to be enough */
  int len;
  va_list valist;

  va_start(valist, format);
  len = vsnprintf(string, sizeof(string), format, valist);
  va_end(valist);
  
  return ME_StreamOutMove(editor, string, len);
}


static BOOL
ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat)
{
  char *cCharSet = NULL;
  UINT nCodePage;
  LANGID language;
  BOOL success;
  
  if (dwFormat & SF_USECODEPAGE) {
    CPINFOEXW info;
    
    switch (HIWORD(dwFormat)) {
      case CP_ACP:
        cCharSet = "ansi";
        nCodePage = GetACP();
        break;
      case CP_OEMCP:
        nCodePage = GetOEMCP();
        if (nCodePage == 437)
          cCharSet = "pc";
        else if (nCodePage == 850)
          cCharSet = "pca";
        else
          cCharSet = "ansi";
        break;
      case CP_UTF8:
        nCodePage = CP_UTF8;
        break;
      default:
        if (HIWORD(dwFormat) == CP_MACCP) {
          cCharSet = "mac";
          nCodePage = 10000; /* MacRoman */
        } else {
          cCharSet = "ansi";
          nCodePage = 1252; /* Latin-1 */
        }
        if (GetCPInfoExW(HIWORD(dwFormat), 0, &info))
          nCodePage = info.CodePage;
    }
  } else {
    cCharSet = "ansi";
    nCodePage = GetACP();
  }
  if (nCodePage == CP_UTF8)
    success = ME_StreamOutPrint(editor, "{\\urtf");
  else
    success = ME_StreamOutPrint(editor, "{\\rtf1\\%s\\ansicpg%u\\uc1", cCharSet, nCodePage);

  if (!success)
    return FALSE;

  editor->pStream->nCodePage = nCodePage;
  
  /* FIXME: This should be a document property */
  /* TODO: handle SFF_PLAINRTF */
  language = GetUserDefaultLangID(); 
  if (!ME_StreamOutPrint(editor, "\\deff0\\deflang%u\\deflangfe%u", language, language))
    return FALSE;

  /* FIXME: This should be a document property */
  editor->pStream->nDefaultFont = 0;

  return TRUE;
}


static BOOL
ME_StreamOutRTFFontAndColorTbl(ME_TextEditor *editor, ME_DisplayItem *pFirstRun, ME_DisplayItem *pLastRun)
{
  ME_DisplayItem *item = pFirstRun;
  ME_FontTableItem *table = editor->pStream->fonttbl;
  int i;
  
  do {
    CHARFORMAT2W *fmt = &item->member.run.style->fmt;
    COLORREF crColor;

    if (fmt->dwMask & CFM_FACE) {
      WCHAR *face = fmt->szFaceName;
      BYTE bCharSet = fmt->bCharSet;
  
      for (i = 0; i < editor->pStream->nFontTblLen; i++)
        if (table[i].bCharSet == bCharSet
            && (table[i].szFaceName == face || !lstrcmpW(table[i].szFaceName, face)))
          break;
      if (i == editor->pStream->nFontTblLen) {
        table[i].bCharSet = bCharSet;
        table[i].szFaceName = face;
        editor->pStream->nFontTblLen++;
      }
    }
    
    if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR)) {
      crColor = fmt->crTextColor;
      for (i = 1; i < editor->pStream->nColorTblLen; i++)
        if (editor->pStream->colortbl[i] == crColor)
          break;
      if (i == editor->pStream->nColorTblLen) {
        editor->pStream->colortbl[i] = crColor;
        editor->pStream->nColorTblLen++;
      }
    }
    if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR)) {
      crColor = fmt->crBackColor;
      for (i = 1; i < editor->pStream->nColorTblLen; i++)
        if (editor->pStream->colortbl[i] == crColor)
          break;
      if (i == editor->pStream->nColorTblLen) {
        editor->pStream->colortbl[i] = crColor;
        editor->pStream->nColorTblLen++;
      }
    }

    if (item == pLastRun)
      break;
    item = ME_FindItemFwd(item, diRun);
  } while (item);
        
  if (!ME_StreamOutPrint(editor, "{\\fonttbl"))
    return FALSE;
  
  for (i = 0; i < editor->pStream->nFontTblLen; i++) {
    if (table[i].bCharSet) {
      if (!ME_StreamOutPrint(editor, "{\\f%u\\fcharset%u ", i, table[i].bCharSet))
        return FALSE;
    } else {
      if (!ME_StreamOutPrint(editor, "{\\f%u ", i))
        return FALSE;
    }
    if (!ME_StreamOutRTFText(editor, table[i].szFaceName, -1))
      return FALSE;
    if (!ME_StreamOutPrint(editor, ";}\r\n"))
      return FALSE;
  }
  if (!ME_StreamOutPrint(editor, "}"))
    return FALSE;

  /* Output colors table if not empty */
  if (editor->pStream->nColorTblLen > 1) {
    if (!ME_StreamOutPrint(editor, "{\\colortbl;"))
      return FALSE;
    for (i = 1; i < editor->pStream->nColorTblLen; i++) {
      if (!ME_StreamOutPrint(editor, "\\red%u\\green%u\\blue%u;",
                             editor->pStream->colortbl[i] & 0xFF,
                             (editor->pStream->colortbl[i] >> 8) & 0xFF,
                             (editor->pStream->colortbl[i] >> 16) & 0xFF))
        return FALSE;
    }
    if (!ME_StreamOutPrint(editor, "}"))
      return FALSE;
  }

  return TRUE;
}


static BOOL
ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_DisplayItem *para)
{
  PARAFORMAT2 *fmt = para->member.para.pFmt;
  char props[STREAMOUT_BUFFER_SIZE] = "";
  int i;

  /* TODO: Don't emit anything if the last PARAFORMAT2 is inherited */
  if (!ME_StreamOutPrint(editor, "\\pard"))
    return FALSE;
  
  /* TODO: PFM_BORDER. M$ does not emit any keywords for these properties, and
   * when streaming border keywords in, PFM_BORDER is set, but wBorder field is
   * set very different from the documentation.
   * (Tested with RichEdit 5.50.25.0601) */
  
  if (fmt->dwMask & PFM_ALIGNMENT) {
    switch (fmt->wAlignment) {
      case PFA_LEFT:
        /* Default alignment: not emitted */
        break;
      case PFA_RIGHT:
        strcat(props, "\\qr");
        break;
      case PFA_CENTER:
        strcat(props, "\\qc");
        break;
      case PFA_JUSTIFY:
        strcat(props, "\\qj");
        break;
    }
  }
  
  if (fmt->dwMask & PFM_LINESPACING) {
    /* FIXME: MSDN says that the bLineSpacingRule field is controlled by the
     * PFM_SPACEAFTER flag. Is that true? I don't believe so. */
    switch (fmt->bLineSpacingRule) {
      case 0: /* Single spacing */
        strcat(props, "\\sl-240\\slmult1");
        break;
      case 1: /* 1.5 spacing */
        strcat(props, "\\sl-360\\slmult1");
        break;
      case 2: /* Double spacing */
        strcat(props, "\\sl-480\\slmult1");
        break;
      case 3:
        sprintf(props + strlen(props), "\\sl%ld\\slmult0", fmt->dyLineSpacing);
        break;
      case 4:
        sprintf(props + strlen(props), "\\sl-%ld\\slmult0", fmt->dyLineSpacing);
        break;
      case 5:
        sprintf(props + strlen(props), "\\sl-%ld\\slmult1", fmt->dyLineSpacing * 240 / 20);
        break;
    }
  }

  if (fmt->dwMask & PFM_DONOTHYPHEN && fmt->wEffects & PFE_DONOTHYPHEN)
    strcat(props, "\\hyph0");
  if (fmt->dwMask & PFM_KEEP && fmt->wEffects & PFE_KEEP)
    strcat(props, "\\keep");
  if (fmt->dwMask & PFM_KEEPNEXT && fmt->wEffects & PFE_KEEPNEXT)
    strcat(props, "\\keepn");
  if (fmt->dwMask & PFM_NOLINENUMBER && fmt->wEffects & PFE_NOLINENUMBER)
    strcat(props, "\\noline");
  if (fmt->dwMask & PFM_NOWIDOWCONTROL && fmt->wEffects & PFE_NOWIDOWCONTROL)
    strcat(props, "\\nowidctlpar");
  if (fmt->dwMask & PFM_PAGEBREAKBEFORE && fmt->wEffects & PFE_PAGEBREAKBEFORE)
    strcat(props, "\\pagebb");
  if (fmt->dwMask & PFM_RTLPARA && fmt->wEffects & PFE_RTLPARA)
    strcat(props, "\\rtlpar");
  if (fmt->dwMask & PFM_SIDEBYSIDE && fmt->wEffects & PFE_SIDEBYSIDE)
    strcat(props, "\\sbys");
  if (fmt->dwMask & PFM_TABLE && fmt->dwMask & PFE_TABLE)
    strcat(props, "\\intbl");
  
  if (fmt->dwMask & PFM_OFFSET)
    sprintf(props + strlen(props), "\\li%ld", fmt->dxOffset);
  if (fmt->dwMask & PFM_OFFSETINDENT || fmt->dwMask & PFM_STARTINDENT)
    sprintf(props + strlen(props), "\\fi%ld", fmt->dxStartIndent);
  if (fmt->dwMask & PFM_RIGHTINDENT)
    sprintf(props + strlen(props), "\\ri%ld", fmt->dxRightIndent);
  if (fmt->dwMask & PFM_SPACEAFTER)
    sprintf(props + strlen(props), "\\sa%ld", fmt->dySpaceAfter);
  if (fmt->dwMask & PFM_SPACEBEFORE)
    sprintf(props + strlen(props), "\\sb%ld", fmt->dySpaceBefore);
  if (fmt->dwMask & PFM_STYLE)
    sprintf(props + strlen(props), "\\s%d", fmt->sStyle);

  if (fmt->dwMask & PFM_TABSTOPS) {
    static const char *leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" };
    
    for (i = 0; i < fmt->cTabCount; i++) {
      switch ((fmt->rgxTabs[i] >> 24) & 0xF) {
        case 1:
          strcat(props, "\\tqc");
          break;
        case 2:
          strcat(props, "\\tqr");
          break;
        case 3:
          strcat(props, "\\tqdec");
          break;
        case 4:
          /* Word bar tab (vertical bar). Handled below */
          break;
      }
      if (fmt->rgxTabs[i] >> 28 <= 5)
        strcat(props, leader[fmt->rgxTabs[i] >> 28]);
    }
  }
    
  
  if (fmt->dwMask & PFM_SHADING) {
    static const char *style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag",
                                     "\\bgdkbdiag", "\\bgdkcross", "\\bgdkdcross",
                                     "\\bghoriz", "\\bgvert", "\\bgfdiag",
                                     "\\bgbdiag", "\\bgcross", "\\bgdcross",
                                     "", "", "" };
    if (fmt->wShadingWeight)
      sprintf(props + strlen(props), "\\shading%d", fmt->wShadingWeight);
    if (fmt->wShadingStyle & 0xF)
      strcat(props, style[fmt->wShadingStyle & 0xF]);
    sprintf(props + strlen(props), "\\cfpat%d\\cbpat%d",
            (fmt->wShadingStyle >> 4) & 0xF, (fmt->wShadingStyle >> 8) & 0xF);
  }
  
  if (*props && !ME_StreamOutPrint(editor, props))
    return FALSE;

  return TRUE;
}


static BOOL
ME_StreamOutRTFCharProps(ME_TextEditor *editor, CHARFORMAT2W *fmt)
{
  char props[STREAMOUT_BUFFER_SIZE] = "";
  int i;

  if (fmt->dwMask & CFM_ALLCAPS && fmt->dwEffects & CFE_ALLCAPS)
    strcat(props, "\\caps");
  if (fmt->dwMask & CFM_ANIMATION)
    sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation);
  if (fmt->dwMask & CFM_BACKCOLOR) {
    if (!(fmt->dwEffects & CFE_AUTOBACKCOLOR)) {
      for (i = 1; i < editor->pStream->nColorTblLen; i++)
        if (editor->pStream->colortbl[i] == fmt->crBackColor) {
          sprintf(props + strlen(props), "\\cb%u", i);
          break;
        }
    }
  }
  if (fmt->dwMask & CFM_BOLD && fmt->dwEffects & CFE_BOLD)
    strcat(props, "\\b");
  if (fmt->dwMask & CFM_COLOR) {
    if (!(fmt->dwEffects & CFE_AUTOCOLOR)) {
      for (i = 1; i < editor->pStream->nColorTblLen; i++)
        if (editor->pStream->colortbl[i] == fmt->crTextColor) {
          sprintf(props + strlen(props), "\\cf%u", i);
          break;
        }
    }
  }
  /* TODO: CFM_DISABLED */
  if (fmt->dwMask & CFM_EMBOSS && fmt->dwEffects & CFE_EMBOSS)
    strcat(props, "\\embo");
  if (fmt->dwMask & CFM_HIDDEN && fmt->dwEffects & CFE_HIDDEN)
    strcat(props, "\\v");
  if (fmt->dwMask & CFM_IMPRINT && fmt->dwEffects & CFE_IMPRINT)
    strcat(props, "\\impr");
  if (fmt->dwMask & CFM_ITALIC && fmt->dwEffects & CFE_ITALIC)
    strcat(props, "\\i");
  if (fmt->dwMask & CFM_KERNING)
    sprintf(props + strlen(props), "\\kerning%u", fmt->wKerning);
  if (fmt->dwMask & CFM_LCID) {
    /* TODO: handle SFF_PLAINRTF */
    if (LOWORD(fmt->lcid) == 1024)
      strcat(props, "\\noproof\\lang1024\\langnp1024\\langfe1024\\langfenp1024");
    else
      sprintf(props + strlen(props), "\\lang%u", LOWORD(fmt->lcid));
  }
  /* CFM_LINK is not streamed out by M$ */
  if (fmt->dwMask & CFM_OFFSET) {
    if (fmt->yOffset >= 0)
      sprintf(props + strlen(props), "\\up%ld", fmt->yOffset);
    else
      sprintf(props + strlen(props), "\\dn%ld", -fmt->yOffset);
  }
  if (fmt->dwMask & CFM_OUTLINE && fmt->dwEffects & CFE_OUTLINE)
    strcat(props, "\\outl");
  if (fmt->dwMask & CFM_PROTECTED && fmt->dwEffects & CFE_PROTECTED)
    strcat(props, "\\protect");
  /* TODO: CFM_REVISED CFM_REVAUTHOR - probably using rsidtbl? */
  if (fmt->dwMask & CFM_SHADOW && fmt->dwEffects & CFE_SHADOW)
    strcat(props, "\\shad");
  if (fmt->dwMask & CFM_SIZE)
    sprintf(props + strlen(props), "\\fs%ld", fmt->yHeight / 10);
  if (fmt->dwMask & CFM_SMALLCAPS && fmt->dwEffects & CFE_SMALLCAPS)
    strcat(props, "\\scaps");
  if (fmt->dwMask & CFM_SPACING)
    sprintf(props + strlen(props), "\\expnd%u\\expndtw%u", fmt->sSpacing / 5, fmt->sSpacing);
  if (fmt->dwMask & CFM_STRIKEOUT && fmt->dwEffects & CFE_STRIKEOUT)
    strcat(props, "\\strike");
  if (fmt->dwMask & CFM_STYLE) {
    sprintf(props + strlen(props), "\\cs%u", fmt->sStyle);
    /* TODO: emit style contents here */
  }
  if (fmt->dwMask & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT)) {
    if (fmt->dwEffects & CFE_SUBSCRIPT)
      strcat(props, "\\sub");
    else if (fmt->dwEffects & CFE_SUPERSCRIPT)
      strcat(props, "\\super");
  }
  if (fmt->dwMask & CFM_UNDERLINE || fmt->dwMask & CFM_UNDERLINETYPE) {
    if (fmt->dwMask & CFM_UNDERLINETYPE)
      switch (fmt->bUnderlineType) {
        case CFU_CF1UNDERLINE:
        case CFU_UNDERLINE:
          strcat(props, "\\ul");
          break;
        case CFU_UNDERLINEDOTTED:
          strcat(props, "\\uld");
          break;
        case CFU_UNDERLINEDOUBLE:
          strcat(props, "\\uldb");
          break;
        case CFU_UNDERLINEWORD:
          strcat(props, "\\ulw");
          break;
        case CFU_UNDERLINENONE:
        default:
          strcat(props, "\\ul0");
          break;
      }
    else if (fmt->dwEffects & CFE_UNDERLINE)
      strcat(props, "\\ul");
  }
  /* FIXME: How to emit CFM_WEIGHT? */
  
  if (fmt->dwMask & CFM_FACE || fmt->dwMask & CFM_CHARSET) {
    WCHAR *szFaceName;
    
    if (fmt->dwMask & CFM_FACE)
      szFaceName = fmt->szFaceName;
    else
      szFaceName = editor->pStream->fonttbl[0].szFaceName;
    for (i = 0; i < editor->pStream->nFontTblLen; i++) {
      if (szFaceName == editor->pStream->fonttbl[i].szFaceName
          || !lstrcmpW(szFaceName, editor->pStream->fonttbl[i].szFaceName))
        if (!(fmt->dwMask & CFM_CHARSET)
            || fmt->bCharSet == editor->pStream->fonttbl[i].bCharSet)
          break;
    }
    if (i < editor->pStream->nFontTblLen && i != editor->pStream->nDefaultFont)
      sprintf(props + strlen(props), "\\f%u", i);
  }
  if (*props)
    strcat(props, " ");
  if (!ME_StreamOutPrint(editor, props))
    return FALSE;
  return TRUE;
}


static BOOL
ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
{
  char buffer[STREAMOUT_BUFFER_SIZE];
  int pos = 0;
  int fit, i;

  if (nChars == -1)
    nChars = lstrlenW(text);
  
  while (nChars) {
    if (editor->pStream->nCodePage == CP_UTF8) {
      /* 6 is the maximum character length in UTF-8 */
      fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
      WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer, STREAMOUT_BUFFER_SIZE,
                          NULL, NULL);
      nChars -= fit;
      text += fit;
      for (i = 0; buffer[i]; i++)
        if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
          if (!ME_StreamOutPrint(editor, "%.*s\\", i - pos, buffer + pos))
            return FALSE;
          pos = i;
        }
      if (!pos)
        if (!ME_StreamOutPrint(editor, "%s", buffer + pos))
          return FALSE;
      pos = 0;
    } else if (*text < 128) {
      if (*text == '{' || *text == '}' || *text == '\\')
        buffer[pos++] = '\\';
      buffer[pos++] = (char)(*text++);
      nChars--;
    } else {
      BOOL unknown;
      BYTE letter[2];
      
      WideCharToMultiByte(editor->pStream->nCodePage, 0, text, 1, letter, 2,
                          NULL, &unknown);
      if (unknown)
        pos += sprintf(buffer + pos, "\\u%d?", (int)*text);
      else if (*letter < 128) {
        if (*letter == '{' || *letter == '}' || *letter == '\\')
          buffer[pos++] = '\\';
        buffer[pos++] = *letter;
      } else
        pos += sprintf(buffer + pos, "\\'%02x", *letter);
      text++;
      nChars--;
    }
    if (pos >= STREAMOUT_BUFFER_SIZE - 10) {
      if (!ME_StreamOutMove(editor, buffer, pos))
        return FALSE;
      pos = 0;
    }
  }
  return ME_StreamOutMove(editor, buffer, pos);
}


static BOOL
ME_StreamOutRTF(ME_TextEditor *editor, int nStart, int nChars, int dwFormat)
{
  ME_DisplayItem *p, *pEnd;
  int nOffset, nEndLen;
  ME_RunOfsFromCharOfs(editor, nStart, &p, &nOffset);
  ME_RunOfsFromCharOfs(editor, nStart+nChars, &pEnd, &nEndLen);
  
  if (!ME_StreamOutRTFHeader(editor, dwFormat))
    return FALSE;

  if (!ME_StreamOutRTFFontAndColorTbl(editor, p, pEnd))
    return FALSE;
  
  /* TODO: stylesheet table */
  
  /* FIXME: maybe emit something smarter for the generator? */
  if (!ME_StreamOutPrint(editor, "{\\*\\generator Wine Riched20 2.0.????;}"))
    return FALSE;

  /* TODO: information group */

  /* TODO: document formatting properties */

  /* FIXME: We have only one document section */

  /* TODO: section formatting properties */

  if (!ME_StreamOutRTFParaProps(editor, ME_GetParagraph(p)))
    return FALSE;

  while(1)
  {
    switch(p->type)
    {
      case diParagraph:
        if (!ME_StreamOutRTFParaProps(editor, p))
          return FALSE;
        break;
      case diRun:
        if (p == pEnd && !nEndLen)
          break;
        TRACE("flags %xh\n", p->member.run.nFlags);
        /* TODO: emit embedded objects */
        if (p->member.run.nFlags & MERF_GRAPHICS)
          FIXME("embedded objects are not handled\n");
        if (p->member.run.nFlags & MERF_ENDPARA) {
          if (!ME_StreamOutPrint(editor, "\r\n\\par"))
            return FALSE;
          nChars--;
        } else {
          int nEnd;
          
          if (!ME_StreamOutPrint(editor, "{"))
            return FALSE;
          TRACE("style %p\n", p->member.run.style);
          if (!ME_StreamOutRTFCharProps(editor, &p->member.run.style->fmt))
            return FALSE;
        
          nEnd = (p == pEnd) ? nEndLen : ME_StrLen(p->member.run.strText);
          if (!ME_StreamOutRTFText(editor, p->member.run.strText->szData + nOffset, nEnd - nOffset))
            return FALSE;
          nOffset = 0;
          if (!ME_StreamOutPrint(editor, "}"))
            return FALSE;
        }
        break;
      default: /* we missed the last item */
        assert(0);
    }
    if (p == pEnd)
      break;
    p = ME_FindItemFwd(p, diRunOrParagraphOrEnd);
  }
  if (!ME_StreamOutPrint(editor, "}"))
    return FALSE;
  return TRUE;
}


static BOOL
ME_StreamOutText(ME_TextEditor *editor, int nStart, int nChars, DWORD dwFormat)
{
  /* FIXME: use ME_RunOfsFromCharOfs */
  ME_DisplayItem *item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart);
  int nLen;
  UINT nCodePage = CP_ACP;
  BYTE *buffer = NULL;
  int nBufLen = 0;
  BOOL success = TRUE;

  if (!item)
    return FALSE;
   
  if (dwFormat & SF_USECODEPAGE)
    nCodePage = HIWORD(dwFormat);

  /* TODO: Handle SF_TEXTIZED */
  
  while (success && nChars && item) {
    nLen = ME_StrLen(item->member.run.strText) - nStart;
    if (nLen > nChars)
      nLen = nChars;

    if (item->member.run.nFlags & MERF_ENDPARA) {
      WCHAR szEOL[] = { '\r', '\n' };
      
      if (dwFormat & SF_UNICODE)
        success = ME_StreamOutMove(editor, (BYTE *)szEOL, 4);
      else
        success = ME_StreamOutMove(editor, "\r\n", 2);
    } else {
      if (dwFormat & SF_UNICODE)
        success = ME_StreamOutMove(editor, (BYTE *)(item->member.run.strText->szData + nStart),
                                   sizeof(WCHAR) * nLen);
      else {
        int nSize;

        nSize = WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
                                    nLen, NULL, 0, NULL, NULL);
        if (nSize > nBufLen) {
          if (buffer)
            FREE_OBJ(buffer);
          buffer = ALLOC_N_OBJ(BYTE, nSize);
          nBufLen = nSize;
        }
        WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,
                            nLen, buffer, nSize, NULL, NULL);
        success = ME_StreamOutMove(editor, buffer, nSize - 1);
      }
    }
    
    nChars -= nLen;
    nStart = 0;
    item = ME_FindItemFwd(item, diRun);
  }
  
  if (buffer)
    FREE_OBJ(buffer);
  return success;
}


LRESULT
ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
{
  int nStart, nTo;
  
  ME_StreamOutInit(editor, stream);

  if (dwFormat & SFF_SELECTION)
    ME_GetSelection(editor, &nStart, &nTo);
  else {
    nStart = 0;
    nTo = -1;
  }
  if (nTo == -1)
    nTo = ME_GetTextLength(editor);
  TRACE("from %d to %d\n", nStart, nTo);
  
  if (dwFormat & SF_RTF || dwFormat & SF_RTFNOOBJS)
    ME_StreamOutRTF(editor, nStart, nTo - nStart, dwFormat);
  else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
    ME_StreamOutText(editor, nStart, nTo - nStart, dwFormat);
  
  ME_StreamOutFlush(editor);
  return ME_StreamOutFree(editor);
}
