/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#define NONAMELESSUNION

#include "editor.h"
#include "rtf.h"

WINE_DEFAULT_DEBUG_CHANNEL(richedit);

#define STREAMOUT_BUFFER_SIZE 4096
#define STREAMOUT_FONTTBL_SIZE 8192
#define STREAMOUT_COLORTBL_SIZE 1024

typedef struct tagME_OutStream
{
    EDITSTREAM *stream;
    char buffer[STREAMOUT_BUFFER_SIZE];
    UINT pos, written;
    UINT nCodePage;
    UINT nFontTblLen;
    ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE];
    UINT nColorTblLen;
    COLORREF colortbl[STREAMOUT_COLORTBL_SIZE];
    UINT nDefaultFont;
    UINT nDefaultCodePage;
    /* nNestingLevel = 0 means we aren't in a cell, 1 means we are in a cell,
     * an greater numbers mean we are in a cell nested within a cell. */
    UINT nNestingLevel;
    CHARFORMAT2W cur_fmt; /* current character format */
} ME_OutStream;

static BOOL
ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars);


static ME_OutStream*
ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
{
  ME_OutStream *pStream = ALLOC_OBJ(ME_OutStream);
  pStream->stream = stream;
  pStream->stream->dwError = 0;
  pStream->pos = 0;
  pStream->written = 0;
  pStream->nFontTblLen = 0;
  pStream->nColorTblLen = 1;
  pStream->nNestingLevel = 0;
  memset(&pStream->cur_fmt, 0, sizeof(pStream->cur_fmt));
  pStream->cur_fmt.dwEffects = CFE_AUTOCOLOR | CFE_AUTOBACKCOLOR;
  pStream->cur_fmt.bUnderlineType = CFU_UNDERLINE;
  return pStream;
}


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

  if (pStream->pos) {
    TRACE("sending %u bytes\n", pStream->pos);
    nWritten = pStream->pos;
    stream->dwError = stream->pfnCallback(stream->dwCookie, (LPBYTE)pStream->buffer,
                                          pStream->pos, &nWritten);
    TRACE("error=%u written=%u\n", stream->dwError, nWritten);
    if (nWritten == 0 || stream->dwError)
      return FALSE;
    /* Don't resend partial chunks if nWritten < pStream->pos */
  }
  if (nWritten == pStream->pos)
      pStream->written += nWritten;
  pStream->pos = 0;
  return TRUE;
}


static LONG
ME_StreamOutFree(ME_OutStream *pStream)
{
  LONG written = pStream->written;
  TRACE("total length = %u\n", written);

  FREE_OBJ(pStream);
  return written;
}


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

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


static BOOL
ME_StreamOutPrint(ME_OutStream *pStream, const 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(pStream, string, len);
}

#define HEX_BYTES_PER_LINE 40

static BOOL
ME_StreamOutHexData(ME_OutStream *stream, const BYTE *data, UINT len)
{

    char line[HEX_BYTES_PER_LINE * 2 + 1];
    UINT size, i;
    static const char hex[] = "0123456789abcdef";

    while (len)
    {
        size = min( len, HEX_BYTES_PER_LINE );
        for (i = 0; i < size; i++)
        {
            line[i * 2] = hex[(*data >> 4) & 0xf];
            line[i * 2 + 1] = hex[*data & 0xf];
            data++;
        }
        line[size * 2] = '\n';
        if (!ME_StreamOutMove( stream, line, size * 2 + 1 ))
            return FALSE;
        len -= size;
    }
    return TRUE;
}

static BOOL
ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
{
  const 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";
    /* TODO: If the original document contained an \ansicpg value, retain it.
     * Otherwise, M$ richedit emits a codepage number determined from the
     * charset of the default font here. Anyway, this value is not used by
     * the reader... */
    nCodePage = GetACP();
  }
  if (nCodePage == CP_UTF8)
    success = ME_StreamOutPrint(pStream, "{\\urtf");
  else
    success = ME_StreamOutPrint(pStream, "{\\rtf1\\%s\\ansicpg%u\\uc1", cCharSet, nCodePage);

  if (!success)
    return FALSE;

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

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

  return TRUE;
}

static void add_font_to_fonttbl( ME_OutStream *stream, ME_Style *style )
{
    ME_FontTableItem *table = stream->fonttbl;
    CHARFORMAT2W *fmt = &style->fmt;
    WCHAR *face = fmt->szFaceName;
    BYTE charset = (fmt->dwMask & CFM_CHARSET) ? fmt->bCharSet : DEFAULT_CHARSET;
    int i;

    if (fmt->dwMask & CFM_FACE)
    {
        for (i = 0; i < stream->nFontTblLen; i++)
            if (table[i].bCharSet == charset
                && (table[i].szFaceName == face || !lstrcmpW(table[i].szFaceName, face)))
                break;

        if (i == stream->nFontTblLen && i < STREAMOUT_FONTTBL_SIZE)
        {
            table[i].bCharSet = charset;
            table[i].szFaceName = face;
            stream->nFontTblLen++;
        }
    }
}

static BOOL find_font_in_fonttbl( ME_OutStream *stream, CHARFORMAT2W *fmt, unsigned int *idx )
{
    WCHAR *facename;
    int i;

    *idx = 0;
    if (fmt->dwMask & CFM_FACE)
        facename = fmt->szFaceName;
    else
        facename = stream->fonttbl[0].szFaceName;
    for (i = 0; i < stream->nFontTblLen; i++)
    {
        if (facename == stream->fonttbl[i].szFaceName
            || !lstrcmpW(facename, stream->fonttbl[i].szFaceName))
            if (!(fmt->dwMask & CFM_CHARSET)
                || fmt->bCharSet == stream->fonttbl[i].bCharSet)
            {
                *idx = i;
                break;
            }
    }

    return i < stream->nFontTblLen;
}

static void add_color_to_colortbl( ME_OutStream *stream, COLORREF color )
{
    int i;

    for (i = 1; i < stream->nColorTblLen; i++)
        if (stream->colortbl[i] == color)
            break;

    if (i == stream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE)
    {
        stream->colortbl[i] = color;
        stream->nColorTblLen++;
    }
}

static BOOL find_color_in_colortbl( ME_OutStream *stream, COLORREF color, unsigned int *idx )
{
    int i;

    *idx = 0;
    for (i = 1; i < stream->nColorTblLen; i++)
    {
        if (stream->colortbl[i] == color)
        {
            *idx = i;
            break;
        }
    }

    return i < stream->nFontTblLen;
}

static BOOL
ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun,
                               ME_DisplayItem *pLastRun)
{
  ME_DisplayItem *item = pFirstRun;
  ME_FontTableItem *table = pStream->fonttbl;
  unsigned int i;
  ME_DisplayItem *pCell = NULL;
  ME_Paragraph *prev_para = NULL;

  do {
    CHARFORMAT2W *fmt = &item->member.run.style->fmt;

    add_font_to_fonttbl( pStream, item->member.run.style );

    if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR))
      add_color_to_colortbl( pStream, fmt->crTextColor );
    if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR))
      add_color_to_colortbl( pStream, fmt->crBackColor );

    if (item->member.run.para != prev_para)
    {
      /* check for any para numbering text */
      if (item->member.run.para->fmt.wNumbering)
        add_font_to_fonttbl( pStream, item->member.run.para->para_num.style );

      if ((pCell = item->member.para.pCell))
      {
        ME_Border* borders[4] = { &pCell->member.cell.border.top,
                                  &pCell->member.cell.border.left,
                                  &pCell->member.cell.border.bottom,
                                  &pCell->member.cell.border.right };
        for (i = 0; i < 4; i++)
          if (borders[i]->width > 0)
            add_color_to_colortbl( pStream, borders[i]->colorRef );
      }

      prev_para = item->member.run.para;
    }

    if (item == pLastRun)
      break;
    item = ME_FindItemFwd(item, diRun);
  } while (item);

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

  /* It seems like Open Office ignores \deff0 tag at RTF-header.
     As result it can't correctly parse text before first \fN tag,
     so we can put \f0 immediately after font table. This forces
     parser to use the same font, that \deff0 specifies.
     It makes OOffice happy */
  if (!ME_StreamOutPrint(pStream, "\\f0"))
    return FALSE;

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

  return TRUE;
}

static BOOL
ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream,
                          ME_DisplayItem *para)
{
  ME_DisplayItem *cell;
  char props[STREAMOUT_BUFFER_SIZE] = "";
  int i;
  const char sideChar[4] = {'t','l','b','r'};

  if (!ME_StreamOutPrint(pStream, "\\trowd"))
    return FALSE;
  if (!editor->bEmulateVersion10) { /* v4.1 */
    PARAFORMAT2 *pFmt = &ME_GetTableRowEnd(para)->member.para.fmt;
    para = ME_GetTableRowStart(para);
    cell = para->member.para.next_para->member.para.pCell;
    assert(cell);
    if (pFmt->dxOffset)
      sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset);
    if (pFmt->dxStartIndent)
      sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent);
    do {
      ME_Border* borders[4] = { &cell->member.cell.border.top,
                                &cell->member.cell.border.left,
                                &cell->member.cell.border.bottom,
                                &cell->member.cell.border.right };
      for (i = 0; i < 4; i++)
      {
        if (borders[i]->width)
        {
          unsigned int idx;
          COLORREF crColor = borders[i]->colorRef;
          sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]);
          sprintf(props + strlen(props), "\\brdrs");
          sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
          if (find_color_in_colortbl( pStream, crColor, &idx ))
            sprintf(props + strlen(props), "\\brdrcf%u", idx);
        }
      }
      sprintf(props + strlen(props), "\\cellx%d", cell->member.cell.nRightBoundary);
      cell = cell->member.cell.next_cell;
    } while (cell->member.cell.next_cell);
  } else { /* v1.0 - 3.0 */
    const ME_Border* borders[4] = { &para->member.para.border.top,
                                    &para->member.para.border.left,
                                    &para->member.para.border.bottom,
                                    &para->member.para.border.right };
    PARAFORMAT2 *pFmt = &para->member.para.fmt;

    assert(!(para->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)));
    if (pFmt->dxOffset)
      sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset);
    if (pFmt->dxStartIndent)
      sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent);
    for (i = 0; i < 4; i++)
    {
      if (borders[i]->width)
      {
        unsigned int idx;
        COLORREF crColor = borders[i]->colorRef;
        sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]);
        sprintf(props + strlen(props), "\\brdrs");
        sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
        if (find_color_in_colortbl( pStream, crColor, &idx ))
          sprintf(props + strlen(props), "\\brdrcf%u", idx);
      }
    }
    for (i = 0; i < pFmt->cTabCount; i++)
    {
      sprintf(props + strlen(props), "\\cellx%d", pFmt->rgxTabs[i] & 0x00FFFFFF);
    }
  }
  if (!ME_StreamOutPrint(pStream, props))
    return FALSE;
  props[0] = '\0';
  return TRUE;
}

static BOOL stream_out_para_num( ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest )
{
    static const char fmt_label[] = "{\\*\\pn\\pnlvlbody\\pnf%u\\pnindent%d\\pnstart%d%s%s}";
    static const char fmt_bullet[] = "{\\*\\pn\\pnlvlblt\\pnf%u\\pnindent%d{\\pntxtb\\'b7}}";
    static const char dec[] = "\\pndec";
    static const char lcltr[] = "\\pnlcltr";
    static const char ucltr[] = "\\pnucltr";
    static const char lcrm[] = "\\pnlcrm";
    static const char ucrm[] = "\\pnucrm";
    static const char period[] = "{\\pntxta.}";
    static const char paren[] = "{\\pntxta)}";
    static const char parens[] = "{\\pntxtb(}{\\pntxta)}";
    const char *type, *style = "";
    unsigned int idx;

    find_font_in_fonttbl( stream, &para->para_num.style->fmt, &idx );

    if (!ME_StreamOutPrint( stream, "{\\pntext\\f%u ", idx )) return FALSE;
    if (!ME_StreamOutRTFText( stream, para->para_num.text->szData, para->para_num.text->nLen ))
        return FALSE;
    if (!ME_StreamOutPrint( stream, "\\tab}" )) return FALSE;

    if (!pn_dest) return TRUE;

    if (para->fmt.wNumbering == PFN_BULLET)
    {
        if (!ME_StreamOutPrint( stream, fmt_bullet, idx, para->fmt.wNumberingTab ))
            return FALSE;
    }
    else
    {
        switch (para->fmt.wNumbering)
        {
        case PFN_ARABIC:
        default:
            type = dec;
            break;
        case PFN_LCLETTER:
            type = lcltr;
            break;
        case PFN_UCLETTER:
            type = ucltr;
            break;
        case PFN_LCROMAN:
            type = lcrm;
            break;
        case PFN_UCROMAN:
            type = ucrm;
            break;
        }
        switch (para->fmt.wNumberingStyle & 0xf00)
        {
        case PFNS_PERIOD:
            style = period;
            break;
        case PFNS_PAREN:
            style = paren;
            break;
        case PFNS_PARENS:
            style = parens;
            break;
        }

        if (!ME_StreamOutPrint( stream, fmt_label, idx, para->fmt.wNumberingTab,
                                para->fmt.wNumberingStart, type, style ))
            return FALSE;
    }
    return TRUE;
}

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

  if (para->member.para.prev_para->type == diParagraph)
      prev_para = &para->member.para.prev_para->member.para;

  if (!editor->bEmulateVersion10) { /* v4.1 */
    if (para->member.para.nFlags & MEPF_ROWSTART) {
      pStream->nNestingLevel++;
      if (pStream->nNestingLevel == 1) {
        if (!ME_StreamOutRTFTableProps(editor, pStream, para))
          return FALSE;
      }
      return TRUE;
    } else if (para->member.para.nFlags & MEPF_ROWEND) {
      pStream->nNestingLevel--;
      if (pStream->nNestingLevel >= 1) {
        if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
          return FALSE;
        if (!ME_StreamOutRTFTableProps(editor, pStream, para))
          return FALSE;
        if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
          return FALSE;
      } else {
        if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
          return FALSE;
      }
      return TRUE;
    }
  } else { /* v1.0 - 3.0 */
    if (para->member.para.fmt.dwMask & PFM_TABLE &&
        para->member.para.fmt.wEffects & PFE_TABLE)
    {
      if (!ME_StreamOutRTFTableProps(editor, pStream, para))
        return FALSE;
    }
  }

  if (prev_para && !memcmp( fmt, &prev_para->fmt, sizeof(*fmt) ))
  {
    if (fmt->wNumbering)
      return stream_out_para_num( pStream, &para->member.para, FALSE );
    return TRUE;
  }

  if (!ME_StreamOutPrint(pStream, "\\pard"))
    return FALSE;

  if (fmt->wNumbering)
    if (!stream_out_para_num( pStream, &para->member.para, TRUE )) return FALSE;

  if (!editor->bEmulateVersion10) { /* v4.1 */
    if (pStream->nNestingLevel > 0)
      strcat(props, "\\intbl");
    if (pStream->nNestingLevel > 1)
      sprintf(props + strlen(props), "\\itap%d", pStream->nNestingLevel);
  } else { /* v1.0 - 3.0 */
    if (fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE)
      strcat(props, "\\intbl");
  }

  /* 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%d\\slmult0", fmt->dyLineSpacing);
        break;
      case 4:
        sprintf(props + strlen(props), "\\sl-%d\\slmult0", fmt->dyLineSpacing);
        break;
      case 5:
        sprintf(props + strlen(props), "\\sl-%d\\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 (!(editor->bEmulateVersion10 && /* v1.0 - 3.0 */
        fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE))
  {
    if (fmt->dxOffset)
      sprintf(props + strlen(props), "\\li%d", fmt->dxOffset);
    if (fmt->dxStartIndent)
      sprintf(props + strlen(props), "\\fi%d", fmt->dxStartIndent);
    if (fmt->dxRightIndent)
      sprintf(props + strlen(props), "\\ri%d", fmt->dxRightIndent);
    if (fmt->dwMask & PFM_TABSTOPS) {
      static const char * const 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]);
        sprintf(props+strlen(props), "\\tx%d", fmt->rgxTabs[i]&0x00FFFFFF);
      }
    }
  }
  if (fmt->dySpaceAfter)
    sprintf(props + strlen(props), "\\sa%d", fmt->dySpaceAfter);
  if (fmt->dySpaceBefore)
    sprintf(props + strlen(props), "\\sb%d", fmt->dySpaceBefore);
  if (fmt->sStyle != -1)
    sprintf(props + strlen(props), "\\s%d", fmt->sStyle);
  
  if (fmt->dwMask & PFM_SHADING) {
    static const char * const 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)
    strcat(props, " ");
  
  if (*props && !ME_StreamOutPrint(pStream, props))
    return FALSE;

  return TRUE;
}


static BOOL
ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
{
  char props[STREAMOUT_BUFFER_SIZE] = "";
  unsigned int i;
  CHARFORMAT2W *old_fmt = &pStream->cur_fmt;
  static const struct
  {
      DWORD effect;
      const char *on, *off;
  } effects[] =
  {
      { CFE_ALLCAPS,     "\\caps",     "\\caps0"     },
      { CFE_BOLD,        "\\b",        "\\b0"        },
      { CFE_DISABLED,    "\\disabled", "\\disabled0" },
      { CFE_EMBOSS,      "\\embo",     "\\embo0"     },
      { CFE_HIDDEN,      "\\v",        "\\v0"        },
      { CFE_IMPRINT,     "\\impr",     "\\impr0"     },
      { CFE_ITALIC,      "\\i",        "\\i0"        },
      { CFE_OUTLINE,     "\\outl",     "\\outl0"     },
      { CFE_PROTECTED,   "\\protect",  "\\protect0"  },
      { CFE_SHADOW,      "\\shad",     "\\shad0"     },
      { CFE_SMALLCAPS,   "\\scaps",    "\\scaps0"    },
      { CFE_STRIKEOUT,   "\\strike",   "\\strike0"   },
  };

  for (i = 0; i < sizeof(effects) / sizeof(effects[0]); i++)
  {
      if ((old_fmt->dwEffects ^ fmt->dwEffects) & effects[i].effect)
          strcat( props, fmt->dwEffects & effects[i].effect ? effects[i].on : effects[i].off );
  }

  if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOBACKCOLOR ||
      old_fmt->crBackColor != fmt->crBackColor)
  {
      if (fmt->dwEffects & CFE_AUTOBACKCOLOR) i = 0;
      else find_color_in_colortbl( pStream, fmt->crBackColor, &i );
      sprintf(props + strlen(props), "\\cb%u", i);
  }
  if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOCOLOR ||
      old_fmt->crTextColor != fmt->crTextColor)
  {
      if (fmt->dwEffects & CFE_AUTOCOLOR) i = 0;
      else find_color_in_colortbl( pStream, fmt->crTextColor, &i );
      sprintf(props + strlen(props), "\\cf%u", i);
  }

  if (old_fmt->bAnimation != fmt->bAnimation)
    sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation);
  if (old_fmt->wKerning != fmt->wKerning)
    sprintf(props + strlen(props), "\\kerning%u", fmt->wKerning);

  if (old_fmt->lcid != fmt->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));
  }

  if (old_fmt->yOffset != fmt->yOffset)
  {
    if (fmt->yOffset >= 0)
      sprintf(props + strlen(props), "\\up%d", fmt->yOffset);
    else
      sprintf(props + strlen(props), "\\dn%d", -fmt->yOffset);
  }
  if (old_fmt->yHeight != fmt->yHeight)
    sprintf(props + strlen(props), "\\fs%d", fmt->yHeight / 10);
  if (old_fmt->sSpacing != fmt->sSpacing)
    sprintf(props + strlen(props), "\\expnd%u\\expndtw%u", fmt->sSpacing / 5, fmt->sSpacing);
  if ((old_fmt->dwEffects ^ fmt->dwEffects) & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT))
  {
    if (fmt->dwEffects & CFE_SUBSCRIPT)
      strcat(props, "\\sub");
    else if (fmt->dwEffects & CFE_SUPERSCRIPT)
      strcat(props, "\\super");
    else
      strcat(props, "\\nosupersub");
  }
  if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_UNDERLINE ||
      old_fmt->bUnderlineType != fmt->bUnderlineType)
  {
      BYTE type = (fmt->dwEffects & CFE_UNDERLINE) ? fmt->bUnderlineType : CFU_UNDERLINENONE;
      switch (type)
      {
      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_CF1UNDERLINE:
      case CFU_UNDERLINENONE:
      default:
          strcat(props, "\\ulnone");
          break;
      }
  }
  
  if (strcmpW(old_fmt->szFaceName, fmt->szFaceName) ||
      old_fmt->bCharSet != fmt->bCharSet)
  {
    if (find_font_in_fonttbl( pStream, fmt, &i ))
    {
      sprintf(props + strlen(props), "\\f%u", i);

      /* In UTF-8 mode, charsets/codepages are not used */
      if (pStream->nDefaultCodePage != CP_UTF8)
      {
        if (pStream->fonttbl[i].bCharSet == DEFAULT_CHARSET)
          pStream->nCodePage = pStream->nDefaultCodePage;
        else
          pStream->nCodePage = RTFCharSetToCodePage(NULL, pStream->fonttbl[i].bCharSet);
      }
    }
  }
  if (*props)
    strcat(props, " ");
  if (!ME_StreamOutPrint(pStream, props))
    return FALSE;
  *old_fmt = *fmt;
  return TRUE;
}


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

  if (nChars == -1)
    nChars = lstrlenW(text);
  
  while (nChars) {
    /* In UTF-8 mode, font charsets are not used. */
    if (pStream->nDefaultCodePage == CP_UTF8) {
      /* 6 is the maximum character length in UTF-8 */
      fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
      nBytes = WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer,
                                   STREAMOUT_BUFFER_SIZE, NULL, NULL);
      nChars -= fit;
      text += fit;
      for (i = 0; i < nBytes; i++)
        if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
          if (!ME_StreamOutPrint(pStream, "%.*s\\", i - pos, buffer + pos))
            return FALSE;
          pos = i;
        }
      if (pos < nBytes)
        if (!ME_StreamOutMove(pStream, buffer + pos, nBytes - pos))
          return FALSE;
      pos = 0;
    } else if (*text < 128) {
      if (*text == '{' || *text == '}' || *text == '\\')
        buffer[pos++] = '\\';
      buffer[pos++] = (char)(*text++);
      nChars--;
    } else {
      BOOL unknown = FALSE;
      char letter[3];

      /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of
       * codepages including CP_SYMBOL for which the last parameter must be set
       * to NULL for the function to succeed. But in Wine we need to care only
       * about CP_SYMBOL */
      nBytes = WideCharToMultiByte(pStream->nCodePage, 0, text, 1,
                                   letter, 3, NULL,
                                   (pStream->nCodePage == CP_SYMBOL) ? NULL : &unknown);
      if (unknown)
        pos += sprintf(buffer + pos, "\\u%d?", (short)*text);
      else if ((BYTE)*letter < 128) {
        if (*letter == '{' || *letter == '}' || *letter == '\\')
          buffer[pos++] = '\\';
        buffer[pos++] = *letter;
      } else {
         for (i = 0; i < nBytes; i++)
           pos += sprintf(buffer + pos, "\\'%02x", (BYTE)letter[i]);
      }
      text++;
      nChars--;
    }
    if (pos >= STREAMOUT_BUFFER_SIZE - 11) {
      if (!ME_StreamOutMove(pStream, buffer, pos))
        return FALSE;
      pos = 0;
    }
  }
  return ME_StreamOutMove(pStream, buffer, pos);
}

static BOOL stream_out_graphics( ME_TextEditor *editor, ME_OutStream *stream,
                                 ME_Run *run )
{
    IDataObject *data;
    HRESULT hr;
    FORMATETC fmt = { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF };
    STGMEDIUM med = { TYMED_NULL };
    BOOL ret = FALSE;
    ENHMETAHEADER *emf_bits = NULL;
    UINT size;
    SIZE goal, pic;
    ME_Context c;

    hr = IOleObject_QueryInterface( run->ole_obj->poleobj, &IID_IDataObject, (void **)&data );
    if (FAILED(hr)) return FALSE;

    ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) );
    hr = IDataObject_QueryGetData( data, &fmt );
    if (hr != S_OK) goto done;

    hr = IDataObject_GetData( data, &fmt, &med );
    if (FAILED(hr)) goto done;
    if (med.tymed != TYMED_ENHMF) goto done;

    size = GetEnhMetaFileBits( med.u.hEnhMetaFile, 0, NULL );
    if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;

    emf_bits = HeapAlloc( GetProcessHeap(), 0, size );
    if (!emf_bits) goto done;

    size = GetEnhMetaFileBits( med.u.hEnhMetaFile, size, (BYTE *)emf_bits );
    if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;

    /* size_in_pixels = (frame_size / 100) * szlDevice / szlMillimeters
       pic = size_in_pixels * 2540 / dpi */
    pic.cx = MulDiv( emf_bits->rclFrame.right - emf_bits->rclFrame.left, emf_bits->szlDevice.cx * 254,
                     emf_bits->szlMillimeters.cx * c.dpi.cx * 10 );
    pic.cy = MulDiv( emf_bits->rclFrame.bottom - emf_bits->rclFrame.top, emf_bits->szlDevice.cy * 254,
                     emf_bits->szlMillimeters.cy * c.dpi.cy * 10 );

    /* convert goal size to twips */
    goal.cx = MulDiv( run->ole_obj->sizel.cx, 144, 254 );
    goal.cy = MulDiv( run->ole_obj->sizel.cy, 144, 254 );

    if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n",
                            pic.cx, pic.cy, goal.cx, goal.cy ))
        goto done;

    if (!ME_StreamOutHexData( stream, (BYTE *)emf_bits, size ))
        goto done;

    if (!ME_StreamOutPrint( stream, "}}\n" ))
        goto done;

    ret = TRUE;

done:
    ME_DestroyContext( &c );
    HeapFree( GetProcessHeap(), 0, emf_bits );
    ReleaseStgMedium( &med );
    IDataObject_Release( data );
    return ret;
}

static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream,
                            const ME_Cursor *start, int nChars, int dwFormat)
{
  ME_Cursor cursor = *start;
  ME_DisplayItem *prev_para = NULL;
  ME_Cursor endCur = cursor;

  ME_MoveCursorChars(editor, &endCur, nChars, TRUE);

  if (!ME_StreamOutRTFHeader(pStream, dwFormat))
    return FALSE;

  if (!ME_StreamOutRTFFontAndColorTbl(pStream, cursor.pRun, endCur.pRun))
    return FALSE;

  /* TODO: stylesheet table */

  if (!ME_StreamOutPrint(pStream, "{\\*\\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 */

  do {
    if (cursor.pPara != prev_para)
    {
      prev_para = cursor.pPara;
      if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara))
        return FALSE;
    }

    if (cursor.pRun == endCur.pRun && !endCur.nOffset)
      break;
    TRACE("flags %xh\n", cursor.pRun->member.run.nFlags);
    /* TODO: emit embedded objects */
    if (cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
      continue;
    if (cursor.pRun->member.run.nFlags & MERF_GRAPHICS) {
      if (!stream_out_graphics(editor, pStream, &cursor.pRun->member.run))
        return FALSE;
    } else if (cursor.pRun->member.run.nFlags & MERF_TAB) {
      if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
          cursor.pPara->member.para.fmt.dwMask & PFM_TABLE &&
          cursor.pPara->member.para.fmt.wEffects & PFE_TABLE)
      {
        if (!ME_StreamOutPrint(pStream, "\\cell "))
          return FALSE;
      } else {
        if (!ME_StreamOutPrint(pStream, "\\tab "))
          return FALSE;
      }
    } else if (cursor.pRun->member.run.nFlags & MERF_ENDCELL) {
      if (pStream->nNestingLevel > 1) {
        if (!ME_StreamOutPrint(pStream, "\\nestcell "))
          return FALSE;
      } else {
        if (!ME_StreamOutPrint(pStream, "\\cell "))
          return FALSE;
      }
      nChars--;
    } else if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) {
      if (cursor.pPara->member.para.fmt.dwMask & PFM_TABLE &&
          cursor.pPara->member.para.fmt.wEffects & PFE_TABLE &&
          !(cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)))
      {
        if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
          return FALSE;
      } else {
        if (!ME_StreamOutPrint(pStream, "\\par\r\n"))
          return FALSE;
      }
      /* Skip as many characters as required by current line break */
      nChars = max(0, nChars - cursor.pRun->member.run.len);
    } else if (cursor.pRun->member.run.nFlags & MERF_ENDROW) {
      if (!ME_StreamOutPrint(pStream, "\\line\r\n"))
        return FALSE;
      nChars--;
    } else {
      int nEnd;

      TRACE("style %p\n", cursor.pRun->member.run.style);
      if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt))
        return FALSE;

      nEnd = (cursor.pRun == endCur.pRun) ? endCur.nOffset : cursor.pRun->member.run.len;
      if (!ME_StreamOutRTFText(pStream, get_text( &cursor.pRun->member.run, cursor.nOffset ),
                               nEnd - cursor.nOffset))
        return FALSE;
      cursor.nOffset = 0;
    }
  } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE));

  if (!ME_StreamOutMove(pStream, "}\0", 2))
    return FALSE;
  return TRUE;
}


static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream,
                             const ME_Cursor *start, int nChars, DWORD dwFormat)
{
  ME_Cursor cursor = *start;
  int nLen;
  UINT nCodePage = CP_ACP;
  char *buffer = NULL;
  int nBufLen = 0;
  BOOL success = TRUE;

  if (!cursor.pRun)
    return FALSE;

  if (dwFormat & SF_USECODEPAGE)
    nCodePage = HIWORD(dwFormat);

  /* TODO: Handle SF_TEXTIZED */

  while (success && nChars && cursor.pRun) {
    nLen = min(nChars, cursor.pRun->member.run.len - cursor.nOffset);

    if (!editor->bEmulateVersion10 && cursor.pRun->member.run.nFlags & MERF_ENDPARA)
    {
      static const WCHAR szEOL[] = { '\r', '\n' };

      /* richedit 2.0 - all line breaks are \r\n */
      if (dwFormat & SF_UNICODE)
        success = ME_StreamOutMove(pStream, (const char *)szEOL, sizeof(szEOL));
      else
        success = ME_StreamOutMove(pStream, "\r\n", 2);
    } else {
      if (dwFormat & SF_UNICODE)
        success = ME_StreamOutMove(pStream, (const char *)(get_text( &cursor.pRun->member.run, cursor.nOffset )),
                                   sizeof(WCHAR) * nLen);
      else {
        int nSize;

        nSize = WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ),
                                    nLen, NULL, 0, NULL, NULL);
        if (nSize > nBufLen) {
          FREE_OBJ(buffer);
          buffer = ALLOC_N_OBJ(char, nSize);
          nBufLen = nSize;
        }
        WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ),
                            nLen, buffer, nSize, NULL, NULL);
        success = ME_StreamOutMove(pStream, buffer, nSize);
      }
    }

    nChars -= nLen;
    cursor.nOffset = 0;
    cursor.pRun = ME_FindItemFwd(cursor.pRun, diRun);
  }

  FREE_OBJ(buffer);
  return success;
}


LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat,
                          const ME_Cursor *start,
                          int nChars, EDITSTREAM *stream)
{
  ME_OutStream *pStream = ME_StreamOutInit(editor, stream);

  if (dwFormat & SF_RTF)
    ME_StreamOutRTF(editor, pStream, start, nChars, dwFormat);
  else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
    ME_StreamOutText(editor, pStream, start, nChars, dwFormat);
  if (!pStream->stream->dwError)
    ME_StreamOutFlush(pStream);
  return ME_StreamOutFree(pStream);
}

LRESULT
ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
{
  ME_Cursor start;
  int nChars;

  if (dwFormat & SFF_SELECTION) {
    int nStart, nTo;
    start = editor->pCursors[ME_GetSelectionOfs(editor, &nStart, &nTo)];
    nChars = nTo - nStart;
  } else {
    ME_SetCursorToStart(editor, &start);
    nChars = ME_GetTextLength(editor);
    /* Generate an end-of-paragraph at the end of SCF_ALL RTF output */
    if (dwFormat & SF_RTF)
      nChars++;
  }
  return ME_StreamOutRange(editor, dwFormat, &start, nChars, stream);
}
