/***************************************************************************
 *   Copyright (c) 2009  Peter Mylemans <peter.mylemans@gmail.com>         *
 *                                                                         *
 *   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 2 of the License, 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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#include "SideBar.h"

#include "SideBarButton.h"

/*!
    \class SideBar
    \brief The SideBar class represents a vertical tabbar (sidebar).
*/

/*!
    Constructs a new sidebar with the specified \a parent.
*/
SideBar::SideBar(QWidget *parent)
    : QWidget(parent), m_activeButton(NULL)
{
    m_emptyWidget = new QWidget(this);

    m_hlayout = new QHBoxLayout();
    m_vlayout = new QVBoxLayout();

    setLayout(m_hlayout);
    m_hlayout->addLayout(m_vlayout, 0);
    m_hlayout->addWidget(m_emptyWidget);

    // Add stretch to fill up space below buttons.
    m_vlayout->addStretch(1);
    
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
}


/*!
    Destroys this sidebar.
*/
SideBar::~SideBar()
{
    delete m_hlayout;
    delete m_vlayout;
}

/*!
    Adds a tab with the specified \a text and \a tabPanel.

    This method will append a new sidebar button. If that sidebar button is clicked, the specified
    \a tabPanel will be shown.

    \pre tabPanel can't be NULL.

    \returns index of the newly added tab. Index is negative if an error occurred.
*/
int SideBar::addTab(const QString &text, QWidget *tabPanel)
{
    if (tabPanel == NULL)
        return -1;

    tabPanel->hide();

    SideBarButton *button = new SideBarButton(this, tabPanel);
    button->setText(text);

    connect(button, SIGNAL(clicked(bool)), this, SLOT(sideBarButtonChecked(bool)));

    // Insert after previous buttons and BEFORE the spacer.
    m_vlayout->insertWidget(m_buttons.size(), button, 0, Qt::AlignTop);

    m_buttons.append(button);
    return m_buttons.size() - 1;
}

/*!
    Returns the index of the active tab of this sidebar.
*/
int SideBar::activeTab()
{
    return m_buttons.indexOf(m_activeButton, 0);
}

/*!
    Hides the active tab of this sidebar.
*/
void SideBar::hideActiveTab()
{
    if (m_activeButton == NULL)
    {
        m_hlayout->removeWidget(m_emptyWidget);
        return;
    }

    m_hlayout->removeWidget(m_activeButton->associatedWidget());
    m_activeButton->setChecked(false);
    m_activeButton->associatedWidget()->hide();
    m_activeButton = NULL;
}

/*!
    Changes the active tab of this sidebar to the tab with the specified \a index.
*/
void SideBar::setActiveTab(int index)
{
    // Valid index required
    if (index < 0 || index >= m_buttons.size())
        return;

    showTab(m_buttons.at(index));
}

/*!
    Called when a sidebar button is clicked.

    Use sender() to determine the which sidebar button has sent the signal.
*/
void SideBar::sideBarButtonChecked(bool checked)
{
    hideActiveTab();

    SideBarButton *button = static_cast<SideBarButton*>(sender());
    if (checked)
        showTab(button);
    else
        showTab(NULL);
}

/*!
    Shows the tab associated with \a button. That tab will automatically become the active tab.

    If \a button is NULL, this sidebar will be collapsed.
*/
void SideBar::showTab(SideBarButton *button)
{
    if (button != NULL) {
        bool collapsed = (m_activeButton == NULL);
        m_hlayout->addWidget(button->associatedWidget());
        button->setChecked(true);
        m_activeButton = button;
        m_activeButton->associatedWidget()->show();

        if (collapsed)
            collapsedChanged(false);
    } else {
        m_hlayout->addWidget(m_emptyWidget);
        emit collapsedChanged(true);
    }
}

