/*
    Copyright (c) 2008 Louai Al-Khanji

    This file is part of Safra.

    Safra is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2 as published
    by the Free Software Foundation.

    Safra 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 Safra; see the file COPYING. If not, see
    <http://www.gnu.org/licenses/>.
*/

#include <QVBoxLayout>
#include <QTabBar>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QVariant>
#include <QStyle>
#include <QStyleOptionTabWidgetFrame>
#include <QStylePainter>

#include <KIcon>

#include "mainwidget.h"
#include "webview.h"

static const qreal INACTIVE_Z = 0.0;
static const qreal ACTIVE_Z = 1.0;

Q_DECLARE_METATYPE(QGraphicsProxyWidget*)

MainWidget::MainWidget(QWidget* parent)
: QWidget(parent), m_tabbar(0), m_view(0), m_scene(0)
{
    m_tabbar = new QTabBar(this);
    m_view = new QGraphicsView(this);
    m_scene = new QGraphicsScene(this);

    connect(m_tabbar, SIGNAL(currentChanged(int)),
            this, SLOT(activateView(int)));

    m_tabbar->setDrawBase(false);

    m_view->setScene(m_scene);
    m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    QVBoxLayout* layout = new QVBoxLayout;
    layout->addWidget(m_tabbar);
    layout->addWidget(m_view);
    setLayout(layout);

    setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding,
                               QSizePolicy::TabWidget));
    setFocusPolicy(Qt::TabFocus);
    setFocusProxy(m_tabbar);

    doLayouts();
}

WebView* MainWidget::currentView() const
{
    WebView* view = 0;
    if (m_current) {
        view = qobject_cast<WebView*>(m_current->widget());
    }
    return view;
}

int MainWidget::newView()
{
    WebView* wv = new WebView;
    QGraphicsProxyWidget* proxy = m_scene->addWidget(wv);
    int index = m_tabbar->addTab("Dummy");
    QVariant variant = QVariant::fromValue(proxy);
    m_tabbar->setTabData(index, variant);
    m_tabbar->setTabIcon(index, KIcon("emblem-symbolic-link"));
    m_tabbar->setCurrentIndex(index);
    wv->show();

    QMetaObject::invokeMethod(this, "activateView", Qt::QueuedConnection,
                               Q_ARG(int, index));

    return index;
}

void MainWidget::activateView(int index)
{
    doLayouts();

    QVariant variant = m_tabbar->tabData(index);
    QGraphicsProxyWidget* proxy = variant.value<QGraphicsProxyWidget*>();
    if (proxy) {
        if (m_current) {
            m_current->setZValue(INACTIVE_Z);
        }

        proxy->setZValue(ACTIVE_Z);
        m_current = proxy;

        m_view->resetTransform();

        proxy->setPos(m_view->mapToScene(0, 0));
        proxy->resize(m_view->viewport()->size());
        m_scene->setSceneRect(proxy->rect());
        proxy->setFocus();
    }

    update();
}

void MainWidget::resizeEvent(QResizeEvent* event)
{
    QWidget::resizeEvent(event);

    int index = m_tabbar->currentIndex();
    QMetaObject::invokeMethod(this, "activateView", Qt::QueuedConnection,
                               Q_ARG(int, index));
}

void MainWidget::paintEvent(QPaintEvent* event)
{
    QWidget::paintEvent(event);

    doLayouts();

    QStylePainter p(this);
    QStyleOptionTabWidgetFrame opt;
    initStyleOption(&opt);
    opt.rect = m_panelRect;
    p.drawPrimitive(QStyle::PE_FrameTabWidget, opt);
}

void MainWidget::initStyleOption(QStyleOptionTabWidgetFrame* option)
{
    option->initFrom(this);
    option->rightCornerWidgetSize = QSize(0, 0);
    option->leftCornerWidgetSize = QSize(0, 0);
    option->shape = QTabBar::RoundedNorth;

    QSize t(0, m_view->frameWidth());
    if (m_tabbar->isVisibleTo(this)) {
        t = m_tabbar->sizeHint();
    }
    option->tabBarSize = t;
}

void MainWidget::doLayouts()
{
    // TODO: implement corner widgets similar to qtabwidget

    QStyleOptionTabWidgetFrame option;
    initStyleOption(&option);

    QRect tabRect = style()->subElementRect(QStyle::SE_TabWidgetTabBar, &option, this);
    m_panelRect = style()->subElementRect(QStyle::SE_TabWidgetTabPane,&option, this);
    QRect contentsRect = style()->subElementRect(QStyle::SE_TabWidgetTabContents, &option, this);
//     QRect leftCornerRect = style()->subElementRect(QStyle::SE_TabWidgetLeftCorner, &option, this);
//     QRect rightCornerRect = style()->subElementRect(QStyle::SE_TabWidgetRightCorner, &option, this);

    m_tabbar->setGeometry(tabRect);
    m_view->setGeometry(contentsRect);
//     if (d->leftCornerWidget)
//         d->leftCornerWidget->setGeometry(leftCornerRect);
//     if (d->rightCornerWidget)
//         d->rightCornerWidget->setGeometry(rightCornerRect);
}

#include "mainwidget.moc"
