/*
 * Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
 *
 * 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, 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 <http://www.gnu.org/licenses/>.
 *
**/
#include "iconedit.h"
#include "imageutil.h"
#include "configuration.h"
#include <QGSettings>
#include <QHBoxLayout>
#include <QWidget>
#include <QPainter>
#include <QFile>
#include <QKeyEvent>
#include <QDebug>
#include <QTimer>
#include <QDir>
#include <QtX11Extras/QX11Info>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>

#define DRM_DIR "/sys/class/leds/"

#define GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD "org.ukui.peripherals-keyboard"
#define CAPSLOCK_STATUS "capslock_state"
/**
 * @brief 判断大写键状态
 * @return true: 大写锁定
 */
bool checkCapsLockState()
{
    QDir ledDir(DRM_DIR);
    QStringList leds = ledDir.entryList(QDir::Dirs);
    QString capsFile;

    for(int i = 0;i<leds.count();i++){
        if(leds.at(i).contains("capslock"))
            capsFile = leds.at(i);
    }
    QFile drmStatusFile(DRM_DIR + capsFile + "/brightness");
    if(drmStatusFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QTextStream in(&drmStatusFile);
        QString status = in.readLine();

        if(status == "0") {
            return false;
        }else{
            return true;
        }
    }

    bool capsState = false;
    unsigned int n;
    XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &n);
    capsState = (n & 0x01) == 1;

    return capsState;
}


IconEdit::IconEdit(QWidget *parent)
    : QWidget(parent),
      m_timer(nullptr),
      configuration(Configuration::instance())
{
    curFontSize = configuration->getFontSize();
    m_ptToPx = configuration->getPtToPx();
    m_edit = new QLineEdit(this);
    m_edit->setObjectName(QStringLiteral("passwdEdit"));
    m_edit->setAttribute(Qt::WA_InputMethodEnabled, false); //禁用输入法
    m_edit->setContextMenuPolicy(Qt::NoContextMenu);    //禁用右键菜单
    m_edit->installEventFilter(this);
    QFont sysFont;
    sysFont.setPointSize((16 + curFontSize) *m_ptToPx);
    m_edit->setFont(sysFont);

    m_capsIcon = new QSvgWidget(this);
    m_capsIcon->setObjectName(QStringLiteral("capsIconLabel"));

    if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland"){
        capsState = checkCapsLockState();
    }else{
        settings = new QGSettings(GSETTINGS_SCHEMA_PERIPHERALS_KEYBOARD, "", this);
        connect(settings, &QGSettings::changed,
            this, &IconEdit::onCapsChanged);
        capsState = settings->get("capslock-state").toBool();
    }

    m_capsIcon->setVisible(capsState);
    m_capsIcon->load(QString(":/image/assets/capslock.svg"));

    m_iconButton = new QPushButton(this);
    m_iconButton->setFixedSize(24, 24);
    m_iconButton->setIconSize(QSize(24, 24));
    m_iconButton->setObjectName(QStringLiteral("loginButton"));
    m_iconButton->setCursor(QCursor(Qt::PointingHandCursor));
    m_iconButton->installEventFilter(this);
    m_iconButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #3D6BE5;");

    m_modeButton = new ModeButton(this);
    m_modeButton->setObjectName(QStringLiteral("echoModeButton"));
    m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic"));
    m_modeButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
    m_modeButton->setCursor(Qt::PointingHandCursor);
    m_modeButton->installEventFilter(this);
    m_modeButton->setFixedSize(24, 14);
    m_modeButton->setIconSize(QSize(16, 16));
    m_modeButton->setFlat(true);
    connect(m_modeButton, &QPushButton::clicked, this, [=](){
        if (m_edit->echoMode() == QLineEdit::Password) {
            setType(QLineEdit::Normal);
        } else {
            setType(QLineEdit::Password);
        }
    });

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setContentsMargins(1, 1, 8, 1);
    layout->setSpacing(2);
    layout->addStretch();
    layout->addWidget(m_capsIcon);
    layout->addWidget(m_modeButton);
    layout->addWidget(m_iconButton);

    connect(m_edit, &QLineEdit::returnPressed, this, &IconEdit::clicked_cb);
    connect(m_iconButton, &QPushButton::clicked, this, &IconEdit::clicked_cb);

    setFocusProxy(m_edit);
    //setCapsState(checkCapsState());
}

bool IconEdit::eventFilter(QObject *obj, QEvent *event)
{
    if(obj == m_edit){
        if(event->type() == 6){ //禁止复制粘贴功能。
            QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
            if(keyEvent->matches(QKeySequence::Copy) || keyEvent->matches(QKeySequence::Cut) || keyEvent->matches(QKeySequence::Paste)){
                event->ignore();
                return true;
            }else if((keyEvent->modifiers() & Qt::MetaModifier) || (keyEvent->modifiers() & Qt::AltModifier)){//当meta或者alt键被按下时，忽略按键事件
                event->ignore();
                return true;
            }
        }
        if(event->type() == 2)
        {
            setFocusin(0);
            Q_EMIT clickedPassword(true);
        }
        if(event->type() == 23)
        {
            if(QX11Info::isPlatformX11()){
                //XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime);
            }
            update();
        }else if(event->type() == QEvent::MouseButtonPress){
            if(QX11Info::isPlatformX11()){
                //XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime);
            }
            update();
        } else if(event->type() == QEvent::MouseButtonRelease) { //禁用鼠标中键
            QMouseEvent *mouseevent = static_cast<QMouseEvent*>(event);
            if(mouseevent->button() == Qt::MidButton){
                event->ignore();
                return true;
            }
        }
    }
    if(obj == m_iconButton){
        if(m_timer && m_timer->isActive())
        {
            return false;
        }
        if(event->type() == 2)
        {
            setFocusin(0);
            Q_EMIT clickedPassword(true);
        }
    }
    if(obj == m_modeButton){
        if(event->type() == 2)
        {
            setFocusin(0);
            Q_EMIT clickedPassword(true);
        }
    }
    return false;
}

void IconEdit::setType(QLineEdit::EchoMode type)
{
    m_edit->setEchoMode(type);
    if (type == 0) {
       m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-display-symbolic"));
    } else {
       m_modeButton->setIcon(QIcon::fromTheme("ukui-eye-hidden-symbolic"));
    }
}

void IconEdit::setModeBtnVisible(bool visible)
{
    m_modeButton->setVisible(visible);
}

void IconEdit::resizeEvent(QResizeEvent *)
{
    // 设置输入框中文件输入区，不让输入的文字在被隐藏在按钮下
    int w = m_iconButton->width() + m_modeButton->width();
    m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 10 : w + 6, 1);
    m_edit->setFixedSize(size());
}


void IconEdit::setX11Focus()
{
    if(QX11Info::isPlatformX11()){
        //XSetInputFocus(QX11Info::display(),this->winId(),RevertToParent,CurrentTime);
    }
    update(); 
}

void IconEdit::setFocusin(int target)
{
    switch (target) {
    case 0:
        m_edit->setFocus();
        m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #3D6BE5;");
        break;
    case 1:
        m_edit->clearFocus();
        m_iconButton->setFocus();
        m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #000000;");
        break;
    default:
        m_iconButton->setStyleSheet("border-radius:12px; border:2px solid #3D6BE5;");
        m_edit->clearFocus();
        break;
    }
}

void IconEdit::clicked_cb()
{
    startWaiting();
    emit clicked(m_edit->text());
}

void IconEdit::onCapsChanged()
{
    if(settings){
        capsState = settings->get("capslock-state").toBool();
    }else{
        capsState = checkCapsLockState();
    }
    m_capsIcon->setVisible(capsState);
    int w = m_iconButton->width() + m_modeButton->width();
    m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 10 : w + 6, 1);
}

void IconEdit::onCapsStateChanged()
{
    capsState = checkCapsLockState();
    m_capsIcon->setVisible(capsState);
    int w = m_iconButton->width() + m_modeButton->width();
    m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() + 10 : w + 6, 1);
}

void IconEdit::setIcon(const QString &text)
{
    m_iconButton->setIcon(QIcon());
    m_iconButton->setText(text);
    m_iconText = text;
    m_icon = QIcon();
}

void IconEdit::setIcon(const QIcon &icon)
{
    m_iconButton->setIcon(icon);
    m_iconButton->setIconSize(QSize(12,12));
    m_iconButton->setText("");
    m_icon = icon;
    m_iconText = "";
}

void IconEdit::clear()
{
    m_edit->setText("");
    setPrompt("");
}

void IconEdit::clearText()
{
    m_edit->setText("");
}

void IconEdit::setPrompt(const QString &prompt)
{
    m_edit->setPlaceholderText(prompt);
    QPalette palette = m_edit->palette();
    palette.setColor(QPalette::Normal, QPalette::PlaceholderText, Qt::gray);
    m_edit->setPalette(palette);
}

const QString IconEdit::text()
{
    return m_edit->text();
}

void IconEdit::readOnly(bool enabled)
{
    m_edit->setEnabled(!enabled);
    m_edit->setReadOnly(enabled);
}

void IconEdit::setLocked(bool lock)
{
    m_iconButton->blockSignals(lock);
}

void IconEdit::startWaiting()
{
    m_edit->setReadOnly(true);
    //m_iconButton->setEnabled(false);

    if(!m_timer)
    {
        m_timer = new QTimer(this);
        m_timer->setInterval(150);
        connect(m_timer, &QTimer::timeout, this, &IconEdit::updatePixmap);
    }

    //m_waitingPixmap.load(":/image/assets/ukui-loginopt-face.svg");

//    m_iconButton->setProperty("useIconHighlightEffect", true);
//    m_iconButton->setProperty("iconHighlightEffectMode", 1);
//     m_waitingPixmap = ImageUtil::loadSvg(":/image/assets/ukui-loginopt-face.svg", "white", 24);
//     m_iconButton->setIcon(QIcon(m_waitingPixmap));

    QPixmap icon = QIcon::fromTheme("ukui-loading-0-symbolic").pixmap(16,16);
    m_waitingPixmap = ImageUtil::drawSymbolicColoredPixmap(icon, "white");
    m_iconButton->setIcon(m_waitingPixmap);
    m_iconButton->setIconSize(QSize(16,16));
    m_timer->start();
}


void IconEdit::stopWaiting()
{
    if(m_timer && m_timer->isActive())
    {
        m_timer->stop();
    }
    m_iconButton->setAttribute(Qt::WA_TransparentForMouseEvents, false);
    m_edit->setReadOnly(false);
    //m_iconButton->setEnabled(true);
    if(!m_icon.isNull()) {
        m_iconButton->setIcon(m_icon);
        m_iconButton->setIconSize(QSize(12,12));
    }
    else
        m_iconButton->setText(m_iconText);
}

void IconEdit::updatePixmap()
{
    m_iconButton->setEnabled(true);
    m_iconButton->setAttribute(Qt::WA_TransparentForMouseEvents, true);
    QMatrix matrix;
    matrix.rotate(90.0);
    m_waitingPixmap = m_waitingPixmap.transformed(matrix, Qt::FastTransformation);
    m_iconButton->setIcon(QIcon(m_waitingPixmap));
    m_iconButton->setIconSize(QSize(16, 16));
}
/*
void IconEdit::setCapsState(bool capsState)
{
    m_capsIcon->setVisible(capsState);
    int w = m_iconButton->width() + m_modeButton->width();
    m_edit->setTextMargins(1, 1, capsState ? w + m_capsIcon->width() : w, 1);
}
*/
