#include "etext.h"
#include "base/locolorselector.h"
#include "cfg.h"
#include "globaldefine.h"
#include "tools.h"
#include <QBoxLayout>
#include <QButtonGroup>
#include <QCheckBox>
#include <QFontComboBox>
#include <QJsonArray>
#include <QLabel>
#include <QSpinBox>
#include <QMessageBox>
#include <QRadioButton>
#include <QStackedLayout>
#include <QThread>
#include <QTimeEdit>
#include <QTextCodec>

EText::EText(EBase *multiWin) : EBase(multiWin) {
    mType = EBase::Text;
    m_attr.text = tr("Enter your text");
    m_attr.cBackground = Qt::transparent;
    m_attr.opt.setAlignment(Qt::AlignCenter);
    m_attr.opt.setWrapMode(QTextOption::WrapAnywhere);
    //Play
    m_attr.playStyle = Flip;
    m_attr.rolling.headTailConnected = true;
    m_attr.rolling.headTailSpacing   = 10;
    m_attr.rolling.rollingSpeed      = 50;
    m_attr.rolling.rollingStyle      = Left2Right;
    m_attr.rolling.playDuration      = 30;
    connect(this, SIGNAL(sizeChanged()), this, SLOT(RefreshBigPixmap()));
    RefreshBigPixmap();
}
EText::EText(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
    mType = EBase::Text;
    setBaseAttr(json);
    setElement(json, m_attr);
    connect(this, SIGNAL(sizeChanged()), this, SLOT(RefreshBigPixmap()));
    RefreshBigPixmap();
}

void EText::setElement(const QJsonObject &json, Data &attr) {
    auto widget = json["widget"];
    attr.text          = widget["text"].toString();
    attr.lineSpacing   = widget["lineSpacing"].toInt();
    attr.letterSpacing = widget["wordSpacing"].toInt();
    attr.opt.setAlignment(static_cast<Qt::Alignment>(widget["align"].toInt()));
    attr.cBackground   = Tools::int2Color(widget["cBackground"].toInt());
    attr.iPageCount    = widget["iPageCount"].toInt();
    auto play = json["play"];
    attr.playStyle = play["style"].toInt();
    auto turning = play["turning"];
    attr.turning.effect = turning["strEffect"].toString();
    attr.turning.pageDuration = turning["iEffectTime"].toInt();
    attr.turning.effectDuration = turning["iEffectSpeed"].toInt();
    attr.turning.playDuration = turning["playDuration"].toInt();
    auto rolling = play["rolling"];
    attr.rolling.rollingStyle = rolling["rollingStyle"].toInt();
    attr.rolling.rollingSpeed = rolling["rollingSpeed"].toInt();
    attr.rolling.headTailConnected = rolling["headTailConnected"].toBool();
    attr.rolling.headTailSpacing = rolling["headTailSpacing"].toInt();
    attr.rolling.playDuration = rolling["playDuration"].toInt();
    attr.playDuration = play["static"]["playDuration"].toInt();
}

class TTextEdit : public QTextEdit {
public:
    explicit TTextEdit(const QString &text) : QTextEdit(text){}
    QSize minimumSizeHint() const override {
        return sizeHint();
    };
    QSize sizeHint() const override {
        auto size = QTextEdit::sizeHint();
        auto minH = minimumHeight();
        if(minH > 0) size.setHeight(minH+0xfff);
        return size;
    };
};
QWidget* EText::attrWgt() {
    auto wgtAttr = new QWidget;
    auto vBox = new QVBoxLayout(wgtAttr);
    vBox->setContentsMargins(4, 0, 4, 0);
    vBox->setSpacing(3);

    addBaseAttrWgt(vBox);

    auto hBox = new QHBoxLayout;
    hBox->addWidget(new QLabel(tr("Basic Properties")));

    auto line = new QFrame;
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    hBox->addWidget(line, 1);

    vBox->addLayout(hBox);

    hBox = new QHBoxLayout;

    auto fdText = new TTextEdit(m_attr.text);

    auto fdFontFamily = new QFontComboBox;
    fdFontFamily->setEditable(false);
    connect(fdFontFamily, &QFontComboBox::currentFontChanged, fdText, [fdText](const QFont &f) {
        QTextCharFormat fmt;
        fmt.setFontFamily(f.family());
        Tools::mergeFormat(fdText, fmt);
    });
    hBox->addWidget(fdFontFamily);

    hBox->addStretch();

    auto fdFontSize = new QSpinBox;
    fdFontSize->setRange(4, 9999);
    fdFontSize->setValue(16);
    connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, fdText, [fdText](int value) {
        if(value <= 0) return;
        QTextCharFormat fmt;
        fmt.setProperty(QTextFormat::FontPixelSize, value);
        Tools::mergeFormat(fdText, fmt);
    });
    hBox->addWidget(fdFontSize);

    vBox->addLayout(hBox);

    hBox = new QHBoxLayout;
    hBox->setSpacing(3);

    auto wTextAlignHL = new QPushButton();
    wTextAlignHL->setFixedSize(QSize(24, 24));
    wTextAlignHL->setIconSize(QSize(24, 24));
    QIcon icon3(":/res/ProgramManager/EditProgram/DocAlignHL_u.png");
    icon3.addFile(":/res/ProgramManager/EditProgram/DocAlignHL_s.png", QSize(), QIcon::Normal, QIcon::On);
    wTextAlignHL->setIcon(icon3);
    wTextAlignHL->setFlat(true);
    wTextAlignHL->setCheckable(true);
    wTextAlignHL->setChecked(true);
    hBox->addWidget(wTextAlignHL);

    auto wTextAlignHC = new QPushButton();
    wTextAlignHC->setFixedSize(QSize(24, 24));
    wTextAlignHC->setIconSize(QSize(24, 24));
    QIcon icon4(":/res/ProgramManager/EditProgram/DocAlignHC_u.png");
    icon4.addFile(":/res/ProgramManager/EditProgram/DocAlignHC_s.png", QSize(), QIcon::Normal, QIcon::On);
    wTextAlignHC->setIcon(icon4);
    wTextAlignHC->setFlat(true);
    wTextAlignHC->setCheckable(true);
    hBox->addWidget(wTextAlignHC);

    auto wTextAlignHR = new QPushButton();
    wTextAlignHR->setFixedSize(QSize(24, 24));
    wTextAlignHR->setIconSize(QSize(24, 24));
    QIcon icon5(":/res/ProgramManager/EditProgram/DocAlignHR_u.png");
    icon5.addFile(":/res/ProgramManager/EditProgram/DocAlignHR_s.png", QSize(), QIcon::Normal, QIcon::On);
    wTextAlignHR->setIcon(icon5);
    wTextAlignHR->setFlat(true);
    wTextAlignHR->setCheckable(true);
    hBox->addWidget(wTextAlignHR);

    hBox->addStretch();

    auto wFontBold = new QPushButton;
    wFontBold->setFixedSize(QSize(24, 24));
    wFontBold->setIconSize(QSize(24, 24));
    QIcon icon(":/res/ProgramManager/EditProgram/FontBold_u.png");
    icon.addFile(":/res/ProgramManager/EditProgram/FontBold_s.png", QSize(), QIcon::Normal, QIcon::On);
    wFontBold->setIcon(icon);
    wFontBold->setFlat(true);
    wFontBold->setCheckable(true);
    connect(wFontBold, &QPushButton::toggled, fdText, [fdText](bool checked) {
        QTextCharFormat fmt;
        fmt.setFontWeight(checked ? QFont::Bold : QFont::Normal);
        Tools::mergeFormat(fdText, fmt);
    });
    hBox->addWidget(wFontBold);

    auto fdFontItalic = new QPushButton;
    fdFontItalic->setFixedSize(24, 24);
    fdFontItalic->setIconSize(QSize(24, 24));
    icon = QIcon(":/res/ProgramManager/EditProgram/FontItalics_u.png");
    icon.addFile(":/res/ProgramManager/EditProgram/FontItalics_s.png", QSize(), QIcon::Normal, QIcon::On);
    fdFontItalic->setIcon(icon);
    fdFontItalic->setFlat(true);
    fdFontItalic->setCheckable(true);
    connect(fdFontItalic, &QPushButton::toggled, fdText, [fdText](bool checked) {
        QTextCharFormat fmt;
        fmt.setFontItalic(checked);
        Tools::mergeFormat(fdText, fmt);
    });
    hBox->addWidget(fdFontItalic);

    auto wFontUnderline = new QPushButton;
    wFontUnderline->setFixedSize(24, 24);
    wFontUnderline->setIconSize(QSize(24, 24));
    icon = QIcon(":/res/ProgramManager/EditProgram/FontUnderline_u.png");
    icon.addFile(":/res/ProgramManager/EditProgram/FontUnderline_s.png", QSize(), QIcon::Normal, QIcon::On);
    wFontUnderline->setIcon(icon);
    wFontUnderline->setFlat(true);
    wFontUnderline->setCheckable(true);
    connect(wFontUnderline, &QPushButton::toggled, fdText, [fdText](bool checked) {
        QTextCharFormat fmt;
        fmt.setFontUnderline(checked);
        Tools::mergeFormat(fdText, fmt);
    });
    hBox->addWidget(wFontUnderline);

    hBox->addStretch();

    auto fdTextColor = new LoColorSelector(tr("Font Color"), Qt::white);
    fdTextColor->setFixedHeight(24);
    connect(fdTextColor, &LoColorSelector::sColorChanged, fdText, [fdText](const QColor &color) {
        if(! color.isValid()) return;
        QTextCharFormat fmt;
        fmt.setForeground(color);
        Tools::mergeFormat(fdText, fmt);
    });
    hBox->addWidget(fdTextColor);

    auto fdBackColor = new LoColorSelector(tr("Back Color"), m_attr.cBackground);
    fdBackColor->setFixedHeight(24);
    connect(fdBackColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) {
        if(! color.isValid()) return;
        m_attr.cBackground = color;
        update();
        RefreshBigPixmap();
    });
    hBox->addWidget(fdBackColor);

    vBox->addLayout(hBox);

    hBox = new QHBoxLayout;
    hBox->setSpacing(3);

    auto wTextAlignVT = new QPushButton;
    wTextAlignVT->setFixedSize(QSize(24, 24));
    wTextAlignVT->setIconSize(QSize(24, 24));
    QIcon icon6(":/res/ProgramManager/EditProgram/DocAlignVT_u.png");
    icon6.addFile(":/res/ProgramManager/EditProgram/DocAlignVT_s.png", QSize(), QIcon::Normal, QIcon::On);
    wTextAlignVT->setIcon(icon6);
    wTextAlignVT->setFlat(true);
    wTextAlignVT->setCheckable(true);
    wTextAlignVT->setChecked(true);
    hBox->addWidget(wTextAlignVT);

    auto wTextAlignVC = new QPushButton();
    wTextAlignVC->setFixedSize(QSize(24, 24));
    wTextAlignVC->setIconSize(QSize(24, 24));
    QIcon icon7(":/res/ProgramManager/EditProgram/DocAlignVC_u.png");
    icon7.addFile(":/res/ProgramManager/EditProgram/DocAlignVC_s.png", QSize(), QIcon::Normal, QIcon::On);
    wTextAlignVC->setIcon(icon7);
    wTextAlignVC->setFlat(true);
    wTextAlignVC->setCheckable(true);
    hBox->addWidget(wTextAlignVC);

    auto wTextAlignVB = new QPushButton();
    wTextAlignVB->setFixedSize(QSize(24, 24));
    wTextAlignVB->setIconSize(QSize(24, 24));
    QIcon icon8(":/res/ProgramManager/EditProgram/DocAlignVB_u.png");
    icon8.addFile(":/res/ProgramManager/EditProgram/DocAlignVB_s.png", QSize(), QIcon::Normal, QIcon::On);
    wTextAlignVB->setIcon(icon8);
    wTextAlignVB->setFlat(true);
    wTextAlignVB->setCheckable(true);
    hBox->addWidget(wTextAlignVB);

    hBox->addStretch();

    hBox->addWidget(new QLabel(tr("Kerning")));

    auto fdLetterSpacing = new QSpinBox();
    fdLetterSpacing->setMaximum(999);
    fdLetterSpacing->setValue(m_attr.letterSpacing);
    connect(fdLetterSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
        m_attr.letterSpacing = value;
        update();
        RefreshBigPixmap();
    });
    hBox->addWidget(fdLetterSpacing);

    hBox->addWidget(new QLabel(tr("Line Spacing")));

    auto fdLineSpacing = new QSpinBox();
    fdLineSpacing->setMaximum(999);
    fdLineSpacing->setValue(m_attr.lineSpacing);
    connect(fdLineSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
        m_attr.lineSpacing = value;
        update();
        RefreshBigPixmap();
    });
    hBox->addWidget(fdLineSpacing);

    vBox->addLayout(hBox);

    auto wTextAlignH = new QButtonGroup(wgtAttr);
    wTextAlignH->addButton(wTextAlignHL, Qt::AlignLeft);
    wTextAlignH->addButton(wTextAlignHC, Qt::AlignHCenter);
    wTextAlignH->addButton(wTextAlignHR, Qt::AlignRight);
    connect(wTextAlignH, &QButtonGroup::idClicked, this, [this](int value) {
        int res = m_attr.opt.alignment();
        res &= ~Qt::AlignHorizontal_Mask;
        res |= value;
        m_attr.opt.setAlignment(static_cast<Qt::Alignment>(res));
        update();
        RefreshBigPixmap();
    });

    auto wTextAlignV = new QButtonGroup(wgtAttr);
    wTextAlignV->addButton(wTextAlignVT, Qt::AlignTop);
    wTextAlignV->addButton(wTextAlignVC, Qt::AlignVCenter);
    wTextAlignV->addButton(wTextAlignVB, Qt::AlignBottom);
    connect(wTextAlignV, &QButtonGroup::idClicked, this, [this](int value) {
        int res = m_attr.opt.alignment();
        res &= ~Qt::AlignVertical_Mask;
        res |= value;
        m_attr.opt.setAlignment(static_cast<Qt::Alignment>(res));
        update();
        RefreshBigPixmap();
    });

    auto align = m_attr.opt.alignment();
    auto h_align = align & Qt::AlignHorizontal_Mask;
    if(h_align==Qt::AlignLeft) wTextAlignHL->setChecked(true);
    if(h_align==Qt::AlignHCenter) wTextAlignHC->setChecked(true);
    if(h_align==Qt::AlignRight) wTextAlignHR->setChecked(true);
    auto v_align = align & Qt::AlignVertical_Mask;
    if(v_align==Qt::AlignTop) wTextAlignVT->setChecked(true);
    if(v_align==Qt::AlignVCenter) wTextAlignVC->setChecked(true);
    if(v_align==Qt::AlignBottom) wTextAlignVB->setChecked(true);

    fdText->setMinimumHeight(160);
    auto font = fdText->font();
    font.setPixelSize(16);
    fdText->setFont(font);
    auto pal = fdText->palette();
    pal.setColor(QPalette::Base, Qt::black);
    pal.setColor(QPalette::Text, Qt::white);
    fdText->setPalette(pal);
    fdText->setFrameShape(QFrame::NoFrame);
    fdText->setAcceptRichText(false);
    connect(fdText, &QTextEdit::textChanged, this, [this, fdText] {
        QString plain = fdText->toPlainText();
        if(plain.isEmpty()) {
            fdText->selectAll();
            QTextCharFormat fmt;
            fmt.setForeground(Qt::white);
            Tools::mergeFormat(fdText, fmt);
        }
        m_attr.text = fdText->toHtml();
        update();
        RefreshBigPixmap();
    });
    vBox->addWidget(fdText);

    hBox = new QHBoxLayout;
    hBox->addStretch();
    hBox->addWidget(new QLabel(tr("PageCount:")));

    auto fdPageCnt = new QLabel(QString::number(m_attr.iPageCount));
    hBox->addWidget(fdPageCnt);

    hBox->addSpacing(20);
    hBox->addWidget(new QLabel(tr("page")));

    auto fdPageIdx = new QSpinBox();
    fdPageIdx->setRange(1, m_attr.iPageCount);
    connect(fdPageIdx, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, &EText::OnPageIndexPreview);
    hBox->addWidget(fdPageIdx);
    hBox->addStretch();

    auto btnImport = new QPushButton(tr("Import txt File"));
    btnImport->setProperty("ssType", "progManageTool");
    connect(btnImport, &QPushButton::clicked, fdText, [fdText] {
        auto filePath = QFileDialog::getOpenFileName(gMainWin, tr("Select File"), gFileHome, "Txt(*.txt)");
        if(filePath.isEmpty()) return;
        QFile file(filePath);
        if(! file.open(QFile::ReadOnly)) {
            QMessageBox::critical(gMainWin, tr("Fail"), tr("File Open Fail"));
            return;
        }
        auto data = file.readAll();
        file.close();
        QTextCodec::ConverterState state;
        QString text = QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state);
        if(state.invalidChars > 0) text = QString::fromLocal8Bit(data);
        fdText->setText(text);
    });
    hBox->addWidget(btnImport);

    vBox->addLayout(hBox);

    hBox = new QHBoxLayout;
    hBox->addWidget(new QLabel(tr("Play Properties")));

    line = new QFrame();
    line->setFrameShape(QFrame::HLine);
    line->setFrameShadow(QFrame::Sunken);
    hBox->addWidget(line, 1);

    vBox->addLayout(hBox);

    hBox = new QHBoxLayout;
    hBox->addStretch();

    auto fdFlip = new QRadioButton(tr("Flip"));
    hBox->addWidget(fdFlip);
    hBox->addStretch();

    auto fdScroll = new QRadioButton(tr("Scroll"));
    fdScroll->setChecked(true);
    hBox->addWidget(fdScroll);
    hBox->addStretch();

    auto fdStatic = new QRadioButton(tr("Static"));
    hBox->addWidget(fdStatic);
    hBox->addStretch();

    vBox->addLayout(hBox);

    auto wPlayStyle = new QButtonGroup(wgtAttr);
    wPlayStyle->addButton(fdFlip, EText::Flip);
    wPlayStyle->addButton(fdScroll, EText::Scroll);
    wPlayStyle->addButton(fdStatic, EText::Static);
    if(m_attr.playStyle==EText::Flip) fdFlip->setChecked(true);
    else if(m_attr.playStyle==EText::Scroll) fdScroll->setChecked(true);
    else if(m_attr.playStyle==EText::Static) fdStatic->setChecked(true);

    auto wgtAttrFlip = new QWidget();
    {
        auto vBox = new QVBoxLayout(wgtAttrFlip);
        vBox->setContentsMargins(2, 0, 2, 0);
        vBox->setSpacing(3);

        hBox = new QHBoxLayout;

        auto label = new QLabel(tr("Play Duration"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto fdDur = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.turning.playDuration*1000));
        fdDur->setReadOnly(true);
        fdDur->setButtonSymbols(QAbstractSpinBox::NoButtons);
        fdDur->setDisplayFormat("H:mm:ss");
        fdDur->setStyleSheet("QTimeEdit{background-color:#ddd;}");
        connect(fdDur, &QTimeEdit::timeChanged, this, [this](const QTime &time) {
            m_attr.turning.playDuration = time.msecsSinceStartOfDay()/1000;
        });
        hBox->addWidget(fdDur);
        hBox->addStretch();

        vBox->addLayout(hBox);

        hBox = new QHBoxLayout();

        label = new QLabel(tr("Duration/Page"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto fdPageDur = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.turning.pageDuration*1000));
        fdPageDur->setDisplayFormat("H:mm:ss");
        fdPageDur->setCurrentSection(QTimeEdit::SecondSection);
        hBox->addWidget(fdPageDur);
        hBox->addStretch();

        vBox->addLayout(hBox);

        hBox = new QHBoxLayout();

        label = new QLabel(tr("Entrance Effect"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto fdEff = new QComboBox();
        fdEff->addItem(tr("no"), "no");
        fdEff->addItem(tr("random"), "random");
        fdEff->addItem(tr("right to left"), "right to left");
        fdEff->addItem(tr("bottom to top"), "bottom to top");
        fdEff->addItem(tr("left to right"), "left to right");
        fdEff->addItem(tr("top to bottom"), "top to bottom");
        int idx = fdEff->findData(m_attr.turning.effect);
        if(idx!=-1) fdEff->setCurrentIndex(idx);
        connect(fdEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, fdEff] {
            m_attr.turning.effect = fdEff->currentData().toString();
            update();
        });
        hBox->addWidget(fdEff);
        hBox->addStretch();

        vBox->addLayout(hBox);

        hBox = new QHBoxLayout();

        label = new QLabel(tr("Effect time"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto wEffectSpeed = new QSpinBox();
        wEffectSpeed->setValue(m_attr.turning.effectDuration);
        hBox->addWidget(wEffectSpeed);
        hBox->addWidget(new QLabel(tr("s")));
        hBox->addStretch();

        vBox->addLayout(hBox);
        vBox->addStretch();

        connect(fdPageDur, &QTimeEdit::timeChanged, this, [this, wEffectSpeed, fdPageDur, fdDur](const QTime &time) {
            int effDur = wEffectSpeed->value();
            int pageDur = time.msecsSinceStartOfDay()/1000;
            if(pageDur < effDur) {
                QMessageBox::warning(gMainWin, tr("Tip Info"), tr("Effect time cannot be longer than duration time"));
                pageDur = effDur;
                fdPageDur->setTime(QTime::fromMSecsSinceStartOfDay(pageDur*1000));
                fdPageDur->setFocus();
            }
            m_attr.turning.pageDuration = pageDur;
            m_attr.turning.playDuration = pageDur * m_attr.iPageCount;
            fdDur->setTime(QTime::fromMSecsSinceStartOfDay(m_attr.turning.playDuration*1000));
        });
        connect(wEffectSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, wEffectSpeed, fdPageDur](int value) {
            int pageDur = fdPageDur->time().msecsSinceStartOfDay()/1000;
            if(value > pageDur) {
                QMessageBox::warning(gMainWin, tr("Tip Info"), tr("Effect time cannot be longer than duration time"));
                if(pageDur>1) value = pageDur-1;
                else value = 0;
                wEffectSpeed->setValue(value);
                wEffectSpeed->setFocus();
            }
            m_attr.turning.effectDuration = value;
        });
        connect(this, &EText::sPageCountChanged, wgtAttr, [this, fdPageCnt, fdPageIdx, fdPageDur, fdDur] {
            fdPageCnt->setText(QString::number(m_attr.iPageCount));
            fdPageIdx->setRange(1, m_attr.iPageCount);
            fdPageIdx->setValue(1);
            fdDur->setTime(QTime::fromMSecsSinceStartOfDay(fdPageDur->time().msecsSinceStartOfDay()*m_attr.iPageCount));
        });
    }
    auto wgtAttrScroll = new QWidget();
    {
        auto vBox = new QVBoxLayout(wgtAttrScroll);
        vBox->setContentsMargins(2, 0, 2, 0);
        vBox->setSpacing(3);

        auto hBox = new QHBoxLayout();

        auto label = new QLabel(tr("Play Duration"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto timeEdit = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.rolling.playDuration*1000));
        timeEdit->setDisplayFormat("H:mm:ss");
        timeEdit->setCurrentSectionIndex(2);
        connect(timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime &time) {
            m_attr.rolling.playDuration = time.msecsSinceStartOfDay()/1000;
        });
        hBox->addWidget(timeEdit);
        hBox->addStretch();

        vBox->addLayout(hBox);

        hBox = new QHBoxLayout();

        label = new QLabel(tr("Head-Tail Connected"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto wHeadTailConnected = new QCheckBox();
        wHeadTailConnected->setLayoutDirection(Qt::LeftToRight);
        wHeadTailConnected->setStyleSheet("QCheckBox::indicator{width: 16px; height: 16px;}");
        hBox->addWidget(wHeadTailConnected);

        auto lHeadTailSpacing = new QLabel(tr("Head-Tail Spacing"));
        hBox->addWidget(lHeadTailSpacing);

        auto wHeadTailSpacing = new QSpinBox();
        wHeadTailSpacing->setMaximum(9999);
        wHeadTailSpacing->setValue(m_attr.rolling.headTailSpacing);
        connect(wHeadTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
            m_attr.rolling.headTailSpacing = value;
        });
        hBox->addWidget(wHeadTailSpacing);
        hBox->addStretch();

        vBox->addLayout(hBox);

        if(m_attr.rolling.headTailConnected) wHeadTailConnected->setChecked(true);
        else {
            lHeadTailSpacing->setVisible(false);
            wHeadTailSpacing->setVisible(false);
        }
        connect(wHeadTailConnected, &QCheckBox::toggled, this, [this, lHeadTailSpacing, wHeadTailSpacing](bool checked) {
            m_attr.rolling.headTailConnected = checked;
            lHeadTailSpacing->setVisible(checked);
            wHeadTailSpacing->setVisible(checked);
        });

        hBox = new QHBoxLayout();

        label = new QLabel(tr("Scroll Style"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto wRollingStyle = new QComboBox();
        wRollingStyle->addItem(tr("Right -> Left"));
        wRollingStyle->addItem(tr("Bottom -> Top"));
        wRollingStyle->addItem(tr("Left -> Right"));
        wRollingStyle->addItem(tr("Top -> Bottom"));
        wRollingStyle->setCurrentIndex(m_attr.rolling.rollingStyle);
        connect(wRollingStyle, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) {
            m_attr.rolling.rollingStyle  = index;
            update();
            RefreshBigPixmap();
        });
        hBox->addWidget(wRollingStyle);
        hBox->addStretch();

        vBox->addLayout(hBox);

        hBox = new QHBoxLayout();

        label = new QLabel(tr("Scroll Speed"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto wRollingSpeed = new QSpinBox();
        wRollingSpeed->setMaximum(9999);
        wRollingSpeed->setValue(m_attr.rolling.rollingSpeed);
        connect(wRollingSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
            m_attr.rolling.rollingSpeed = value;
        });
        hBox->addWidget(wRollingSpeed);
        hBox->addStretch();

        vBox->addLayout(hBox);
        vBox->addStretch();
    }
    auto wgtAttrStatic = new QWidget();
    {
        auto vBox = new QVBoxLayout(wgtAttrStatic);
        vBox->setContentsMargins(2, 0, 2, 0);
        vBox->setSpacing(3);

        hBox = new QHBoxLayout();
        auto label = new QLabel(tr("Play Duration"));
        label->setMinimumWidth(100);
        hBox->addWidget(label);

        auto timeEdit = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.playDuration*1000));
        timeEdit->setDisplayFormat("H:mm:ss");
        timeEdit->setCurrentSectionIndex(2);
        connect(timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime &time) {
            m_attr.playDuration = time.msecsSinceStartOfDay() / 1000;
        });
        hBox->addWidget(timeEdit);
        hBox->addStretch();

        vBox->addLayout(hBox);
        vBox->addStretch();
    }
    auto stackBox = new QStackedLayout;
    vBox->addLayout(stackBox);
    stackBox->addWidget(wgtAttrFlip);
    stackBox->addWidget(wgtAttrScroll);
    stackBox->addWidget(wgtAttrStatic);
    stackBox->setCurrentIndex(m_attr.playStyle);
    connect(wPlayStyle, &QButtonGroup::idClicked, this, [this, stackBox](int value) {
        m_attr.playStyle = value;
        update();
        RefreshBigPixmap();
        stackBox->setCurrentIndex(value);
    });
    return wgtAttr;
}

bool EText::save(const QString &pRoot) {
   m_pRootPath=pRoot;
   QString strDir = QString("%1%2%3%4%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
   //保存图片元素到相应目录
   QDir dirTemp(m_pRootPath+MACRO_FENGEFU+strDir);
   if(dirTemp.exists())
   {
       if(dirTemp.removeRecursively())
       {
           int iReTryCount=0;
           QDir dRoot(m_pRootPath);
           while(!dRoot.mkdir(strDir))
           {
               QThread::sleep(1);
               iReTryCount++;
               if(iReTryCount>10)
                   break;
           }
       }
   }
   else {
       int iReTryCount=0;
       QDir dRoot(m_pRootPath);
       while(!dRoot.mkdir(strDir))
       {
           QThread::sleep(1);
           iReTryCount++;
           if(iReTryCount>10)
               break;
       }
   }



//   QDir dRoot(m_pRootPath);
//   if(dRoot.exists(strDir)) {
//       QDir dirTemp(m_pRootPath+MACRO_FENGEFU+strDir);
//       if(dirTemp.exists())
//       {

//       }
//       dRoot.removeRecursively()
//       if(dRoot.remove(strDir))
//       {
//            removeRecursively
//       }
//   }
//   int iReTryCount=0;
//   while(!dRoot.mkdir(strDir))
//   {
//       QThread::sleep(1);
//       iReTryCount++;
//       if(iReTryCount>10)
//           break;

//   }
   QString strPath=m_pRootPath+ MACRO_FENGEFU +strDir;
   if(m_attr.playStyle==EText::Flip)//生成多张图
   {
       for (int i=0;i<m_list.count();i++)
       {
          QString strFile=QString("text%1.png").arg(i);
           QString strPngName=strPath+MACRO_FENGEFU+strFile;
           MakeMuliPngToDir(i+1,strPngName);
       }
   }
   else if(m_attr.playStyle==EText::Scroll)//生成一张大图
   {
       if(m_attr.rolling.rollingStyle==0||m_attr.rolling.rollingStyle==2)//0,1左右滚动生成一张横向长图
       {
           QString strFile="text";
           QString strPngName=strPath+MACRO_FENGEFU+strFile;
           MakeBigMoveLeftOrRightOnePngToDir(strPngName);
       }
       else if(m_attr.rolling.rollingStyle==1||m_attr.rolling.rollingStyle==3)//上下滚动，生成一张纵向长图
       {
           QString strFile="text0.png";
           QString strPngName=strPath+MACRO_FENGEFU+strFile;
           MakeBigMoveUpOrDownOnePngToDir(strPngName);
       }
   }
   else if(m_attr.playStyle==EText::Static)//生成一张图
   {
       QString strFile="text0.png";
       QString strPngName=strPath+MACRO_FENGEFU+strFile;
       MakeMuliPngToDir(1,strPngName);
   }
    return true;

}
QJsonObject EText::attrJson() const {
    QJsonObject oRoot;
    QJsonObject oWidget;
    QJsonObject oColor;
    QJsonObject oFont;
    QJsonObject oPlay;

    addBaseAttr(oRoot);
    oRoot["elementType"]   = "Text";
    // Widget
    oWidget["text"]        = m_attr.text;
    oWidget["align"]       = static_cast<int>(m_attr.opt.alignment());
    oColor["background"]   = Tools::color2Int(m_attr.cBackground);
    oWidget["lineSpacing"] = m_attr.lineSpacing;
    oWidget["wordSpacing"] = m_attr.letterSpacing;
    oWidget["cBackground"] = Tools::color2Int(m_attr.cBackground);

    QJsonObject QJOPngObject;
    QJsonArray QJArrayPngItems;
    QString strDir=QString("%1%2%3%4%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
    if(m_attr.playStyle==EText::Flip)//生成多张图
    {

        for (int i=0;i<m_list.count();i++)
        {
           QString strFile=QString("text%1.png").arg(i);
           QJArrayPngItems.append(strFile);
        }

    }
    else if(m_attr.playStyle==EText::Scroll)//生成一张大图
    {
        if(m_attr.rolling.rollingStyle==0||m_attr.rolling.rollingStyle==2)//上下滚动，生成一张纵向长图
        {
            for (int i=0;i<m_linelist.count();i++)
            {
               QString strFile=QString("text%1.png").arg(i);
               QJArrayPngItems.append(strFile);
            }
        }
        else if(m_attr.rolling.rollingStyle==1||m_attr.rolling.rollingStyle==3)//上下滚动，生成一张纵向长图
        {
             QString strFile="text0.png";
             QJArrayPngItems.append(strFile);
        }
    }
    else if(m_attr.playStyle==EText::Static)//生成一张图
    {
        QString strFile="text0.png";
        QJArrayPngItems.append(strFile);
    }
    oWidget.insert("iPageCount",m_attr.iPageCount);
    oWidget.insert("files",QJArrayPngItems);
    oWidget.insert("idDir",strDir);

    oRoot["widget"]        = oWidget;
    // Play
    oPlay["style"]             = m_attr.playStyle;

    QJsonObject objTurning;
    objTurning["strEffect"]=m_attr.turning.effect;
    objTurning["iEffectTime"]=m_attr.turning.pageDuration;
    objTurning["iEffectSpeed"]=m_attr.turning.effectDuration;
    objTurning["playDuration"]=m_attr.turning.playDuration;
    oPlay["turning"] = objTurning;
    QJsonObject objRolling;
    objRolling["rollingStyle"]=m_attr.rolling.rollingStyle;
    objRolling["rollingSpeed"]=m_attr.rolling.rollingSpeed;
    objRolling["headTailConnected"]=m_attr.rolling.headTailConnected;
    objRolling["headTailSpacing"]=m_attr.rolling.headTailSpacing;
    objRolling["playDuration"]=m_attr.rolling.playDuration;
    oPlay["rolling"] = objRolling;
    QJsonObject objStatic;
    objStatic["playDuration"] = m_attr.playDuration;
    oPlay["static"] = objStatic;

    oRoot["play"]              = oPlay;
    return oRoot;
}

void EText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    painter->save();
    painter->drawPixmap(innerRect(), mRenderImg, QRectF());
    painter->restore();
    EBase::paint(painter, option, widget);
}

void EText::CreateBigOnePixBmp(){
    QPainter painter;
    QTextDocument doc;
    doc.setDefaultTextOption(m_attr.opt);
    doc.setDocumentMargin(0);
    doc.setTextWidth(rect().width());

    QFont font;
    if(gTextAntialiasing) font.setHintingPreference(QFont::PreferNoHinting);
    else {
        font.setLetterSpacing(QFont::AbsoluteSpacing, m_attr.letterSpacing);
        font.setStyleStrategy(QFont::NoAntialias);
    }
    font.setPixelSize(16);
    doc.setDefaultFont(font);
    m_lineH = m_attr.lineSpacing + QFontMetrics(doc.defaultFont()).lineSpacing();
    doc.setHtml("<style>div{color:#fff; line-height:"+QString::number(m_lineH)+"px; white-space:pre-wrap;}</style><div>"+m_attr.text+"</div>");

    int iwidth=this->rect().toRect().width();
    QRectF OutPutBmpRect = QRectF(0, 0, iwidth, doc.size().height());//实际绘制文本的矩形大小
    int iheight=OutPutBmpRect.toRect().height();

    QPixmap map(iwidth, iheight);

    map.fill(m_attr.cBackground);
    painter.begin(&map);
    doc.drawContents(&painter, OutPutBmpRect);
    painter.end();
    m_bigOnePixBmp=map.copy(OutPutBmpRect.toRect());
}

void EText::RefreshBigPixmap(){
    if(m_attr.playStyle==EText::Flip){//生成多张图
        CreateBigOnePixBmp();
        if(m_bigOnePixBmp.height()>6) {
            QImage tempQImage=m_bigOnePixBmp.toImage();
            m_ImageBkColor=tempQImage.pixelColor(0,0);
            m_list.clear();
            GetPagesPosList();
        }
        if(m_list.count()>0) OnPageIndexPreview(1);
        m_attr.iPageCount=m_list.count();
        emit sPageCountChanged(m_list.count());
    }
    else if(m_attr.playStyle==EText::Scroll)//生成一张大图
    {
        if(m_attr.rolling.rollingStyle==0||m_attr.rolling.rollingStyle==2)//上下滚动，生成一张纵向长图
        {
            MakeBigMoveLeftOrRightOnePngToDir();
        }
        else if(m_attr.rolling.rollingStyle==1||m_attr.rolling.rollingStyle==3)//上下滚动，生成一张纵向长图
        {
            MakeBigMoveUpOrDownOnePngToDir();
        }
        m_attr.iPageCount=1;
        emit sPageCountChanged(1);
    }
    else if(m_attr.playStyle==EText::Static)//生成一张图
    {
        CreateBigOnePixBmp();
        if(m_bigOnePixBmp.height()>6){
            QImage tempQImage=m_bigOnePixBmp.toImage();
            m_ImageBkColor=tempQImage.pixelColor(0,0);
            m_list.clear();
            GetPagesPosList();
        }
        m_attr.iPageCount=1;
        OnPageIndexPreview(1);
        emit sPageCountChanged(1);
    }
}

int EText::GetPagesPosList(){
    int iIndex=0;
    for (;;) {
        if(ClearPixmapTopAndBottomBlack()<=0) return m_list.count();
        txtBmpPage temp=GetFirstPagePixmap();
        if(temp.index==-1) {//表示到最后，bigpixmap已经没有内容了
            temp.index=iIndex;
            iIndex++;
            m_list.append(temp);
            return m_list.count();
        } else {
            temp.index=iIndex;
            m_list.append(temp);
            iIndex++;
            if(iIndex > 100) break;
        }
    }
    return m_list.count();
}
//去除上下的黑边，返回去掉黑边图像的高度
int EText::ClearPixmapTopAndBottomBlack()
{
    QImage tempQImage=m_bigOnePixBmp.toImage();
    int iFirst=0;
    int iEnd=m_bigOnePixBmp.height();
    bool bFirst=false;
    bool bEnd=false;
    for(int y=0;y<m_bigOnePixBmp.height();y++)
    {
        for (int x=0;x<m_bigOnePixBmp.width();x++)
        {
            if(tempQImage.pixelColor(x,y)!=m_ImageBkColor)
            {
                iFirst=y;
                bFirst=true;
                break;
            }
        }
        if(bFirst)
            break;
    }
    if(bFirst==false)//图全黑
    {
        return -1;
    }
    for(int m=m_bigOnePixBmp.height()-1;m>=0;m--)
    {
        for (int n=0;n<m_bigOnePixBmp.width();n++)
        {
            if(tempQImage.pixelColor(n,m)!=m_ImageBkColor)
            {
                iEnd=m;
                bEnd=true;
                break;
            }
        }
        if(bEnd)
            break;
    }
    if(iEnd-iFirst>1)
    {
        int iCopyHeight=iEnd-iFirst+1;
        m_bigOnePixBmp=m_bigOnePixBmp.copy(0,iFirst,m_bigOnePixBmp.width(),iCopyHeight+1);
        return iCopyHeight;
    }
    else {
        //空的没有文字的部分
        return -1;
    }
}

txtBmpPage EText::GetFirstPagePixmap()
{
    QImage tempQImage=m_bigOnePixBmp.toImage();
//    tempQImage.save("f://a.png","PNG");
    txtBmpPage tempPageClass;
    int iWidth=m_bigOnePixBmp.width();
    int iHeight=m_bigOnePixBmp.height();
    int iRectHeight=rect().height();
    if(iRectHeight>iHeight) iRectHeight=iHeight;
    int iType=0;
    //判断底边是不是黑
    for (int x=0;x<iWidth;x++)
    {
        QColor aa=tempQImage.pixelColor(x,iRectHeight-1);
        if(aa!=m_ImageBkColor)
        {
            iType=1;
            break;
        }
    }

     if(iType==0) //矩形底边是黑色
     {
         //倒着推断图的下边
         for (int y=iRectHeight-1;y>=0;y--)
         {
             bool bFinished=false;
             for (int x=0;x<iWidth;x++)
             {
                 QColor bb=tempQImage.pixelColor(x,y);
                 if(bb!=m_ImageBkColor)
                 {
                    bFinished=true;
                     break;
                 }
             }
             if(bFinished)
             {
                 tempPageClass.bitmap=m_bigOnePixBmp.copy(0,0,iWidth,y+1);
                 m_bigOnePixBmp=m_bigOnePixBmp.copy(0,y+1,iWidth,iHeight-y-1);
                  break;
             }
         }
     }
     else if(iType==1)
     {
         //倒着推断图的下边，如果到顶都没有符合条件的黑边，则表示文字的大小大于图片的高度，否则找到上一个文字底部作为图片的下边
         int iSubType=0;
         int iSubEnd=0;
         for (int y=iRectHeight-1;y>=0;y--)
         {
             bool bFinished=false;
             for (int x=0;x<iWidth;x++)
             {
                 QColor bb=tempQImage.pixelColor(x,y);
                 if(bb!=m_ImageBkColor)
                 {
                         bFinished=true;
                         break;
                 }
             }
             if(bFinished==false)
             {
                //找到了 一条黑边，则证明上面还有文字，
                 iSubType=1;
                 iSubEnd=y;
                 break;
             }

         }
         if(iSubType==0)//文字的大小大于图片的高度
         {
             tempPageClass.bitmap=m_bigOnePixBmp.copy(0,0,iWidth,iRectHeight);
             if(iHeight>iRectHeight)
                m_bigOnePixBmp=m_bigOnePixBmp.copy(0,iRectHeight,iWidth,iHeight-iRectHeight);
             else
             {
                 tempPageClass.index=-1;
                 return tempPageClass;
             }
         }
         else if(iSubType==1)
         {
             for (int y=iSubEnd;y>=0;y--)
             {
                 bool bFinished=false;
                 for (int x=0;x<iWidth;x++)
                 {
                     if(tempQImage.pixelColor(x,y)!=m_ImageBkColor)
                     {
                             bFinished=true;
                             break;
                     }
                 }
                 if(bFinished==true)
                 {
                     tempPageClass.bitmap=m_bigOnePixBmp.copy(0,0,iWidth,y+1);
                     m_bigOnePixBmp=m_bigOnePixBmp.copy(0,y+1,iWidth,iHeight-y-1);
                     break;
                 }

             }
         }

     }
    return tempPageClass;
}
void EText::OnPageIndexPreview(int iPageIndex) {
    iPageIndex=iPageIndex-1;
    if(iPageIndex<0) iPageIndex=0;
    if(iPageIndex>=0) {
        if(m_list.count()>0 && iPageIndex<m_list.count()) {
            mRenderImg = QPixmap(rect().size().toSize());
            mRenderImg.fill(m_attr.cBackground);
            int res = m_attr.opt.alignment();
            QPixmap pageImg = m_list[iPageIndex].bitmap;
            QPainter painter;
            painter.begin(&mRenderImg);
            QBrush bshBackground = Tools::getBrush(m_attr.cBackground);
            if((res & Qt::Alignment::enum_type::AlignTop)!=0) {
                if(bshBackground != Qt::NoBrush) painter.fillRect(0, pageImg.height(), pageImg.width(),rect().height()-pageImg.height(), bshBackground);
                painter.drawPixmap(0, 0, pageImg.width(),pageImg.height(),pageImg);
            } else if((res & Qt::Alignment::enum_type::AlignBottom)!=0) {
                if(bshBackground != Qt::NoBrush) painter.fillRect(0, 0, pageImg.width(), rect().height()-pageImg.height(), bshBackground);
                painter.drawPixmap(0, rect().height()-pageImg.height(),pageImg.width(),pageImg.height(),pageImg);
            } else {
                int iTopOffset = (rect().height()-pageImg.height())/2;
                if(bshBackground != Qt::NoBrush) {
                    painter.fillRect(0,0,pageImg.width(),iTopOffset, bshBackground);
                    painter.fillRect(0, iTopOffset+pageImg.height(),pageImg.width(),rect().height()-iTopOffset-pageImg.height() ,bshBackground);
                }
                painter.drawPixmap(0, iTopOffset, pageImg.width(), pageImg.height(), pageImg);
            }
            painter.end();
        }
    }
    update();
}

void EText::MakeBigMoveUpOrDownOnePngToDir() {
    QPainter painter;
    QTextDocument doc;
    doc.setDefaultTextOption(m_attr.opt);
    doc.setDocumentMargin(0);
    doc.setTextWidth(rect().width());

    QFont font;
    if(gTextAntialiasing) font.setHintingPreference(QFont::PreferNoHinting);
    else {
        font.setLetterSpacing(QFont::AbsoluteSpacing, m_attr.letterSpacing);
        font.setStyleStrategy(QFont::NoAntialias);
    }
    font.setPixelSize(16);
    doc.setDefaultFont(font);

    int lineSpacing = QFontMetrics(doc.defaultFont()).lineSpacing();
    doc.setHtml("<style>div{color:#fff; line-height:"+QString::number(m_attr.lineSpacing + lineSpacing)+"px; white-space:pre-wrap;}</style><div>"+m_attr.text+"</div>");

    int iwidth=this->rect().toRect().width();
    QRectF OutPutBmpRect = QRectF(0, 0, iwidth, doc.size().height());//实际绘制文本的矩形大小
    int iheight=OutPutBmpRect.toRect().height();

    QPixmap map(iwidth,iheight);
    map.fill(m_attr.cBackground);
    painter.begin(&map);
    doc.drawContents(&painter, OutPutBmpRect);
    painter.end();
    mRenderImg = QPixmap(rect().size().toSize());
    mRenderImg.fill(m_attr.cBackground);
    painter.begin(&mRenderImg);
    if(rect().height()>map.height()) {
        QBrush bshBackground = Tools::getBrush(m_attr.cBackground);
        if(bshBackground != Qt::NoBrush) painter.fillRect(0,map.height(),rect().width(),rect().height()-map.height(), bshBackground);
        painter.drawPixmap(map.rect(), map,map.rect());
    } else {
        QRectF rectSource(0,0,rect().width(),rect().height());
        painter.drawPixmap(rect(),map,rectSource);
    }
    painter.end();
    update();
}
void EText::MakeBigMoveLeftOrRightOnePngToDir() {
    QPainter painter;
    QTextDocument doc;
    //m_attr.opt.setAlignment(Qt::AlignJustify);
    m_attr.opt.setAlignment(Qt::AlignLeft);
    doc.setDefaultTextOption(m_attr.opt);
    doc.setDocumentMargin(0);
   // doc.setTextWidth(rect().width());
    doc.setTextWidth(3800);

    QFont font;
    if(gTextAntialiasing) font.setHintingPreference(QFont::PreferNoHinting);
    else {
        font.setLetterSpacing(QFont::AbsoluteSpacing, m_attr.letterSpacing);
        font.setStyleStrategy(QFont::NoAntialias);
    }
    font.setPixelSize(16);
    doc.setDefaultFont(font);

    const int lineSpacing = QFontMetrics(doc.defaultFont()).lineSpacing();
    int lineH = m_attr.lineSpacing + lineSpacing;
    doc.setHtml("<style>div{color:#fff; line-height:"+QString::number(lineH)+"px; white-space:pre-wrap;}</style><div>"+m_attr.text+"</div>");

    //int iwidth=this->rect().toRect().width();
    int iwidth=3800;
    QRectF OutPutBmpRect = QRectF(0, 0, iwidth, doc.size().height());//实际绘制文本的矩形大小
    int iheight=OutPutBmpRect.toRect().height();

    QPixmap map(iwidth,iheight);
    map.fill(m_attr.cBackground);
    painter.begin(&map);
    doc.drawContents(&painter, OutPutBmpRect);
    painter.end();
    QPixmap bigOnePixmap=map.copy(OutPutBmpRect.toRect());
    //获取
    m_linelist.clear();
    //获取到长图的每页添加到list，并返回最大高度
    GetLinePng(bigOnePixmap);
    //把list中的图片拼接起来
    if(m_linelist.count()>0) {
        QBrush bshBackground = Tools::getBrush(m_attr.cBackground);
        //把长图的开头拷贝到输出pixmap预览
        mRenderImg = QPixmap(rect().size().toSize());
        mRenderImg.fill(m_attr.cBackground);
        painter.begin(&mRenderImg);

        txtBmpLine tmpLine=m_linelist.at(0);
        int itempHeight=tmpLine.bitmap.height();//tmpLine.iEnd-tmpLine.iStart;

        int iTopOffset=(rect().height()-itempHeight)/2;
        painter.fillRect(0,0,rect().width(),iTopOffset, bshBackground);
        painter.fillRect(0,iTopOffset+itempHeight,rect().width(),rect().height()-iTopOffset-itempHeight, bshBackground);

        QRectF rectDest(0,iTopOffset,rect().width(),itempHeight);
        QRectF rectSource(0,0,rect().width(),itempHeight);
        painter.drawPixmap(rectDest,tmpLine.bitmap,rectSource);
        painter.end();
    }
    update();
}

int EText::GetLinePng(QPixmap bigOnePixmap)
{
    QImage tempQImage=bigOnePixmap.toImage();
    m_ImageBkColor=tempQImage.pixelColor(0,0);
//    int iFirst=0;
//    int iEnd=bigOnePixmap.height();
    bool bLineFlag=false;
//    bool bEnd=false;
    int iIndex=0;
    txtBmpLine tmp;
    int iMaxHeight=0;
    for(int y=0;y<bigOnePixmap.height();y++)
    {
        bool bOneWidthEnd=false;
        int itemp=0;
        for (int x=0;x<bigOnePixmap.width();x++)
        {
            if(bLineFlag==false)//行没有开始
            {
                QColor bb=tempQImage.pixelColor(x,y);
                if(bb!=m_ImageBkColor )//找到行的开始
                {
                    tmp.index=iIndex;
                    tmp.iStart=y;
                    iIndex++;
                    bLineFlag=true;
                    itemp=1;
                    break;
                }
            }
            else//行开始了
            {
                if(tempQImage.pixelColor(x,y)!=m_ImageBkColor )
                {
                    bOneWidthEnd=true;
                }
            }

        }
        if(itemp==0)
        {
            if(bLineFlag)//行开始后
            {
                if(bOneWidthEnd )//仍旧是行
                {
                    if(y==bigOnePixmap.height()-1)
                    {
                        tmp.iEnd=y;
                        int ipicHeight=tmp.iEnd-tmp.iStart;
                        if(ipicHeight>2)
                        {
                            if(ipicHeight>iMaxHeight)
                                iMaxHeight=ipicHeight;
                            tmp.bitmap=bigOnePixmap.copy(0,tmp.iStart,bigOnePixmap.width(),tmp.iEnd-tmp.iStart);
                            m_linelist.append(tmp);
                            bLineFlag=false;
                        }
                    }
                }

                else //文字行向下判断到了一个背景色的行，扫描了一行也没有发现文字颜色，都是背景色
                {

                    tmp.iEnd=y;
                    int ipicHeight=tmp.iEnd-tmp.iStart;
                    if(ipicHeight>2)
                    {
                        if(ipicHeight>iMaxHeight)
                            iMaxHeight=ipicHeight;
                        tmp.bitmap=bigOnePixmap.copy(0,tmp.iStart,bigOnePixmap.width(),tmp.iEnd-tmp.iStart);
                        m_linelist.append(tmp);
                        bLineFlag=false;
                    }

                 }
            }
        }
    }

    return iMaxHeight;
}
//生成左右滚动图片素材
void EText::MakeBigMoveLeftOrRightOnePngToDir(QString strPngPathAndName) {
    QPainter painter;
        GetPagesPosList();
        QTextDocument doc;
         m_attr.opt.setAlignment(Qt::AlignLeft);
        doc.setDefaultTextOption(m_attr.opt);
        doc.setDocumentMargin(0);
        doc.setTextWidth(3800);
        QFont font;
        if(gTextAntialiasing) font.setHintingPreference(QFont::PreferNoHinting);
        else {
            font.setLetterSpacing(QFont::AbsoluteSpacing, m_attr.letterSpacing);
            font.setStyleStrategy(QFont::NoAntialias);
        }
        font.setPixelSize(16);
        doc.setDefaultFont(font);

        const int lineSpacing = QFontMetrics(doc.defaultFont()).lineSpacing();
        int lineH = m_attr.lineSpacing + lineSpacing;
        doc.setHtml("<style>div{color:#fff; line-height:"+QString::number(lineH)+"px; white-space:pre-wrap;}</style><div>"+m_attr.text+"</div>");

        //int iwidth=this->rect().toRect().width()*iAllPagesTemp;
        int iwidth=3800;
        QRectF OutPutBmpRect = QRectF(0, 0, iwidth, doc.size().height());//实际绘制文本的矩形大小
        int iheight=OutPutBmpRect.toRect().height();

        QPixmap map(iwidth,iheight);
        map.fill(m_attr.cBackground);
        painter.begin(&map);
        doc.drawContents(&painter,OutPutBmpRect);
        painter.end();
        QPixmap bigOnePixmap=map.copy(OutPutBmpRect.toRect());
        //获取
        bigOnePixmap.save("f:/a.png","PNG");
        m_linelist.clear();
        //获取到长图的每页添加到list，并返回最大高度
        GetLinePng(bigOnePixmap);
        //把list中的图片拼接起来
        int iMaxHeight=rect().height();
        if(m_linelist.count()>0)
        {
            QBrush bshBackground(m_attr.cBackground);// = LoAppTools::getInstance()->getBrush(m_attr.cBackground);
            QList<int> listPageWidth;
            int iPicLongSize=0;
            for (int j=0;j<m_linelist.count();j++)
            {
                txtBmpLine tmpLine=m_linelist.at(j);
                iPicLongSize=tmpLine.bitmap.width();
 //               iPicLongSize+=tmpLine.bitmap.width();
//                if(iPicLongSize>4096-rect().width())
                {
                    listPageWidth.append(iPicLongSize);
//                    iPicLongSize=0;
                }
            }
//            if(iPicLongSize!=0)
//            {
//                listPageWidth.append(iPicLongSize);
//            }

            int iIOffset=0;
            for (int m=0;m<listPageWidth.count();m++)
            {
                int itempWidth=listPageWidth.at(m);
                QPixmap bigOneLongPixmap(itempWidth,iMaxHeight);
                bigOneLongPixmap.fill(m_attr.cBackground);
                QPainter *pPainterTemp=new QPainter();
                pPainterTemp->begin(&bigOneLongPixmap);
                iPicLongSize=0;
                for (int i=iIOffset;i<m_linelist.count();i++)
                {

                    txtBmpLine tmpLine=m_linelist.at(i);
                    int itempHeight=tmpLine.bitmap.height();//tmpLine.iEnd-tmpLine.iStart;
                    iPicLongSize+=tmpLine.bitmap.width();
                    if(bshBackground != Qt::NoBrush)
                    {
                        int iTopOffset=(iMaxHeight-itempHeight)/2;
                        pPainterTemp->fillRect((i-iIOffset)*iwidth,0,rect().width(),iTopOffset, bshBackground);
                        pPainterTemp->fillRect((i-iIOffset)*iwidth,iTopOffset+itempHeight,rect().width(),iMaxHeight-iTopOffset-itempHeight, bshBackground);
                    }

                    QRectF rectDest((i-iIOffset)*iwidth,(iMaxHeight-itempHeight)/2,iwidth,itempHeight);
                    pPainterTemp->drawPixmap(rectDest,tmpLine.bitmap,tmpLine.bitmap.rect());
                    if(iPicLongSize==itempWidth)
                    {

                        pPainterTemp->end();
                        delete pPainterTemp;
                        if(m==listPageWidth.count()-1)
                        {
                            //如果启用了首位相接，根据间隔值处理吧文字后边的黑边流出来。
                            if(m_attr.rolling.headTailConnected)
                            {
                                int itempSpace=GetWordSpaceRealInBmp(bigOneLongPixmap);
                                ProcessLastStartEndLianJie(bigOneLongPixmap,strPngPathAndName+QString::number(m)+".png",itempSpace+m_attr.rolling.headTailSpacing);

                            }
                            else {
                                int itempSpace=GetWordSpaceRealInBmp(bigOneLongPixmap);
                                ProcessLastStartEndLianJie(bigOneLongPixmap,strPngPathAndName+QString::number(m)+".png",itempSpace);
                                //bigOneLongPixmap.save(strPngPathAndName+QString::number(m)+".png","PNG");

                            }
                        }
                        else {
                            int itempSpace=GetWordSpaceRealInBmp(bigOneLongPixmap);
                            ProcessLastStartEndLianJie(bigOneLongPixmap,strPngPathAndName+QString::number(m)+".png",itempSpace);
                            //bigOneLongPixmap.save(strPngPathAndName+QString::number(m)+".png","PNG");

                        }
                         iIOffset=i+1;
                        break;
                    }
                    else {
                        pPainterTemp->end();
                        delete pPainterTemp;

                    }
                }
            }
        }

}
void EText::ProcessLastStartEndLianJie(QPixmap bmp,QString strPngFilePathName,int iLastRightNoWordWidth) {
    QImage tempQImage=bmp.toImage();
   int iWidth = bmp.width();
   for (int x=iWidth-1;x>0;x--) {
       for(int y=0;y<bmp.height();y++) {
           QColor bb=tempQImage.pixelColor(x,y);
           if(bb!=m_ImageBkColor) {
               QPixmap returnBmp(x+1+iLastRightNoWordWidth,bmp.height());
               returnBmp.fill(m_ImageBkColor);
               QPainter *pPainterTemp=new QPainter();
               pPainterTemp->begin(&returnBmp);
               pPainterTemp->drawPixmap(bmp.rect(),bmp,bmp.rect());
               pPainterTemp->end();
               if(m_attr.rolling.headTailConnected)
               {
                   if(returnBmp.width()>=rect().width())//如果图片的宽大于区域的宽
                   {
                        returnBmp.save(strPngFilePathName,"PNG");
                   }
                   else {
                       int iBeiShu=rect().width()/returnBmp.width();
                       int iTempWidth=returnBmp.width();
                       QPixmap returnNewBmp(iTempWidth*(iBeiShu+1),bmp.height());
                       returnNewBmp.fill(m_ImageBkColor);
                       QPainter painter;
                       painter.begin(&returnNewBmp);
                       for (int ii=0;ii<iBeiShu+1;ii++) {
                           QRect tempRc(ii*iTempWidth,0,iTempWidth,returnBmp.height());
                           painter.drawPixmap(tempRc,returnBmp,returnBmp.rect());
                       }
                       returnNewBmp.save(strPngFilePathName,"PNG");

                   }
               }
               else {
                   if(returnBmp.width()>=rect().width())//如果图片的宽大于区域的宽
                   {
                       returnBmp.save(strPngFilePathName,"PNG");

                   }
                   else {
                       int iTempWidth=returnBmp.width();
                       QPixmap returnNewBmp(rect().width(),bmp.height());
                       returnNewBmp.fill(m_ImageBkColor);
                       QPainter painter;
                       painter.begin(&returnNewBmp);
                       QBrush bshBackground = Tools::getBrush(m_attr.cBackground);

                       painter.fillRect(returnNewBmp.rect(),bshBackground);
                           QRect tempRc(0,0,iTempWidth,returnBmp.height());
                           painter.drawPixmap(tempRc,returnBmp,returnBmp.rect());
                        returnNewBmp.save(strPngFilePathName,"PNG");
                   }

               }

               delete pPainterTemp;
               return;
           }
       }
   }
}


int EText::GetWordSpaceRealInBmp(QPixmap bmp)
{
    QImage tempQImage=bmp.toImage();
//    m_ImageBkColor=tempQImage.pixelColor(0,0);
   int iWidth= bmp.width();
   int iLastX = iWidth;
   int iCount=0;
   for (int x=iWidth-1;x>0;x--)
   {
       int iAllSameFlag=0;
       for(int y=0;y<bmp.height();y++)
       {
           QColor bb=tempQImage.pixelColor(x,y);
           if(bb!=m_ImageBkColor)
           {
               iAllSameFlag=1;
           }
           if(iCount==0)
           {
               if(bb!=m_ImageBkColor)
               {
                   iCount=1;
                   break;
               }
           }
           else if(iCount==2)
           {
               if(bb!=m_ImageBkColor)
               {
                   iCount=3;
                   break;
               }
           }
       }
       if(iCount==1)
       {
           if(iAllSameFlag==0)
           {
               iLastX=x;
               iCount=2;

           }
       }
       else if(iCount==3)
       {
           return iLastX-x;
       }
   }
   return 1;
}

//生成上下滚动图片素材
void EText::MakeBigMoveUpOrDownOnePngToDir(QString strPngPathAndName) {
    QTextDocument doc;
    doc.setDefaultTextOption(m_attr.opt);
    doc.setDocumentMargin(0);
    doc.setTextWidth(rect().width());

    QFont font;
    if(gTextAntialiasing) font.setHintingPreference(QFont::PreferNoHinting);
    else {
        font.setLetterSpacing(QFont::AbsoluteSpacing, m_attr.letterSpacing);
        font.setStyleStrategy(QFont::NoAntialias);
    }
    font.setPixelSize(16);
    doc.setDefaultFont(font);

    const int lineSpacing = QFontMetrics(doc.defaultFont()).lineSpacing();
    int lineH = m_attr.lineSpacing + lineSpacing;
    doc.setHtml("<style>div{color:#fff; line-height:"+QString::number(lineH)+"px; white-space:pre-wrap;}</style><div>"+m_attr.text+"</div>");
    int iwidth = innerRect().width();
    QRectF OutPutBmpRect(0, 0, iwidth, doc.size().height());//实际绘制文本的矩形大小
    int iheight = OutPutBmpRect.toRect().height();

    QPixmap map(iwidth,iheight);
    map.fill(m_attr.cBackground);
    QPainter painter;
    painter.begin(&map);
    doc.drawContents(&painter, OutPutBmpRect);
    painter.end();

    QPixmap pRenderPixmap = QPixmap(rect().size().toSize());
    pRenderPixmap.fill(m_attr.cBackground);
    painter.begin(&pRenderPixmap);
    if(rect().height()>map.height()) {
        QBrush bshBackground = Tools::getBrush(m_attr.cBackground);
        if(bshBackground != Qt::NoBrush) painter.fillRect(0,map.height(),rect().width(),rect().height()-map.height(), bshBackground);
        painter.drawPixmap(map.rect(),map,map.rect());
        pRenderPixmap.save(strPngPathAndName);
    } else {
        QRectF rectSource(0,0,rect().width(),rect().height());
        painter.drawPixmap(rect(),map,rectSource);
        map.copy(OutPutBmpRect.toRect()).save(strPngPathAndName);
    }
    painter.end();
}
//生成翻页和静态图片素材
void EText::MakeMuliPngToDir(int iPageIndex,QString strPngPathAndName){
    iPageIndex=iPageIndex-1;
    if(iPageIndex<0) iPageIndex=0;
    if(iPageIndex>=0){
        if(m_list.count()>0&&iPageIndex<m_list.count()){
            QPixmap tempPixamp(rect().size().toSize());
            tempPixamp.fill(m_ImageBkColor);
            int res = m_attr.opt.alignment();
            QPixmap tmp=m_list.at(iPageIndex).bitmap;
            if((res & Qt::Alignment::enum_type::AlignTop)!=0){
                QPainter painter;
                painter.begin(&tempPixamp);
                    QBrush bshBackground = Tools::getBrush(m_ImageBkColor);
                    if(bshBackground != Qt::NoBrush) {
                        painter.fillRect(0,tmp.height(),tmp.width(),rect().height()-tmp.height(), bshBackground);
                    }
                painter.drawPixmap(0,0,tmp.width(),tmp.height(),tmp);
                painter.end();
            } else if((res & Qt::Alignment::enum_type::AlignBottom)!=0){
                QPainter painter;
                painter.begin(&tempPixamp);
                QBrush bshBackground = Tools::getBrush(m_ImageBkColor);
                if(bshBackground != Qt::NoBrush) {
                    painter.fillRect(0,0,tmp.width(),rect().height()-tmp.height(), bshBackground);
                }
                painter.drawPixmap(0,rect().height()-tmp.height(),tmp.width(),tmp.height(),tmp);
                painter.end();
            } else {
                QPainter painter;
                painter.begin(&tempPixamp);
                QBrush bshBackground = Tools::getBrush(m_ImageBkColor);
                int iTopOffset=(rect().height()-tmp.height())/2;
                if(bshBackground != Qt::NoBrush) {
                    painter.fillRect(0,0,tmp.width(),iTopOffset, bshBackground);
                    painter.fillRect(0,iTopOffset+tmp.height(),tmp.width(),rect().height()-iTopOffset-tmp.height() ,bshBackground);
                }
                painter.drawPixmap(0,iTopOffset,tmp.width(),tmp.height(),tmp);
                painter.end();
            }
            tempPixamp.save(strPngPathAndName,"PNG");
        }
    }
}
