/*
  This file is part of libkdepim.

  Copyright (c) 2004 Lutz Rogowski <rogowski@kde.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License along
  with this program; if not, write to the Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

  As a special exception, permission is given to link this program
  with any edition of Qt, and distribute the resulting executable,
  without including the source code for Qt in the source distribution.
*/

#include "kincidencechooser.h"

#include <kcal/incidence.h>
#include <kcal/incidenceformatter.h>

#include <KGlobal>
#include <KHBox>
#include <KLocale>

#include <QApplication>
#include <QGridLayout>
#include <QLabel>
#include <QLayout>
#include <QPushButton>
#include <QRadioButton>
#include <QTextBrowser>
#include <Q3ButtonGroup>
#include <Q3ScrollView>

using namespace KPIM;

int KIncidenceChooser::chooseMode = KIncidenceChooser::ask ;

KIncidenceChooser::KIncidenceChooser( QWidget *parent )
  : KDialog( parent )
{
    setModal( true );
    QWidget *topFrame = mainWidget();
    QGridLayout *topLayout = new QGridLayout( topFrame );
    topLayout->setMargin( 5 );
    topLayout->setSpacing( 3 );

    int iii = 0;
    setWindowTitle( i18n( "Conflict Detected" ) );
    QLabel *lab;
    lab = new QLabel(
      i18n( "<qt>A conflict was detected. This probably means someone edited "
            "the same entry on the server while you changed it locally."
            "<br/>NOTE: You have to check mail again to apply your changes "
            "to the server.</qt>" ), topFrame );
    lab->setWordWrap( true );
    topLayout->addWidget( lab, iii, 0, 1, 3 );
    ++iii;
    KHBox *b_box = new KHBox( topFrame );
    topLayout->addWidget( b_box, iii, 0, 1, 3 );
    ++iii;
    QPushButton *button = new QPushButton( i18n( "Take Local" ), b_box );
    connect ( button, SIGNAL( clicked()), this, SLOT (takeIncidence1() ) );
    button = new QPushButton( i18n( "Take New" ), b_box );
    connect ( button, SIGNAL( clicked()), this, SLOT (takeIncidence2() ) );
    button = new QPushButton( i18n( "Take Both" ), b_box );
    connect ( button, SIGNAL( clicked()), this, SLOT (takeBoth() ) );
    topLayout->setSpacing( spacingHint() );
    topLayout->setMargin( marginHint() );
    // text is not translated, because text has to be set later
    mInc1lab = new QLabel ( i18n( "Local incidence" ), topFrame );
    topLayout->addWidget( mInc1lab, iii, 0 );
    mInc1Sumlab = new QLabel ( i18n( "Local incidence summary" ), topFrame );
    topLayout->addWidget( mInc1Sumlab, iii, 1, 1, 2 );
    ++iii;
    topLayout->addWidget( new QLabel ( i18n( "Last modified:" ), topFrame ), iii, 0 );
    mMod1lab = new QLabel ( i18n("Set Last modified"), topFrame );
    topLayout->addWidget( mMod1lab, iii, 1 );
    showDetails1 = new QPushButton( i18n( "Show Details" ), topFrame );
    connect ( showDetails1, SIGNAL( clicked()), this, SLOT (showIncidence1() ) );
    topLayout->addWidget( showDetails1, iii, 2 );
    ++iii;

    mInc2lab = new QLabel ( i18n("Local incidence"), topFrame );
    topLayout->addWidget( mInc2lab, iii, 0 );
    mInc2Sumlab = new QLabel ( i18n("Local incidence summary"), topFrame );
    topLayout->addWidget( mInc2Sumlab, iii, 1, 1, 2 );
    ++iii;
    topLayout->addWidget( new QLabel ( i18n( "Last modified:" ), topFrame ), iii, 0 );
    mMod2lab = new QLabel ( i18n("Set Last modified"), topFrame );
    topLayout->addWidget( mMod2lab, iii, 1 );
    showDetails2 = new QPushButton( i18n( "Show Details" ), topFrame );
    connect ( showDetails2, SIGNAL( clicked()), this, SLOT (showIncidence2() ) );
    topLayout->addWidget( showDetails2, iii, 2 );
    ++iii;
    //
#if 0
    // commented out for now, because the diff code has too many bugs
    diffBut = new QPushButton( i18n( "Show Differences" ), topFrame );
    connect ( diffBut, SIGNAL( clicked()), this, SLOT ( showDiff() ) );
    topLayout->addWidget( cdiffBut, iii, 0, 1, 3 );
    ++iii;
#else
    diffBut = 0;
#endif
    mBg = new Q3ButtonGroup ( 1, Qt::Horizontal, i18n( "Sync Preferences" ), topFrame );
    topLayout->addWidget( mBg, iii, 0, 1, 3 );
    ++iii;
    mBg->insert(
      new QRadioButton ( i18n( "Take local entry on conflict" ), mBg ),
      KIncidenceChooser::local );
    mBg->insert(
      new QRadioButton ( i18n( "Take new (remote) entry on conflict" ), mBg ),
      KIncidenceChooser::remote );
    mBg->insert(
      new QRadioButton ( i18n( "Take newest entry on conflict" ), mBg ),
      KIncidenceChooser::newest );
    mBg->insert(
      new QRadioButton ( i18n( "Ask for every entry on conflict" ), mBg ),
      KIncidenceChooser::ask );
    mBg->insert(
      new QRadioButton ( i18n( "Take both on conflict" ), mBg ),
      KIncidenceChooser::both );
    mBg->setButton ( chooseMode );
    mTbL = 0;
    mTbN =  0;
    mDisplayDiff = 0;
    choosedIncidence = 0;
    button = new QPushButton( i18n( "Apply This to All Conflicts of This Sync" ), topFrame );
    connect ( button, SIGNAL( clicked()), this, SLOT ( setSyncMode() ) );
    topLayout->addWidget( button, iii, 0, 1, 3 );
}

KIncidenceChooser::~KIncidenceChooser()
{
  if ( mTbL ) {
    delete mTbL;
  }
  if ( mTbN ) {
    delete mTbN;
  }
  if ( mDisplayDiff ) {
    delete mDisplayDiff;
    delete diff;
  }
}

void KIncidenceChooser::setIncidence( KCal::Incidence *local, KCal::Incidence *remote )
{
  mInc1 = local;
  mInc2 = remote;
  setLabels();

}
KCal::Incidence *KIncidenceChooser::getIncidence( )
{
  KCal::Incidence *retval = choosedIncidence;
  if ( chooseMode == KIncidenceChooser::local ) {
    retval = mInc1;
  } else if ( chooseMode == KIncidenceChooser::remote ) {
    retval = mInc2;
  } else if ( chooseMode == KIncidenceChooser::both ) {
    retval = 0;
  } else if ( chooseMode == KIncidenceChooser::newest ) {
    if ( mInc1->lastModified() == mInc2->lastModified() ) {
      retval = 0;
    }
    if ( mInc1->lastModified() >  mInc2->lastModified() ) {
      retval =  mInc1;
    } else {
      retval = mInc2;
    }
  }
  return retval;
}

void KIncidenceChooser::setSyncMode()
{
  chooseMode = mBg->selectedId ();
  if ( chooseMode != KIncidenceChooser::ask ) {
    QDialog::accept();
  }
}

void KIncidenceChooser::useGlobalMode()
{
  if ( chooseMode != KIncidenceChooser::ask ) {
    QDialog::reject();
  }
}

void KIncidenceChooser::setLabels()
{
  KCal::Incidence *inc = mInc1;
  QLabel *des = mInc1lab;
  QLabel *sum = mInc1Sumlab;

  if ( inc->type() == "Event" ) {
    des->setText( i18n( "Local Event" ) );
    sum->setText( inc->summary().left( 30 ) );
    if ( diffBut ) {
      diffBut->setEnabled( true );
    }
  } else if ( inc->type() == "Todo" ) {
    des->setText( i18n( "Local Todo" ) );
    sum->setText( inc->summary().left( 30 ) );
    if ( diffBut ) {
      diffBut->setEnabled( true );
    }
  } else if ( inc->type() == "Journal" ) {
    des->setText( i18n( "Local Journal" ) );
    sum->setText( inc->description().left( 30 ) );
    if ( diffBut ) {
      diffBut->setEnabled( false );
    }
  }
  mMod1lab->setText( KGlobal::locale()->formatDateTime( inc->lastModified().dateTime() ) );
  inc = mInc2;
  des = mInc2lab;
  sum = mInc2Sumlab;
  if ( inc->type() == "Event" ) {
    des->setText( i18n( "New Event" ) );
    sum->setText( inc->summary().left( 30 ) );
  } else if ( inc->type() == "Todo" ) {
    des->setText( i18n( "New Todo" ) );
    sum->setText( inc->summary().left( 30 ) );
  } else if ( inc->type() == "Journal" ) {
    des->setText( i18n( "New Journal" ) );
    sum->setText( inc->description().left( 30 ) );

  }
  mMod2lab->setText( KGlobal::locale()->formatDateTime( inc->lastModified().dateTime() ) );
}

void KIncidenceChooser::showIncidence1()
{
  if ( mTbL ) {
    if ( mTbL->isVisible() ) {
      showDetails1->setText( i18n( "Show Details" ) );
      mTbL->hide();
    } else {
      showDetails1->setText( i18n( "Hide Details" ) );
      mTbL->show();
      mTbL->raise();
    }
    return;
  }
  mTbL = new KDialog( this );
  mTbL->setCaption( mInc1lab->text() );
  mTbL->setModal( false );
  mTbL->setButtons( Ok );
  connect( mTbL, SIGNAL( okClicked() ), this, SLOT( detailsDialogClosed() ) );
  QTextBrowser *textBrowser = new QTextBrowser( mTbL );
  mTbL->setMainWidget( textBrowser );
  textBrowser->setHtml( KCal::IncidenceFormatter::extensiveDisplayString( mInc1 ) );
  mTbL->setMinimumSize( 400, 400 );
  showDetails1->setText( i18n( "Hide Details" ) );
  mTbL->show();
  mTbL->raise();
}

void KIncidenceChooser::detailsDialogClosed()
{
  KDialog *dialog = static_cast<KDialog *>( const_cast<QObject *>( sender() ) );
  if ( dialog == mTbL ) {
    showDetails1->setText( i18n( "Show details..." ) );
  } else {
    showDetails2->setText( i18n( "Show details..." ) );
  }
}

void KIncidenceChooser::showDiff()
{
  if ( mDisplayDiff ) {
    mDisplayDiff->show();
    mDisplayDiff->raise();
    return;
  }
  mDisplayDiff = new KPIM::HTMLDiffAlgoDisplay (this);
  if ( mInc1->summary().left( 20 ) != mInc2->summary().left( 20 ) ) {
    mDisplayDiff->setWindowTitle(
      i18n( "Differences of %1 and %2", mInc1->summary().left( 20 ),
            mInc2->summary().left( 20 ) ) );
  } else {
    mDisplayDiff->setWindowTitle(
      i18n( "Differences of %1", mInc1->summary().left( 20 ) ) );
  }

  diff = new KPIM::CalendarDiffAlgo( mInc1, mInc2 );
  diff->setLeftSourceTitle( i18n( "Local entry" ) );
  diff->setRightSourceTitle( i18n( "New (remote) entry" ) );
  diff->addDisplay( mDisplayDiff );
  diff->run();
  mDisplayDiff->show();
  mDisplayDiff->raise();
}

void KIncidenceChooser::showIncidence2()
{
  if ( mTbN ) {
    if ( mTbN->isVisible() ) {
      showDetails2->setText( i18n( "Show Details" ) );
      mTbN->hide();
    } else {
      showDetails2->setText( i18n( "Hide Details" ) );
      mTbN->show();
      mTbN->raise();
    }
    return;
  }
  mTbN = new KDialog( this );
  mTbN->setCaption( mInc2lab->text() );
  mTbN->setModal( false );
  mTbN->setButtons( Ok );
  connect( mTbN, SIGNAL( okClicked() ), this, SLOT( detailsDialogClosed() ) );
  QTextBrowser *textBrowser = new QTextBrowser( mTbN );
  mTbN->setMainWidget( textBrowser );
  textBrowser->setHtml( KCal::IncidenceFormatter::extensiveDisplayString( mInc2 ) );
  mTbN->setMinimumSize( 400, 400 );
  showDetails2->setText( i18n( "Hide Details" ) );
  mTbN->show();
  mTbN->raise();
}

void KIncidenceChooser::takeIncidence1()
{
  choosedIncidence = mInc1;
  QDialog::accept();
}

void KIncidenceChooser::takeIncidence2()
{
  choosedIncidence = mInc2;
  QDialog::accept();
}

void KIncidenceChooser::takeBoth()
{
  choosedIncidence = 0;
  QDialog::accept();
}

#include "kincidencechooser.moc"
