/* ====================================================================
 * Copyright (c) 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 "TextStatusFilterDialog.h"
#include "StatusId.h"
#include "util/max.h"

// qt
#include <QtCore/QVariant>
#include <QtGui/QGridLayout>
#include <QtGui/QBoxLayout>
#include <QtGui/QCheckBox>
#include <QtGui/QGroupBox>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
#include <QtGui/QDialogButtonBox>


static QString StatusProperty("StatusId");

TextStatusFilterDialog::TextStatusFilterDialog( QWidget* parent, const
  TextStatusFilter& filter )
: super(parent,Qt::Tool), _filter(filter)
{
  setCaption(_q("text status filter"));
  QVBoxLayout* layout = new QVBoxLayout(this);

  QLabel* desc = new QLabel(
    _q("all working copy items with a working copy text status that is "
    "checked below will be visible. Any working copy item that has a "
    " text status that is not checked will be invisible.") );
  desc->setWordWrap(true);
  layout->add(desc);

  _groupbox = new QGroupBox(this);
  _groupbox->setTitle(_q("text status filter") + " ");
  _groupbox->setFlat(true);
  layout->add(_groupbox);
  QGridLayout* grouplayout = new QGridLayout(_groupbox);
  {
    //checkbox = new QCheckBox( getStatusName(StatusNone), this );
    //checkbox = new QCheckBox( getStatusName(StatusNormal), this );
    grouplayout->addWidget( createCheckBox(StatusIgnored), 0, 0 );

    grouplayout->addWidget( createCheckBox(StatusUnversioned), 1, 0 );
    grouplayout->addWidget( createCheckBox(StatusAdded), 1, 1 );
    grouplayout->addWidget( createCheckBox(StatusModified), 1, 2 );
    grouplayout->addWidget( createCheckBox(StatusDeleted), 1, 3 );

    grouplayout->addWidget( createCheckBox(StatusMerged), 2, 0 );
    grouplayout->addWidget( createCheckBox(StatusReplaced), 2, 1 );
    grouplayout->addWidget( createCheckBox(StatusMissing), 2, 2 );
    grouplayout->addWidget( createCheckBox(StatusConflicted), 2, 3 );

    grouplayout->addWidget( createCheckBox(StatusObstructed), 3, 0 );
    grouplayout->addWidget( createCheckBox(StatusExternal), 3, 1 );
  }

  QDialogButtonBox* db = new QDialogButtonBox(this);
  db->setContentsMargins(0,0,0,0);
  layout->addWidget(db);
  {
    int minWidth = 0;

    QPushButton* ok = new QPushButton(this);
    ok->setText( _q("&Ok") );
    ok->setDefault(true);
    db->addButton( ok, QDialogButtonBox::AcceptRole );
    minWidth = std::max( minWidth, ok->sizeHint().width() );

    QPushButton* ca = new QPushButton(this);
    ca->setText( _q("&Cancel") );
    ok->setAutoDefault(true);
    db->addButton( ca, QDialogButtonBox::RejectRole );
    minWidth = std::max( minWidth, ca->sizeHint().width() );

    QPushButton* reset = new QPushButton(this);
    reset->setText( _q("&Reset") );
    db->addButton( reset, QDialogButtonBox::ResetRole );
    minWidth = std::max( minWidth, reset->sizeHint().width() );

    ok->setMinimumWidth(minWidth);
    ca->setMinimumWidth(minWidth);
    reset->setMinimumWidth(minWidth);

    connect( ok, SIGNAL(clicked()), SLOT(accept()) );
    connect( ca, SIGNAL(clicked()), SLOT(reject()) );
    connect( reset, SIGNAL(clicked()), SLOT(reset()) );
  }

  setMaximumHeight( sizeHint().height() );
  setMaximumWidth( sizeHint().width() );
}

void TextStatusFilterDialog::checkBoxStateChanged( int state )
{
  QObject* source = sender();
  if( state == Qt::Checked )
    _filter.set( (StatusId)source->property(StatusProperty).asInt() );
  else
    _filter.clear( (StatusId)source->property(StatusProperty).asInt() );
}

QCheckBox* TextStatusFilterDialog::createCheckBox( StatusId id )
{
  QCheckBox* check = new QCheckBox( getStatusName(id), this );
  check->setName(getStatusName(id));
  check->setProperty( StatusProperty, QVariant(id) );
  check->setChecked( _filter.test(id) );
  connect( check, SIGNAL(stateChanged(int)),
           this, SLOT(checkBoxStateChanged(int)) );
  return check;
}

const TextStatusFilter& TextStatusFilterDialog::getTextStatusFilter()
  const
{
  return _filter;
}

void TextStatusFilterDialog::reset()
{
  clearCheckBoxes();
  setDefaultFilter();
  setCheckBoxes();
}

void TextStatusFilterDialog::setDefaultFilter()
{
  _filter = TextStatusFilter::getDefaultFilter();
}

void TextStatusFilterDialog::clearCheckBoxes()
{
  const QObjectList& childs = _groupbox->children();
  for( int i = 0; i < childs.size(); i++ )
  {
    QCheckBox* box = dynamic_cast<QCheckBox*>(childs.at(i));
    if( box )
      box->setChecked(false);
  }
}

void TextStatusFilterDialog::setCheckBoxes()
{
  const std::set<StatusId>& ids = _filter.getStatusIds();

  for( std::set<StatusId>::const_iterator it = ids.begin();
    it != ids.end(); it++ )
  {
    QCheckBox* cb =
      _groupbox->findChild<QCheckBox*>(getStatusName(*it));
    assert(cb);
    cb->setChecked(true);
  }
}
