/// QasTools: Desktop toolset for the Linux sound system ALSA.
/// \copyright See COPYING file.

#include "multi_page_dialog.hpp"
#include "wdg/scroll_area_vertical.hpp"
#include <QGroupBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QListView>
#include <QPushButton>
#include <QSplitter>
#include <QStackedLayout>
#include <QStandardItem>
#include <QStandardItemModel>
#include <QVBoxLayout>
#include <QtGlobal>
#include <iostream>

namespace Views
{

Multi_Page_Dialog::Multi_Page_Dialog ( QWidget * parent_n,
                                       Qt::WindowFlags flags_n )
: Views::Basic_Dialog ( parent_n, flags_n )
{
  {
    _pages_model = new QStandardItemModel ( this );
    _page_selection = new QListView;
    _page_selection->setModel ( _pages_model );

    // QueuedConnection to paint update the tree view before
    // painting heavy new widgets
    connect (
        _page_selection->selectionModel (),
        SIGNAL ( currentChanged ( const QModelIndex &, const QModelIndex & ) ),
        this,
        SLOT ( page_changed ( const QModelIndex &, const QModelIndex & ) ),
        Qt::QueuedConnection );
  }

  // Close button layout
  QHBoxLayout * lay_close ( new QHBoxLayout );
  {
    QPushButton * btn_close ( create_close_button () );

    lay_close->setContentsMargins ( 0, 0, 0, 0 );
    lay_close->addStretch ( 1 );
    lay_close->addWidget ( btn_close, 0 );
    lay_close->addStretch ( 1 );
  }

  // Page selection widget
  QWidget * navi_wdg ( new QWidget );
  {
    QVBoxLayout * lay_vbox ( new QVBoxLayout );
    lay_vbox->addWidget ( _page_selection, 1 );
    lay_vbox->addLayout ( lay_close, 0 );
    navi_wdg->setLayout ( lay_vbox );
    {
      QMargins margs = lay_vbox->contentsMargins ();
      // Clear all but right
      margs.setLeft ( 0 );
      margs.setTop ( 0 );
      margs.setBottom ( 0 );
      lay_vbox->setContentsMargins ( margs );
    }
  }

  // Page display widget
  QWidget * pages_wdg ( new QWidget );
  {
    QHBoxLayout * lay_pages ( new QHBoxLayout );
    lay_pages->setContentsMargins ( 0, 0, 0, 0 );
    pages_wdg->setLayout ( lay_pages );

    _lay_pages_stack = new QStackedLayout;
    _lay_pages_stack->setContentsMargins ( 0, 0, 0, 0 );

    lay_pages->addSpacing ( fontMetrics ().averageCharWidth () * 3 / 2 );
    lay_pages->addLayout ( _lay_pages_stack );
  }

  // Main splitter and layout
  {
    _splitter = new QSplitter;
    _splitter->setChildrenCollapsible ( false );
    _splitter->addWidget ( navi_wdg );
    _splitter->addWidget ( pages_wdg );
    _splitter->setStretchFactor ( 0, 0 );
    _splitter->setStretchFactor ( 1, 1 );

    set_central_widget ( _splitter );
  }
}

Multi_Page_Dialog::~Multi_Page_Dialog () = default;

void
Multi_Page_Dialog::add_pages_begin ()
{
}

void
Multi_Page_Dialog::add_pages_end ()
{
  // Width hint for the page selection side of the splitter
  int whint = qMax ( _page_selection->sizeHintForColumn ( 0 ), 0 );
  whint += qMax ( _page_selection->frameWidth () * 2, 0 );
  // Add margins
  {
    auto add_margins = [ &whint ] ( const QMargins & margs_n ) {
      whint += qMax ( margs_n.left (), 0 );
      whint += qMax ( margs_n.right (), 0 );
    };
    add_margins ( _page_selection->contentsMargins () );
    if ( QWidget * wdg = _splitter->widget ( 0 ); wdg != nullptr ) {
      add_margins ( wdg->contentsMargins () );
      if ( QLayout * lay = wdg->layout (); lay != nullptr ) {
        add_margins ( lay->contentsMargins () );
      }
    }
  }

  // Set splitter sizes
  {
    QList< int > sizes;
    sizes.reserve ( 2 );
    sizes.push_back ( whint );
    sizes.push_back ( qMax ( sizeHint ().width (), 100 ) );
    _splitter->setSizes ( sizes );
  }
}

void
Multi_Page_Dialog::add_page ( const QString & name_n, QWidget * wdg_n )
{
  if ( wdg_n == nullptr ) {
    return;
  }

  // Add widget
  _lay_pages_stack->addWidget ( wdg_n );

  // Add selection entry
  {
    QStandardItem * sitem ( new QStandardItem );
    sitem->setText ( name_n );
    sitem->setToolTip ( name_n );
    sitem->setSelectable ( true );
    sitem->setEditable ( false );

    _pages_model->appendRow ( sitem );
  }
}

void
Multi_Page_Dialog::add_page_vscroll ( const QString & name_n, QWidget * wdg_n )
{
  if ( wdg_n == nullptr ) {
    return;
  }

  // Add widget
  {
    Wdg::Scroll_Area_Vertical * vscroll ( new Wdg::Scroll_Area_Vertical );
    vscroll->setFrameStyle ( QFrame::NoFrame );
    vscroll->set_widget ( wdg_n );

    add_page ( name_n, vscroll );
  }
}

std::size_t
Multi_Page_Dialog::num_pages () const
{
  return _lay_pages_stack->count ();
}

std::size_t
Multi_Page_Dialog::current_page_idx () const
{
  return _lay_pages_stack->currentIndex ();
}

void
Multi_Page_Dialog::set_current_page_idx ( std::size_t idx_n )
{
  _page_selection->setCurrentIndex (
      _pages_model->index ( idx_n, 0, QModelIndex () ) );
}

QByteArray
Multi_Page_Dialog::splitter_state () const
{
  return _splitter->saveState ();
}

void
Multi_Page_Dialog::restore_splitter_state ( const QByteArray & state_n )
{
  if ( !state_n.isEmpty () ) {
    _splitter->restoreState ( state_n );
  }
}

void
Multi_Page_Dialog::page_changed ( const QModelIndex & cur_n,
                                  const QModelIndex & )
{
  page_selected ( cur_n );
}

void
Multi_Page_Dialog::page_selected ( const QModelIndex & index_n )
{
  QModelIndex root_idx;
  int rows = _pages_model->rowCount ( root_idx );
  for ( int ii = 0; ii < rows; ++ii ) {
    if ( _pages_model->index ( ii, 0, root_idx ) == index_n ) {
      _lay_pages_stack->setCurrentIndex ( ii );
      break;
    }
  }
}

} // namespace Views
