#define _USE_MATH_DEFINES
#include <math.h>
#include "eaclock.h"
#include "eaclockattr.h"
#include "QSettings"
eAClock::eAClock(QRectF rectInit,InteractiveType type, QGraphicsItem *parent) :
    eObject(rectInit, type, parent)
{
    m_iType=eObject::AClock;
    m_attr.timeZoneId        = QTimeZone::systemTimeZoneId();
    m_attr.hourMark          = 0;
    m_attr.hourMarkSize      = 5;
    m_attr.hourMarkColor     = Qt::green;
    m_attr.minMark           = 1;
    m_attr.minMarkSize       = 2;
    m_attr.minMarkColor      = Qt::yellow;
    m_attr.hourHandColor     = Qt::yellow;
    m_attr.minHandColor      = Qt::green;
    m_attr.secHandColor      = Qt::red;
    m_attr.date              = false;
    m_attr.dateFontFamily    = "Arial";
    m_attr.dateFontSize      = 9;
    m_attr.dateFontBold      = false;
    m_attr.dateFontItalics   = false;
    m_attr.dateFontUnderline = false;
    m_attr.dateColor         = Qt::red;
    m_attr.text              = "";
    m_attr.textFontFamily    = "Arial";
    m_attr.textFontSize      = 9;
    m_attr.textFontBold      = false;
    m_attr.textFontItalics   = false;
    m_attr.textFontUnderline = false;
    m_attr.textColor         = Qt::red;
    m_attr.playDuration      = MACRO_DEFAULT_PLAYDURATION;
    m_attr.path              ="";
    m_attr.name              ="";
    m_attr.bCustomDial       =false;
    init();
}

eAClock::eAClock(const QJsonObject &json, InteractiveType type, QGraphicsItem *parent) :
    eObject(json["geometry"].toObject(), type, parent)
{
    m_iType=eObject::AClock;
    setElement(json, m_attr);
    if(!m_attr.bCustomDial)
    {
        QRectF r1 = geometry();
        QRect r=r1.toRect();
        QString strDir=QString("%1%2%3%4%5").arg(zValue()).arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height());
        m_attr.selfCreateDialName=strDir+".png";
    }
    else {
        if(m_pBiaoPanImage!=nullptr)
            delete m_pBiaoPanImage;
        m_pBiaoPanImage= new QImage(m_attr.path+MACRO_FENGEDANFU+m_attr.name);

    }
    init();

}

void eAClock::init()
{
    connect(LoAppTools::getInstance(), SIGNAL(sTick()), this, SLOT(updateGeometry()));
}

void eAClock::setElement(const QJsonObject &json, Data &attr)
{
    auto at = LoAppTools::getInstance();
    QJsonDocument jRoot(json);
    attr.timeZoneId        = QByteArray().append(jRoot["widget"]["timeZone"]         .toString());
    attr.hourMark          =                     jRoot["widget"]["hourMark"]         .toInt();
    attr.hourMarkSize      =                     jRoot["widget"]["hourMarkSize"]     .toInt();
    attr.hourMarkColor     = at->int2Color(      jRoot["widget"]["hourMarkColor"]    .toInt());
    attr.minMark           =                     jRoot["widget"]["minMark"]          .toInt();
    attr.minMarkSize       =                     jRoot["widget"]["minMarkSize"]      .toInt();
    attr.minMarkColor      = at->int2Color(      jRoot["widget"]["minMarkColor"]     .toInt());
    attr.hourHandColor     = at->int2Color(      jRoot["widget"]["hourHandColor"]    .toInt());
    attr.minHandColor      = at->int2Color(      jRoot["widget"]["minHandColor"]     .toInt());
    attr.secHandColor      = at->int2Color(      jRoot["widget"]["secHandColor"]     .toInt());
    attr.date              =                     jRoot["widget"]["date"]             .toBool();
    attr.dateFontFamily    =                     jRoot["widget"]["dateFontFamily"]   .toString();
    attr.dateFontSize      =                     jRoot["widget"]["dateFontSize"]     .toInt();
    attr.dateFontBold      =                     jRoot["widget"]["dateFontBold"]     .toBool();
    attr.dateFontItalics   =                     jRoot["widget"]["dateFontItalics"]  .toBool();
    attr.dateFontUnderline =                     jRoot["widget"]["dateFontUnderline"].toBool();
    attr.dateColor         = at->int2Color(      jRoot["widget"]["dateColor"]        .toInt());
    attr.text              =                     jRoot["widget"]["text"]             .toString();
    attr.textFontFamily    =                     jRoot["widget"]["textFontFamily"]   .toString();
    attr.textFontSize      =                     jRoot["widget"]["textFontSize"]     .toInt();
    attr.textFontBold      =                     jRoot["widget"]["textFontBold"]     .toBool();
    attr.textFontItalics   =                     jRoot["widget"]["textFontItalics"]  .toBool();
    attr.textFontUnderline =                     jRoot["widget"]["textFontUnderline"].toBool();;
    attr.textColor         = at->int2Color(      jRoot["widget"]["textColor"]        .toInt());
    attr.playDuration      =                     jRoot["play"]["duration"]           .toInt();
    attr.path              =                     jRoot["widget"]["path"]    .toString();
    attr.name              =                     jRoot["widget"]["name"]    .toString();
    attr.selfCreateDialName=                     jRoot["widget"]["selfCreateDialName"].toString();
    attr.bCustomDial       =                     jRoot["widget"]["bCustomDial"]     .toBool();
}

qreal eAClock::radiusHour() const
{
    qreal r = (rect().width() < rect().height() ? rect().width() : rect().height()) / 2;
    return r - m_attr.hourMarkSize / 2;
}

qreal eAClock::radiusMin() const
{
    qreal r = (rect().width() < rect().height() ? rect().width() : rect().height()) / 2;
    return r - m_attr.minMarkSize / 2;
}

void eAClock::paintDial(QPainter *painter)
{
    if(m_pBiaoPanImage==nullptr)
    {
        qreal r = radius();
        QPointF c = center();
        QList<QPointF> plist;
        qreal x, y, ox, oy;
        qreal k;
        qreal a = 0;
        const qreal s = 6;
        for(int i=0; i<60; i++) {
            if (a < 90) {
                k = a * M_PI / 180;
                ox = sin(k) * r;
                oy = cos(k) * r;
                x = c.x() + ox;
                y = c.y() - oy;
            } else if (a < 180) {
                k = (a - 90) * M_PI / 180;
                ox = cos(k) * r;
                oy = sin(k) * r;
                x = c.x() + ox;
                y = c.y() + oy;
            } else if (a < 270) {
                k = (a - 180) * M_PI / 180;
                ox = sin(k) * r;
                oy = cos(k) * r;
                x = c.x() - ox;
                y = c.y() + oy;
            } else {
                k = (a - 270) * M_PI / 180;
                ox = cos(k) * r;
                oy = sin(k) * r;
                x = c.x() - ox;
                y = c.y() - oy;
            }
            a += s;
            plist.push_back(QPointF(x, y));
        }

        a = 0;
        for(int i=0; i<60; i++) {
            if(i % 5) {
                switch (m_attr.minMark) {
                case 0:  drawMarkCircular (painter, plist.at(i), m_attr.minMarkColor, m_attr.minMarkSize);    break;
                case 1:  drawMarkRectangle(painter, plist.at(i), m_attr.minMarkColor, m_attr.minMarkSize, a); break;
                default: break;
                }
            } else {
                switch (m_attr.hourMark) {
                case 0:  drawMarkCircular (painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize);      break;
                case 1:  drawMarkRectangle(painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize,   a); break;
                case 2:  drawMarkNumber   (painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize, i/5); break;
                default: break;
                }
            }
            a += s;
        }
    }
    else {
        int iWidth=rect().width();
        int iHeight=rect().height();
        if(iWidth>=iHeight)
        {
            QRect rttemp((iWidth-iHeight)/2,0,iHeight,iHeight);
            painter->drawImage(rttemp, *m_pBiaoPanImage);
        }
        else {
            QRect rttemp(0,(iHeight-iWidth)/2,iWidth,iWidth);
            painter->drawImage(rttemp, *m_pBiaoPanImage);
        }
    }
}

void eAClock::drawMarkCircular(QPainter *painter, const QPointF &pos, const QColor &color, qreal diameter)
{
    QPointF cp(pos.x(), pos.y());
    qreal r = diameter / 2;
    painter->save();
    painter->setBrush(color);
    painter->setPen(color);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawEllipse(cp, r, r);
    painter->restore();
}

void eAClock::drawMarkRectangle(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, qreal angle)
{
    QPointF cp(pos.x(), pos.y());
    QRectF rect(-len/2, -len/2, len, len);
    painter->save();
    painter->setBrush(color);
    painter->setPen(color);
    painter->translate(cp);
    painter->rotate(angle);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawRect(rect);
    painter->restore();
}

void eAClock::drawMarkNumber(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, int num)
{
    QRectF rect(pos.x()-len/2, pos.y()-len/2, len, len);
    QFont font;
    font.setFamily("Arial");
    font.setPointSizeF(len*0.75);
    QTextOption opt;
    opt.setAlignment(Qt::AlignCenter);
    painter->save();
    painter->setPen(color);
    painter->setFont(font);
    painter->setRenderHint(QPainter::Antialiasing);
    if(num==0)
        num=12;
    painter->drawText(rect, QString("%1").arg(num), opt);
    painter->restore();
}

void eAClock::paintHand(QPainter *painter)
{
    const qreal sMS = 6;
    const qreal sH  = 30;
    QDateTime dt = QDateTime::currentDateTime().toTimeZone(QTimeZone(m_attr.timeZoneId));
    QTime t = dt.time();
    drawHand(painter, t.hour()   * sH,  m_attr.hourHandColor, radius()/2,   radius() / 20);
    drawHand(painter, t.minute() * sMS, m_attr.minHandColor,  radius()*3/4, radius() / 30);
    drawHand(painter, t.second() * sMS, m_attr.secHandColor,  radius(),     radius() / 40);
}

void eAClock::drawHand(QPainter *painter, qreal angle, const QColor &color, qreal len, qreal base)
{
    QPointF cp = center();
    QPointF points[3] = {
        QPointF(-base,    0),
        QPointF( base,    0),
        QPointF(    0, -len),
    };
    painter->save();
    painter->setBrush(color);
    painter->setPen(color);
    painter->translate(cp);
    painter->rotate(angle);
    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawPolygon(points, 3);
    painter->restore();
}

void eAClock::paintDate(QPainter *painter)
{
    if(!m_attr.date) return;
    QDateTime dt = QDateTime::currentDateTime().toTimeZone(QTimeZone(m_attr.timeZoneId));
    QDate date = dt.date();
    QString text = date.toString("dd/MM/yyyy\ndddd");
    QRectF r(0, rect().height()*5/8, rect().width(), rect().height()/4);
    QFont font;
    font.setFamily(m_attr.dateFontFamily);
    font.setPointSizeF(m_attr.dateFontSize);
    font.setBold(m_attr.dateFontBold);
    font.setItalic(m_attr.dateFontItalics);
    font.setUnderline(m_attr.dateFontUnderline);
    QTextOption opt;
    opt.setAlignment(Qt::AlignCenter);
    painter->save();
    painter->setPen(m_attr.dateColor);
    MACRO_FONT_FANG_JUCHI_2(font)
    painter->setFont(font);
    painter->setRenderHint(QPainter::Antialiasing, false);
//    painter->setRenderHint(QPainter::Antialiasing);
    painter->drawText(r, text, opt);
    painter->restore();
}

void eAClock::paintText(QPainter *painter)
{
    if(m_attr.text.isNull() || m_attr.text.isEmpty()) return;
    QRectF r(0, rect().height()/6, rect().width(), rect().height()/4);
    QFont font;
    font.setFamily(m_attr.textFontFamily);
    font.setPointSizeF(m_attr.textFontSize);
    font.setBold(m_attr.textFontBold);
    font.setItalic(m_attr.textFontItalics);
    font.setUnderline(m_attr.textFontUnderline);
    QTextOption opt;
    opt.setAlignment(Qt::AlignCenter);
    painter->save();
    painter->setPen(m_attr.textColor);
    MACRO_FONT_FANG_JUCHI_2(font)

    painter->setFont(font);
    //painter->setRenderHint(QPainter::Antialiasing);
    painter->setRenderHint(QPainter::Antialiasing, false);
    painter->drawText(r, m_attr.text, opt);
    painter->restore();
}

void eAClock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->save();
    paintDial(painter);
    paintDate(painter);
    paintText(painter);
    paintHand(painter);
    painter->restore();
    eObject::paint(painter, option, widget);
}

QWidget* eAClock::wAttr()
{
    QWidget *wObj = eObject::wAttr();
    QWidget *w = wAttrElement();
    static_cast<QBoxLayout*>(w->layout())->insertWidget(0, wObj);
    return w;
}

QWidget* eAClock::wAttrElement()
{
    eAClockAttr *w = new eAClockAttr(m_attr);
    connect(w, SIGNAL(sAttrChanged(const eAClock::Data &)), this, SLOT(onAttrChanged(const eAClock::Data &)));
    return w;
}
QJsonObject eAClock::save(const QString &pRoot)
{

    if(!m_attr.bCustomDial)
    {

    }
    else {

        QString file0 = m_attr.path + PAGEDEL_SUFFIX + MACRO_FENGEDANFU + m_attr.name;
        QString file1 = m_attr.path + MACRO_FENGEDANFU + m_attr.name;
        QFile f0(file0);
        QFile f1(file1);

        QString old_file;
        QString file_full=old_file.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);
        QString new_file = pRoot + MACRO_FENGEDANFU + m_attr.name;
        if(f0.exists()) {
            old_file = file0;
        } else if(f1.exists()) {
            old_file = file1;
        } else {//自己画点，不用背景表盘
           return elementJson();
        }

        QFile old_f(old_file);
        QFile new_f(new_file);
        if(!new_f.exists())
            old_f.copy(new_file);
//        m_attr.path = pRoot;
//        m_attr.path.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);

    }
    QRectF r = geometry();
    QString strDir=QString("%1%2%3%4%5").arg(zValue()).arg(r.x()).arg(r.y()).arg(r.width()).arg(r.height());

    m_attr.selfCreateDialName=strDir+".png";
    m_attr.path = pRoot;
    m_attr.path.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);
    QPixmap *tempPixamp=new QPixmap(r.width(),r.height());
    tempPixamp->fill(Qt::transparent);
    QPainter painter;
    painter.begin(tempPixamp);
    this->paintDial(&painter);
    this->paintText(&painter);
    painter.end();
    QString strSaveFile=pRoot+MACRO_FENGEDANFU+strDir+".png";
    strSaveFile.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);
    tempPixamp->save(strSaveFile,"PNG");
    delete  tempPixamp;
   //生成表盘背景图
   return elementJson();


}
QJsonObject eAClock::elementJson() const
{
    QJsonObject oRoot;
    QJsonObject oWidget;
    QJsonObject oDate;
    QJsonObject oText;
    QJsonObject oPlay;
    auto at = LoAppTools::getInstance();

    oRoot["elementType"]   = "AClock";
    oRoot["elementTypeId"] = type();
    oRoot["geometry"]      = eObject::elementJson();

    oWidget["timeZone"]          = QString().append(m_attr.timeZoneId);
    oWidget["hourMark"]          = m_attr.hourMark;
    oWidget["hourMarkSize"]      = m_attr.hourMarkSize;
    oWidget["hourMarkColor"]     = at->color2Int(m_attr.hourMarkColor);
    oWidget["minMark"]           = m_attr.minMark;
    oWidget["minMarkSize"]       = m_attr.minMarkSize;
    oWidget["minMarkColor"]      = at->color2Int(m_attr.minMarkColor);
    oWidget["hourHandColor"]     = at->color2Int(m_attr.hourHandColor);
    oWidget["minHandColor"]      = at->color2Int(m_attr.minHandColor);
    oWidget["secHandColor"]      = at->color2Int(m_attr.secHandColor);
    oWidget["date"]              = m_attr.date;
    oWidget["dateFontFamily"]    = m_attr.dateFontFamily;
    oWidget["dateFontSize"]      = m_attr.dateFontSize;
    oWidget["dateFontBold"]      = m_attr.dateFontBold;
    oWidget["dateFontItalics"]   = m_attr.dateFontItalics;
    oWidget["dateFontUnderline"] = m_attr.dateFontUnderline;
    oWidget["dateColor"]         = at->color2Int(m_attr.dateColor);
    oWidget["text"]              = m_attr.text;
    oWidget["textFontFamily"]    = m_attr.textFontFamily;
    oWidget["textFontSize"]      = m_attr.textFontSize;
    oWidget["textFontBold"]      = m_attr.textFontBold;
    oWidget["textFontItalics"]   = m_attr.textFontItalics;
    oWidget["textFontUnderline"] = m_attr.textFontUnderline;
    oWidget["textColor"]         = at->color2Int(m_attr.textColor);
    oWidget["path"]     = m_attr.path;
    oWidget["name"]     = m_attr.name;
    oWidget["selfCreateDialName"]     = m_attr.selfCreateDialName;
    oWidget["bCustomDial"]     = m_attr.bCustomDial;

    oRoot["widget"]              = oWidget;

    oPlay["duration"] = m_attr.playDuration;
    oRoot["play"]     = oPlay;
    return oRoot;
}

void eAClock::onAttrChanged(const eAClock::Data &data)
{
    QString strbk=data.path+MACRO_FENGEDANFU+data.name;
    strbk.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);
    QString strOldBk=m_attr.path+MACRO_FENGEDANFU+m_attr.name;
    strOldBk.replace(MACRO_DANYINFANXIEGAN, MACRO_DANYINXIEGAN);
    m_attr = data;
  //  if(strOldBk!=strbk)
    {
        if(!data.bCustomDial)
        {
            if(m_pBiaoPanImage!=nullptr)
                delete m_pBiaoPanImage;
            m_pBiaoPanImage=nullptr;
        }
        else {
            if(m_pBiaoPanImage!=nullptr)
                delete m_pBiaoPanImage;
            m_pBiaoPanImage= new QImage(strbk);
         }

    }
    updateGeometry();
}
