// $Id$
// (c) 2001, Cornelius Schumacher

#include <ktextedit.h>
#include <tqlayout.h>

#include <klocale.h>
#include <kdebug.h>
#include <tqcombobox.h>
#include <tqsplitter.h>
#include <tqlabel.h>

#include "messageeditor.h"
#include "kbbprefs.h"
#include "bugsystem.h"
#include "bugcommand.h"

#include "msginputdialog.h"
#include "msginputdialog.moc"

MsgInputDialog::MsgInputDialog(MsgInputDialog::MessageType type, const Bug &bug,
                               const Package &package, const TQString &quotedMsg,
                               TQWidget *parent)
  : KDialogBase(Plain,TQString(),User1|User2|Ok|Cancel,Ok,parent,0,false,
                true,KStdGuiItem::clear(),i18n( "&Edit Presets..." )),
    mBug( bug ),
    mPackage( package ),
    mType( type )
{
  switch ( mType ) {
    case Close:
      setCaption( i18n("Close Bug %1").arg( mBug.number() ) );
      break;
    case Reply:
      setCaption( i18n("Reply to Bug") );
      break;
    case ReplyPrivate:
      setCaption( i18n("Reply Privately to Bug") );
      break;
    default:
      break;
  }

  TQFrame *topFrame = plainPage();
  ( new TQHBoxLayout( topFrame ) )->setAutoAdd( true );

  mSplitter = new TQSplitter( Qt::Horizontal, topFrame );

  TQWidget *w = new TQWidget( mSplitter );
  ( new TQVBoxLayout( w, spacingHint(), -1 ) )->setAutoAdd( true );

  if ( mType == Reply ) {
    TQWidget *r = new TQWidget( w );
    TQHBoxLayout* rlayout = new TQHBoxLayout( r );

    TQLabel *rlabel = new TQLabel( i18n("&Recipient:"),r );
    TQFont f = r->font();
    f.setBold( true );
    r->setFont( f );
    rlayout->add( rlabel );

    mRecipient = new TQComboBox( r );
    mRecipient->insertItem( i18n("Normal (bugs.trinitydesktop.org & Maintainer & tde-bugs-dist)"), BugCommand::Normal );
    mRecipient->insertItem( i18n("Maintonly (bugs.trinitydesktop.org & Maintainer)"), BugCommand::Maintonly );
    mRecipient->insertItem( i18n("Quiet (bugs.trinitydesktop.org only)"), BugCommand::Quiet );
    rlabel->setBuddy( mRecipient );
    rlayout->add( mRecipient );

    TQSpacerItem *rspacer= new TQSpacerItem( 1,1,TQSizePolicy::Expanding );
    rlayout->addItem( rspacer );

    // Reply currently only replies to the bug tracking system
    r->hide();
  }


  TQLabel *l = new TQLabel( i18n( "&Message" ), w );
  TQFont f = l->font();
  f.setBold( true );
  l->setFont( f );

  mMessageEdit = new KTextEdit( w );
  mMessageEdit->setMinimumWidth( mMessageEdit->fontMetrics().width('x') * 72 );
  mMessageEdit->setWordWrap( TQTextEdit::FixedColumnWidth );
  mMessageEdit->setWrapColumnOrWidth( 72 );
  l->setBuddy( mMessageEdit );

  w = new TQWidget( mSplitter );
  ( new TQVBoxLayout( w, spacingHint(), -1 ) )->setAutoAdd( true );
  l = new TQLabel( i18n( "&Preset Messages" ), w );
  l->setFont( f );

  mPresets = new KListBox( w );
  updatePresets();
  l->setBuddy( mPresets );

  connect( mPresets, TQT_SIGNAL( executed( TQListBoxItem* ) ),
           TQT_SLOT( slotPresetSelected( TQListBoxItem * ) ) );
  connect( this, TQT_SIGNAL( user2Clicked() ), TQT_SLOT( editPresets() ) );
  connect( this, TQT_SIGNAL( user1Clicked() ), TQT_SLOT( clearMessage() ) );
  mMessageEdit->setFocus();

  if ( !quotedMsg.isEmpty() )
    insertQuotedMessage( quotedMsg );

  readConfig();
}

MsgInputDialog::~MsgInputDialog()
{
  kdDebug() << "MsgInputDialog::~MsgInputDialog()" << endl;
  writeConfig();
}

void MsgInputDialog::readConfig()
{
  resize( KBBPrefs::instance()->mMsgDlgWidth,
          KBBPrefs::instance()->mMsgDlgHeight );
  TQValueList<int> sizes = KBBPrefs::instance()->mMsgDlgSplitter;
  mSplitter->setSizes( sizes );
}

void MsgInputDialog::writeConfig()
{
  KBBPrefs::instance()->mMsgDlgWidth = width();
  KBBPrefs::instance()->mMsgDlgHeight = height();
  KBBPrefs::instance()->mMsgDlgSplitter = mSplitter->sizes();
}

void MsgInputDialog::updatePresets()
{
  mPresets->clear();

  TQMap<TQString,TQString> messageButtons = KBBPrefs::instance()->mMessageButtons;

  int id = 0;
  TQMap<TQString,TQString>::ConstIterator it;
  for( it = messageButtons.begin(); it != messageButtons.end(); ++it )
    mPresets->insertItem( it.key(), id );
}

TQString MsgInputDialog::message() const
{
  return mMessageEdit->text();
}

void MsgInputDialog::editPresets()
{
  MessageEditor *dlg = new MessageEditor(this);
  dlg->exec();
  delete dlg;

  updatePresets();
}

void MsgInputDialog::slotPresetSelected( TQListBoxItem *lbi )
{
  mMessageEdit->setText( KBBPrefs::instance()->mMessageButtons[ lbi->text() ] );
}

void MsgInputDialog::clearMessage()
{
  mMessageEdit->setText("");
}

void MsgInputDialog::queueCommand()
{
  switch ( mType ) {
    case Close:
      BugSystem::self()->queueCommand(
          new BugCommandClose( mBug, message(), mPackage ) );
      break;
    case Reply:
      BugSystem::self()->queueCommand(
          new BugCommandReply( mBug, message(), mRecipient->currentItem() ) );
      break;
    case ReplyPrivate:
      BugSystem::self()->queueCommand(
          new BugCommandReplyPrivate( mBug, mBug.submitter().email,
	                              message() ) );
      break;
    default:
      break;
  }
}

void MsgInputDialog::slotOk()
{
  queueCommand();
  delete this;
}

void MsgInputDialog::slotCancel()
{
  delete this;
}

void MsgInputDialog::insertQuotedMessage( const TQString &msg )
{
	Q_ASSERT( mMessageEdit->wordWrap() == TQTextEdit::FixedColumnWidth );

	const TQString quotationMarker = "> ";
	const unsigned int wrapColumn = mMessageEdit->wrapColumnOrWidth();

	// ### Needs something more sophisticated than simplifyWhiteSpace to
	// handle quoting multiple paragraphs properly.
	TQString line = msg.simplifyWhiteSpace();

	TQString quotedMsg;
	while ( line.length() + quotationMarker.length() + 1 > wrapColumn ) {
		int pos = wrapColumn - quotationMarker.length() - 1;
		while ( pos > 0 && !line[ pos ].isSpace() )
			--pos;
		if ( pos == 0 )
			pos = wrapColumn;
		quotedMsg += quotationMarker + line.left( pos ) + "\n";
		line = line.mid( pos + 1 );
	}
	quotedMsg += quotationMarker + line + "\n\n";

	mMessageEdit->setText( quotedMsg );

	const int lastPara = mMessageEdit->paragraphs() - 1;
	const int lastParaLen = mMessageEdit->paragraphLength( lastPara ) - 1;
	mMessageEdit->setCursorPosition( lastPara, lastParaLen );
}
