/* ====================================================================
 * Copyright (c) 2007-2009  Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */

// sc
#include "config.h"
#include "WcViewTreeWidget.h"
#include "WcViewTree.h"
#include "WcViewTreeItemModel.h"
#include "WcViewTreeProxyModel.h"
#include "WcViewItemProxyModel.h"
#include "WcViewViewState.h"
#include "WcViewStatus.h"
#include "WcViewModel.h"
#include "TextStatusFilterDialog.h"
#include "sublib/ActionStorage.h"

// qt
#include <QtGui/QLayout>
#include <QtGui/QToolButton>
#include <QtGui/QStatusBar>
#include <QtGui/QLabel>
#include <QtGui/QCheckBox>
#include <QtGui/QToolTip>
#include <Qt3Support/Q3PopupMenu>


WcViewTreeWidget::WcViewTreeWidget( WcViewModel* model,
  WcViewTreeItemModel* itemModel, ActionStorage* as, QWidget* parent )
: super(parent), _model(model), _itemModel(itemModel)
{
  QVBoxLayout* vl = new QVBoxLayout(this);
  vl->setContentsMargins(0,0,0,2);
  vl->setSpacing(3);
  {
    _state = new WcViewViewState(_model->getBookmark());

#ifdef SC_NEWPROXY
    _proxyModel = new WcViewItemProxyModel();
    _proxyModel->setSourceModel(_itemModel);
#else // SC_NEWPROXY
    _proxyModel = new WcViewTreeProxyModel();
    _proxyModel->setSourceModel(_itemModel);
    _proxyModel->setCurrentPath( _state->getPath() );
#endif // SC_NEWPROXY

    _tree  = new WcViewTree(_proxyModel, _state, as, this);
    vl->addWidget(_tree);
    vl->setStretchFactor(_tree,1);

    QHBoxLayout* hl = new QHBoxLayout();
    vl->addLayout(hl);
    {
      setStyleSheet(
        "QToolButton {border: none;} "
        "QToolButton::menu-indicator {image:none; background:none;} "
//        "QCheckBox {padding-right: 10px;} "
        );

      hl->setContentsMargins(1,1,3,1);
      hl->setSpacing(5);

      QHBoxLayout* ha = new QHBoxLayout();
      ha->setContentsMargins(0,0,0,0);
      ha->setSpacing(0);
      {
        _back = new QToolButton(this);
        _back->setPopupMode(QToolButton::DelayedPopup);
        _back->setArrowType(Qt::LeftArrow);
        _back->setDisabled(true);
        _back->setPopup( new QMenu(_back) );
        _back->setPopupDelay(250);
        
        _forward = new QToolButton(this);
        _forward->setPopupMode(QToolButton::DelayedPopup);
        _forward->setArrowType(Qt::RightArrow);
        _forward->setDisabled(true);
        _forward->setPopup( new QMenu(_forward) );
        _forward->setPopupDelay(250);

#ifndef _MACOSX
        _back->setFixedHeight(11);
        _back->setFixedWidth(13);
        _forward->setFixedHeight(11);
        _forward->setFixedWidth(13);
#endif //_MACOSX
        
        ha->addWidget(_back);
        ha->addWidget(_forward);
      }
      
      _all = new QCheckBox(_q("&all"), this);
      _filter = new QToolButton(this);
      _filter->setText(_q("f&ilter"));
      _filter->setToolTip(_q("click to change filter"));
      _viewtype = new QCheckBox(_q("flat/tree"), this);
      _viewtype->setChecked(false);
      
      _status = new QStatusBar(this);
      _status->setSizeGripEnabled(false);
      
      _version = new QLabel("-",this);
      _version->setFrameStyle(QFrame::Box|QFrame::Plain);
      _version->setMidLineWidth(2);
      _version->setLineWidth(2);
      
      hl->addLayout(ha);
      hl->addWidget(_viewtype);
      hl->addWidget(_all);
      hl->addWidget(_filter);
      hl->addWidget(_status);
      hl->addWidget(_version);
    }
  }

  // back/forward
  connect(
    _state, SIGNAL(historyChanged()),
    this,   SLOT(historyChange()) );
  connect(
    _state, SIGNAL(currentChanged(const sc::String&)),
    _tree,  SLOT(setCurrentDir(const sc::String&)) );
  connect(
    _tree, SIGNAL(currentChanged(const sc::String&)),
    this,  SLOT(currentChange(const sc::String&)) );
  connect(
    _back,  SIGNAL(clicked()),
    _state, SLOT(prevPath()) );
  connect(
    _forward, SIGNAL(clicked()),
    _state,   SLOT(nextPath()) );
  connect(
    _back->popup(), SIGNAL(activated(int)),
    _state,         SLOT(prevPath(int)) );
  connect(
    _forward->popup(), SIGNAL(activated(int)),
    _state,            SLOT(nextPath(int)) );

  // view options
  connect(
    _all,   SIGNAL(toggled(bool)),
    _state, SLOT(setViewAll(bool)) );
  connect(
    _filter, SIGNAL(clicked()),
    this, SLOT(selectFilter()));
  connect(
    _viewtype, SIGNAL(toggled(bool)),
    this, SLOT(setWcViewType(bool)) );
  connect( 
    _state, SIGNAL(optionsChanged()),
    _tree,  SLOT(refresh()) );

  // WcViewModel connections
  connect(
    _tree,  SIGNAL(move(const sc::String&,bool)),
    _model, SLOT(move(const sc::String&,bool)) );
  connect(
    _tree,  SIGNAL(copy(const sc::String&)),
    _model, SLOT(copy(const sc::String&)) );
  connect(
    _tree,  SIGNAL(selectionChanged(const WcSelection&)),
    _model, SLOT(setSelection(const WcSelection&)) );
  connect(
    _model, SIGNAL(updatedOld(const sc::String&,const svn::WcStatuss&)),
    _tree,  SLOT(updateOld(const sc::String&,const svn::WcStatuss&)) );
  connect(
    _model, SIGNAL(updatedNew(const sc::String&,const svn::WcStatuss&,bool)),
    _tree,  SLOT(updateNew(const sc::String&,const svn::WcStatuss&,bool)) );
  connect(
    _model, SIGNAL(updatedVersion(const Version&)),
    this,   SLOT(updatedVersion(const Version&)) );
}

WcViewTreeWidget::~WcViewTreeWidget()
{
  delete _state;
}

void WcViewTreeWidget::setWcViewType(bool on)
{
  if(on)
    _state->setType(WcViewTypeFlat);
  else
    _state->setType(WcViewTypeTree);

  if( _viewtype->isChecked() != on )
   _viewtype->setChecked(on);

  _tree->refreshType();
}

void WcViewTreeWidget::selectFilter()
{
  TextStatusFilter filter = _state->getTextStatusFilter();
  boost::shared_ptr<TextStatusFilterDialog> dlg(
    new TextStatusFilterDialog( this, filter ) );

  dlg->exec();

  if( dlg->result() != QDialog::Accepted )
    return; 

  const TextStatusFilter& statusFilter = dlg->getTextStatusFilter();
  _state->setTextStatusFilter(statusFilter);

  _tree->refresh();

  if(statusFilter.isDefault())
    _filter->setStyleSheet( "color: black;" );
  else
    _filter->setStyleSheet( "color: red;" );
}

void WcViewTreeWidget::historyChange()
{
  {
    PathHistory history;
    _state->getPrevPathHistory(history);

    Q3PopupMenu* menu = (Q3PopupMenu*)_back->popup();
    menu->clear();

    int id = 1;
    for( PathHistory::iterator it = history.begin(); it != history.end(); it++ )
    {
      menu->insertItem( QString::fromUtf8((*it)), id++ );
    }

    _back->setEnabled( history.size()>0 );
  }

  {
    PathHistory history;
    _state->getNextPathHistory(history);

    Q3PopupMenu* menu = (Q3PopupMenu*)_forward->popup();
    menu->clear();

    int id = 1;
    for( PathHistory::iterator it = history.begin(); it != history.end(); it++ )
    {
      menu->insertItem( QString::fromUtf8((*it)), id++ );
    }

    _forward->setEnabled( history.size()>0 );
  }
}

void WcViewTreeWidget::currentChange(const sc::String& current )
{
#if 0
  static QString PathAndUrlFormat("%1 (%2)");

  QString text = PathAndUrlFormat
    .arg(QString::fromUtf8(current))
    .arg(QString::fromUtf8(_model->getUrlFromPath(current)));

  QToolTip::add( _status, text );
  _status->message(text);
#endif

  emit rootChanged(
    QString::fromUtf8(current),
    QString::fromUtf8(_model->getUrlFromPath(current))
    );
}

void WcViewTreeWidget::updatedVersion( const Version& v )
{
  _version->setText(v.toString());
}

