/* ====================================================================
 * Copyright (c) 2007-2008  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 "RpViewTreeWidget.h"
#include "RpViewTree.h"
#include "RpViewState.h"
#include "RpViewModel.h"
#include "RpViewTreeItemModel.h"
#include "sublib/ActionStorage.h"

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


RpViewTreeWidget::RpViewTreeWidget( RpViewModel* model, ActionStorage* as, QWidget* parent )
: super(parent), _model(model)
{
  QVBoxLayout* vl = new QVBoxLayout(this);
  vl->setContentsMargins(0,0,0,2);
  vl->setSpacing(3);
  {
    _state = new RpViewState(_model->getBookmark()); 
    _tree  = new RpViewTree(_model->getRootPath(), _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;} "
        );
      
      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);
      }

      QStatusBar* status = new QStatusBar(this);
      status->setSizeGripEnabled(false);

      _version = new QLabel("head",this);
      _version->setFrameStyle(QFrame::Box|QFrame::Plain);
      _version->setMidLineWidth(2);
      _version->setLineWidth(2);

      hl->addLayout(ha);
      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&)) );
#if 0
  connect(
    _tree, SIGNAL(currentChanged(const sc::String&)),
    this,  SLOT(currentChange(const sc::String&)) );
#endif
  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)) );

#if 0
  // view options
  connect( _tree->getState(), SIGNAL(optionsChanged()), _tree, SLOT(refresh()) );
#endif

  // RpViewModel 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 RpSelection&)),
    _model, SLOT(setSelection(const RpSelection&)) );
  connect(
    _model, SIGNAL(updatedOld(const sc::String&,const svn::DirEntries&)),
    _tree,  SLOT(updateOld(const sc::String&,const svn::DirEntries&)) );
  connect(
    _model, SIGNAL(updatedNew(const sc::String&,const svn::DirEntries&)),
    _tree,  SLOT(updateNew(const sc::String&,const svn::DirEntries&)) );
  connect(
    // fixme _itemModel should be passed as parameter to _tree
    _tree->_itemModel, SIGNAL(fetch(const sc::String&)),
    this, SLOT(fetch(const sc::String&)) );
}

void RpViewTreeWidget::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 RpViewTreeWidget::fetch( const sc::String& path )
{
  printf("fetch\n");

  svn::DirEntries entries;
  _model->getEntriesOld(path,entries);

  if( entries.size() == 0 )
    _model->list(path,false);
  else {
    _tree->updateOld( path, entries );
    _tree->updateNew( path, entries );
  }
}
