/*
 * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include "synrtfexporter.h"

SynRTFExporter::SynRTFExporter():SynExporter()
{
    mDefaultFilter = "Rich Text Format Documents (*.rtf)|*.rtf";
    mClipboardFormat = "application/x-qt-windows-mime;value=\"Rich Format Text\"";
    //mClipboardFormat = "Rich Format Text";
    // setup array of chars to be replaced
    mReplaceReserved['\\'] = "\\\\";
    mReplaceReserved['{'] = "\\{";
    mReplaceReserved['}'] = "\\}";

}

QString SynRTFExporter::ColorToRTF(const QColor &AColor) const
{
    return QString("\\red%1\\green%2\\blue%3;")
            .arg(AColor.red())
            .arg(AColor.green())
            .arg(AColor.blue());
}

int SynRTFExporter::GetColorIndex(const QColor &AColor)
{
    int index = mListColors.indexOf(AColor);
    if (index<0) {
        mListColors.append(AColor);
        index = mListColors.length()-1;
    }
    return index;
}

QString SynRTFExporter::GetFontTable()
{
    QString Result = "{\\fonttbl{\\f0\\fmodern\\fcharset134 "
        + ReplaceReservedChars(mFont.family());
    Result = Result + ";}}" + lineBreak();
    return Result;
}

void SynRTFExporter::FormatAttributeDone(bool , bool , SynFontStyles FontStylesChanged)
{
    // nothing to do about the color, but reset the font style
    if (FontStylesChanged.testFlag(SynFontStyle::fsBold)) {
        mAttributesChanged = true;
        AddData("\\b0");
    }
    if (FontStylesChanged.testFlag(SynFontStyle::fsItalic)) {
        mAttributesChanged = true;
        AddData("\\i0");
    }
    if (FontStylesChanged.testFlag(SynFontStyle::fsUnderline)) {
        mAttributesChanged = true;
        AddData("\\ul0");
    }
    if (FontStylesChanged.testFlag(SynFontStyle::fsStrikeOut)) {
        mAttributesChanged = true;
        AddData("\\strike0");
    }
}

void SynRTFExporter::FormatAttributeInit(bool BackgroundChanged, bool ForegroundChanged, SynFontStyles FontStylesChanged)
{
    // background color
    if (BackgroundChanged) {
        AddData(QString("\\chshdng0\\chcbpat%1\\cb%2\\highlight%3 ")
              .arg(GetColorIndex(mLastBG))
              .arg(GetColorIndex(mLastBG))
              .arg(GetColorIndex(mLastBG)));
        mAttributesChanged = true;
    }
    // text color
    if (ForegroundChanged) {
        AddData(QString("\\cf%1").arg(GetColorIndex(mLastFG)));
        mAttributesChanged = true;
    }
    // font styles
    // nothing to do about the color, but reset the font style
    if (FontStylesChanged.testFlag(SynFontStyle::fsBold)) {
        mAttributesChanged = true;
        AddData("\\b0");
    }
    if (FontStylesChanged.testFlag(SynFontStyle::fsItalic)) {
        mAttributesChanged = true;
        AddData("\\i0");
    }
    if (FontStylesChanged.testFlag(SynFontStyle::fsUnderline)) {
        mAttributesChanged = true;
        AddData("\\ul0");
    }
    if (FontStylesChanged.testFlag(SynFontStyle::fsStrikeOut)) {
        mAttributesChanged = true;
        AddData("\\strike0");
    }
    if (mAttributesChanged) {
        AddData(" ");
        mAttributesChanged = false;
    }
}

void SynRTFExporter::FormatAfterLastAttribute()
{
    // no need to reset the font style here...
}

void SynRTFExporter::FormatBeforeFirstAttribute(bool BackgroundChanged, bool ForegroundChanged, SynFontStyles FontStylesChanged)
{
    FormatAttributeInit(BackgroundChanged, ForegroundChanged, FontStylesChanged);
}

void SynRTFExporter::FormatNewLine()
{
    AddNewLine();
    AddData("\\par ");
}

QString SynRTFExporter::GetFooter()
{
    return "}";
}

QString SynRTFExporter::GetFormatName()
{
    return "RTF";
}

QString SynRTFExporter::GetHeader()
{
    QString Result = "{\\rtf1\\ansi\\deff0\\deftab720" + GetFontTable();
    // all the colors
    Result = Result + "{\\colortbl";
    for (int i = 0; i<mListColors.count();i++) {
        Result = Result + ColorToRTF(mListColors[i]);
    }
    Result = Result + ColorToRTF(mBackgroundColor);
    Result = Result + "}" + lineBreak();
    // title and creator comment
    Result = Result + "{\\info{\\comment Generated by the QSynEdit RTF " +
        "exporter}" + lineBreak();
    Result = Result + "{\\title " + mTitle + "}}" + lineBreak();
//    if (mUseBackground)
//        Result = Result + { TODO } #13#10;
    Result = Result + QString("\\deflang1033\\pard\\plain\\f0\\fs%1 ").arg((int)(2 * pixelToPoint(mFont.pixelSize())));
    if (mUseBackground)
        Result = Result + QString("\\chshdng0\\chcbpat%1\\cb%2\\highlight%3 ")
                .arg(GetColorIndex(mLastBG))
                .arg(GetColorIndex(mBackgroundColor))
                .arg(GetColorIndex(mBackgroundColor));
    return Result;
}