/* ====================================================================
 * Copyright (c) 2003-2006, 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 "BlameDialog.h"
#include "BlameLineLvi.h"
#include "BaseModel.h"
#include "RevisionWidget.h"
#include "PostCmdResult.h"
#include "ScModel.h"
#include "settings/FontSettings.h"
#include "events/BlameEvent.h"
#include "events/EventSupport.h"
#include "commands/BlameParam.h"
#include "sublib/Gui.h"
#include "sublib/TargetRepository.h"
#include "svn/BlameBaton.h"
#include "svn/BlameLine.h"

// qt
#include <qlayout.h>
#include <qhbox.h>
#include <qpushbutton.h>
#include <qlistview.h>
#include <qheader.h>



///////////////////////////////////////////////////////////////////////////////
//

class BlameBaton : public svn::BlameBaton
{
public:
  BlameBaton( BlameDialog* dlg ) :_dlg(dlg)
  {
  }

  void receive( const svn::BlameLine* line )
  {
    postEvent( _dlg, new BlameEvent(line) );
  }

private:
  BlameDialog* _dlg;
};

//
///////////////////////////////////////////////////////////////////////////////


BlameDialog::BlameDialog( BaseModel* model, QWidget *parent, const char *name )
: super( 0, name, Qt::WStyle_Customize | Qt::WType_TopLevel | Qt::WStyle_MinMax |
  Qt::WStyle_NormalBorder | Qt::WStyle_Title | Qt::WStyle_SysMenu
  | Qt::WDestructiveClose ), TargetId(this), _model(model)
{
  setCaption( _q("subcommander:blame") );

  QVBoxLayout *vbl = new QVBoxLayout(this,5,8);
  vbl->setSpacing(10);
  {
    QGroupBox* gb = new QGroupBox(1,Qt::Vertical,this);
    gb->setTitle( _q("blame options: ") );
    //gb->setInsideSpacing(10);
    gb->setInsideMargin(0);
    gb->setFlat(true);
    vbl->addWidget(gb);
    {
      QHBox* hb = new QHBox(gb);
      hb->setSpacing(5);
      {
        _rwStart = new RevisionWidget(false,"NDS","HBCP",0,hb);
        _rwStart->setTitle( _q("start revision") );
        _rwStop = new RevisionWidget(false,"SND","HBCP",0,hb);
        _rwStop->setTitle( _q("stop revision") );
      }
    }

    _blame = new QListView(this);
    vbl->addWidget(_blame);
    _blame->addColumn( _q("line") );
    _blame->addColumn( _q("revision") );
    _blame->addColumn( _q("date") );
    _blame->addColumn( _q("author") );
    _blame->addColumn( _q("content") );
    _blame->addColumn( "" );
    _blame->setColumnAlignment( 0, Qt::AlignRight );
    _blame->setColumnAlignment( 1, Qt::AlignRight );
    _blame->setColumnAlignment( 2, Qt::AlignRight );
    //_blame->setResizeMode(QListView::LastColumn);
    _blame->setAllColumnsShowFocus(true);
    _blame->setSortOrder(Qt::Ascending);
    _blame->setSorting(0);
    _blame->setItemMargin(0);

    QFont font = _model->getModel()->getFontSettings()->getEditorFont();
    _blame->setFont( font );

    QHBoxLayout* hu = new QHBoxLayout;
    vbl->addLayout(hu);
    {
      // eats extra space, so the buttons keep their size
      hu->addStretch(1); 

      _run = new QPushButton(this);
      _run->setText( _q("&Run") );
      _run->setFocus();
      hu->addWidget(_run);
      _done = new QPushButton(this);
      _done->setText( _q("&Done") );
      hu->addWidget(_done);

      hu->addSpacing(getSizeGripSpacing());
      
      connect( _run,  SIGNAL(clicked()), SLOT(run()) );
      connect( _done, SIGNAL(clicked()), SLOT(close()) );
    }
  }

  resize( QSize( 700, 600 ) );
}

BlameDialog::~BlameDialog()
{
}

void BlameDialog::customEvent( QCustomEvent* ce )
{
  switch( ce->type() )
  {
  case ScBlameEvent:
    {
      const svn::BlameLine* l = dynamic_cast<BlameEvent*>(ce)->getLine();
      new BlameLineLvi( _blame, l );      
      break;
    }
  case ScParameterEvent:
    {
      //ScParamEvent* pe = dynamic_cast<ScParamEvent*>(ce);
      //delete pe;
      finished();
      break;
    }
  default:
    {
      printf( "BlameDialog: unknown custom event type %d!\n", ce->type() );
    }
  }
}

void BlameDialog::setSource( const sc::String& source )
{
  _source = source;

  setCaption( QString(_q("subcommander:blame (%1)")).arg((const char*)_source) );
}

void BlameDialog::finished()
{
  _run->setEnabled(true);
  _done->setEnabled(true);
}

void BlameDialog::run()
{
  _run->setEnabled(false);
  _done->setEnabled(false);
  _blame->clear();

  BlameParam* param = new BlameParam( _source, _rwStart->getRevision(),
    _rwStop->getRevision(), new BlameBaton(this) );
  PostCmdResult* pcres = new PostCmdResult(this);

  _model->blame( param, pcres );
}



syntax highlighted by Code2HTML, v. 0.9.1