#include "TitleBar.h"
#include "Skin.h"
#include "StateButton.h"
#include <qdrawutil.h>

TitleBar::TitleBar(QWidget *parent, Skin *skin)
    : QWidget(parent), left_pressed_(false), show_style_(FORM_STYLE) // default: show all title buttons
      ,
      is_maxed_(false), skin_(skin)
{
    init();
}

TitleBar::~TitleBar()
{
}

int TitleBar::init()
{
    hbox_layout_ = new QHBoxLayout(this);
    icon_ = new QLabel(this);
    title_ = new QLabel(this);
    skin_button_ = new StateButton(this);
    menu_button_ = new StateButton(this);
    min_button_ = new StateButton(this);
    max_button_ = new StateButton(this);
    close_button_ = new StateButton(this);

    // 设置name以方便使用 CSS
    icon_->setObjectName("title_bar_icon");
    title_->setObjectName("title_bar_text");
    skin_button_->setObjectName("title_bar_skin");
    menu_button_->setObjectName("title_bar_menu");
    min_button_->setObjectName("title_bar_min");
    max_button_->setObjectName("title_bar_max");
    close_button_->setObjectName("title_bar_close");

    // load Skin
    if (NULL == skin_)
    {
        skin_ = skinman->default_skin();
    }
    load_skin_internal();

    // title
    title_->setText("Title bar");

    const int frame_width = 5;

    // layout
    hbox_layout_->addWidget(icon_, 0, Qt::AlignVCenter);
    hbox_layout_->addSpacing(frame_width);
    hbox_layout_->addWidget(title_, 0, Qt::AlignVCenter);
    hbox_layout_->addStretch();
    hbox_layout_->addWidget(skin_button_, 0, Qt::AlignTop);
    hbox_layout_->addWidget(menu_button_, 0, Qt::AlignTop);
    hbox_layout_->addWidget(min_button_, 0, Qt::AlignTop);
    hbox_layout_->addWidget(max_button_, 0, Qt::AlignTop);
    hbox_layout_->addWidget(close_button_, 0, Qt::AlignTop);

    hbox_layout_->setSpacing(0);

    //
    setLayout(hbox_layout_);
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    //
    connect(skin_button_, SIGNAL(clicked()), this, SIGNAL(skin_clicked()));
    connect(menu_button_, SIGNAL(clicked()), this, SIGNAL(menu_clicked()));
    connect(min_button_, SIGNAL(clicked()), this, SLOT(show_small()));
    connect(max_button_, SIGNAL(clicked()), this, SLOT(show_max_restore()));
    connect(close_button_, SIGNAL(clicked()), window(), SLOT(close()));

    return 0;
}

void TitleBar::load_skin_internal()
{
    // show_style
    int show_style = skin_->titlebar_showstyle();
    if (show_style != -1 && show_style != show_style_)
    {
        show_style_ = show_style;
        widget_set_visible();
    }

    // height
    int h = skin_->titlebar_height();
    switch (h)
    {
    case -1: // 设置为背景图片的高度
    {
        fix_height_to_background();
        break;
    }
    case 0: // 当前样式之标题栏的高度
    {
        int titlebar_height = style()->pixelMetric(QStyle::PM_TitleBarHeight);
        setFixedHeight(titlebar_height);
        break;
    }
    default:
    {
        setFixedHeight(h);
        break;
    }
    }

    // margin
    hbox_layout_->setContentsMargins(skin_->titlebar_background().margin());

    // icon
    icon_->setPixmap(skin_->app_pixmap());
    icon_->setFixedSize(16, 16);
    icon_->setScaledContents(true);

    // title
    title_->setStyleSheet(skin_->titlebar_qss());

    // windows taskbar icon
    window()->setWindowIcon(skin_->app_pixmap());

    //
    skin_button_->set_pixmap(skin_->skin_pixmap());
    menu_button_->set_pixmap(skin_->menu_pixmap());
    min_button_->set_pixmap(skin_->min_pixmap());
    max_button_->set_pixmap(skin_->max_pixmap());
    close_button_->set_pixmap(skin_->close_pixmap());
}

void TitleBar::load_skin(Skin *skin)
{
    if (NULL != skin)
    {
        skin_ = skin;
    }
    load_skin_internal();
}

void TitleBar::show_max_restore()
{
    if (is_maxed_)
    {
        is_maxed_ = false;
        window()->setGeometry(normal_rect_);
        max_button_->set_pixmap(skin_->max_pixmap());
    }
    else
    {
        is_maxed_ = true;
        // avoid max-size overlap taskbar, this BUG still exists until Qt 5.1
        normal_rect_ = window()->geometry();
        window()->setGeometry(QApplication::desktop()->availableGeometry());
        max_button_->set_pixmap(skin_->restore_pixmap());
    }
}

void TitleBar::mousePressEvent(QMouseEvent *e)
{
    QRect r = rect();
    r.adjust(5, 5, -5, -5);
    if (r.contains(e->pos())) // 5:边框大小，边框用来拉伸改变窗口大小
    {
        if (e->button() == Qt::LeftButton)
        {
            left_pressed_ = true;
            click_pos_ = mapToParent(e->pos());
            e->accept();
            return;
        }
    }

    e->ignore();
}

void TitleBar::mouseMoveEvent(QMouseEvent *e)
{
    if (left_pressed_ && !is_maxed_)
    {
        window()->move(e->globalPos() - click_pos_);
        e->accept();
    }
    else
    {
        e->ignore();
    }
}

void TitleBar::mouseReleaseEvent(QMouseEvent *e)
{
    left_pressed_ = false;
    e->ignore();
}

void TitleBar::show_small()
{
    window()->showMinimized();
}

void TitleBar::mouseDoubleClickEvent(QMouseEvent *e)
{
    if (show_style_ & SHOW_MAX_BUTTON)
    {
        show_max_restore();
        left_pressed_ = false;
    }
}

void TitleBar::set_show_style(int style)
{
    show_style_ = style;
    widget_set_visible();
}

void TitleBar::widget_set_visible()
{
    icon_->setVisible(show_style_ & SHOW_ICON);
    title_->setVisible(show_style_ & SHOW_TITLE);
    skin_button_->setVisible(show_style_ & SHOW_SKIN);
    menu_button_->setVisible(show_style_ & SHOW_MENU);
    min_button_->setVisible(show_style_ & SHOW_MIN_BUTTON);
    max_button_->setVisible(show_style_ & SHOW_MAX_BUTTON);
    close_button_->setVisible(show_style_ & SHOW_CLOSE_BUTTON);
}

void TitleBar::paintEvent(QPaintEvent *e)
{
    QWidget::paintEvent(e);

    if (show_style_ & DRAW_BACKGROUND)
    {
        const Border_Image &bi = skin_->titlebar_background();

        QPainter painter(this);
        qDrawBorderPixmap(&painter, rect(), bi.border(), bi.pixmap());
    }
}

void TitleBar::fix_height_to_background()
{
    const Border_Image &bi = skin_->titlebar_background();
    int h = bi.pixmap().height();
    if (h > 0)
    {
        setFixedHeight(h);
    }
}

int TitleBar::str2showstyle(const char *str)
{
    int index = TitleBar::staticMetaObject.indexOfEnumerator("Show_Style");
    QMetaEnum myEnum = TitleBar::staticMetaObject.enumerator(index);
    bool ok = false;
    int ret = myEnum.keyToValue(str, &ok); //-1: error
    return ok ? ret : -1;                  //
}

QHBoxLayout *TitleBar::layout() const
{
    return hbox_layout_;
}

QLabel *TitleBar::icon() const
{
    return icon_;
}

QLabel *TitleBar::title() const
{
    return title_;
}

StateButton *TitleBar::skin_button() const
{
    return skin_button_;
}

StateButton *TitleBar::menu_button() const
{
    return menu_button_;
}

StateButton *TitleBar::min_button() const
{
    return min_button_;
}

StateButton *TitleBar::max_button() const
{
    return max_button_;
}

StateButton *TitleBar::close_button() const
{
    return close_button_;
}
