//
// Created by uos on 2022/4/26.
//

#include "SelectFileTreeView.h"
#include "BaseTableView.h"
#include "BaseItemDelegate.h"
#include "BaseHeaderView.h"

#include <DApplication>
#include <DGuiApplicationHelper>
#include <DPaletteHelper>
#include <DPalette>
#include <DStyle>

#include <QDebug>
#include <QPainter>
#include <QPainterPath>
#include <QHeaderView>
#include <QHoverEvent>
#include <QMouseEvent>
#include <QScroller>
#include <QScrollBar>

SelectFileTreeView::SelectFileTreeView(DWidget *parent)
        : BaseTableView(parent)
{
    m_itemDelegate = new SelectFileItemDelegate(this);
    setItemDelegate(m_itemDelegate);

    setRootIsDecorated(true);
    setItemsExpandable(true);
}

void SelectFileTreeView::paintEvent(QPaintEvent *event)
{

    QPainter painter(viewport());
    painter.save();
    painter.setRenderHints(QPainter::Antialiasing);
    painter.setOpacity(0.03);
    painter.setClipping(true);

    QWidget *wnd = DApplication::activeWindow();
    DPalette::ColorGroup cg;
    if (!wnd) {
        cg = DPalette::Inactive;
    } else {
        cg = DPalette::Active;
    }

    auto style = dynamic_cast<DStyle *>(DApplication::style());
    auto *dAppHelper = DGuiApplicationHelper::instance();
    auto palette = dAppHelper->applicationPalette();

    QBrush bgBrush(palette.color(cg, DPalette::BrightText));

    QStyleOptionFrame option;
    initStyleOption(&option);
    int radius = style->pixelMetric(DStyle::PM_FrameRadius, &option);

    QRect rect = viewport()->rect();
    QRectF clipRect(rect.x(), rect.y() - rect.height(), rect.width(), rect.height() * 2);
    QRectF subRect(rect.x(), rect.y() - rect.height(), rect.width(), rect.height());
    QPainterPath clipPath, subPath;
    clipPath.addRoundedRect(clipRect, radius, radius);
    subPath.addRect(subRect);
    clipPath = clipPath.subtracted(subPath);

    painter.fillPath(clipPath, bgBrush);

    painter.restore();
    DTreeView::paintEvent(event);
}

void SelectFileTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &options,
                            const QModelIndex &index) const
{
    painter->save();
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setOpacity(0.05);
    DPalette::ColorGroup cg;
    if (!(options.state & DStyle::State_Enabled)) {
        cg = DPalette::Disabled;
    } else {
        cg = DPalette::Active;
    }

    auto *style = dynamic_cast<DStyle *>(DApplication::style());

    auto radius = style->pixelMetric(DStyle::PM_FrameRadius, &options);

    auto palette = options.palette;
    QBrush background;
    auto baseColor = palette.color(DPalette::Active, DPalette::BrightText);

    int rowNum = index.row();
    if (index.parent().isValid()) {
        if (index.parent().row() % 2 == 0) {
            rowNum += 1;
        }
    }
    //qInfo() << "col=" << index.column() << "," << "row" << index.row();
    if (rowNum % 2 == 0) {
        background = palette.color(DPalette::Active, DPalette::AlternateBase);
    } else {
        background = baseColor;
    }

    if (options.state & DStyle::State_Enabled) {
        if (selectionModel()->isSelected(index)) {
            background = palette.color(cg, DPalette::Highlight);
            if (m_hover.isValid() && m_hover.row() == index.row()) {
                // hovered
                background = style->adjustColor(background.color(), 0, 0, 20);
            }
        } else {
            if (m_hover.isValid() && m_hover.row() == index.row()) {
                // hovered
                background = style->adjustColor(baseColor, 0, 0, -10);
            }
        }
    }

    // draw row background
    QPainterPath path;
    QRect rowRect { options.rect.x() - header()->offset(),
                    options.rect.y(),
                    header()->length(),
                    options.rect.height() };
    rowRect.setX(rowRect.x());
    rowRect.setWidth(rowRect.width());

    path.addRoundedRect(rowRect, radius, radius);
    painter->fillPath(path, background);
    painter->restore();
    QTreeView::drawRow(painter, options, index);
}

void SelectFileTreeView::setAlwaysChecked(bool checked)
{
    if (m_itemDelegate != nullptr) {
        m_itemDelegate->setAlwaysChecked(checked);
    }
}
