/*
** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au>
**
*/

/*
** 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 in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to kde-devel@kde.org
*/


#include "../config.h"
// qt headers
#include <tqlabel.h>

#include <tdelocale.h>
#include <tdeglobal.h>
#include <tdeglobalsettings.h>
#include <tdelistview.h>
#include <kseparator.h>
#include <kdebug.h>
#include <kpushbutton.h>
#include <kstdguiitem.h>

#include "pkgOptions.h"
#include "managementWidget.h"
#include "debInterface.h"
#include "kpackage.h"
#include "options.h"

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

pkgOptions::pkgOptions(pkgInterface *pki, TQWidget *parent, const TQString &caption)
  :  KDialog(parent,0,true)
{
  //  setFrameStyle(TQFrame::Raised | TQFrame::Panel);

  pkgInt = pki;

  hide();

  setCaption(caption);
}

// Destructor
pkgOptions::~pkgOptions()
{
  //  int i;
  //  for (i = 0; i < bnumber; i++) {
  //    delete(Boxs[i]);
  //  }
}

// Set up the sub-widgets
void pkgOptions::setupWidgets(TQPtrList<param> &pars)
{
  int i;

  // Create widgets
  title = new TQLabel("", this);
  TQFont f( TDEGlobalSettings::generalFont());
  f.setBold(true);
  f.setPointSize(f.pointSize()+6);
  title->setFont(f);

  installButton = new TQPushButton(insType,this);
  cancelButton = new KPushButton(KStdGuiItem::cancel(),this);
  // count number of buttons
  bnumber = pars.count();

  Boxs = new TQCheckBox *[bnumber];
  param *p;
  i = 0;
  for ( p=pars.first(); p != 0; p=pars.next(), i++ ) {
    Boxs[i] = new TQCheckBox(p->name, this);
    Boxs[i]->setChecked(p->init);
  }

  Keep = new TQCheckBox(i18n("Keep this window"), this);

  // Connections
  connect(installButton,TQ_SIGNAL(clicked()),TQ_SLOT(pkginstallButtonClicked()));
  connect(cancelButton,TQ_SIGNAL(clicked()),TQ_SLOT(cancelButtonClicked()));
  connect(Keep, TQ_SIGNAL(toggled(bool)), TQ_SLOT(keepToggle(bool)));

  // Do the layout
  vlayout = new TQBoxLayout(this, TQBoxLayout::TopToBottom, marginHint(), spacingHint());
  vlayout->addWidget(title,0);

  {
    hlayout = new TQBoxLayout(vlayout,TQBoxLayout::LeftToRight, spacingHint());

    {
      layout = new TQBoxLayout(hlayout,TQBoxLayout::TopToBottom, spacingHint());

      packages = new TDEListView(this);
      layout->addWidget(packages,20);
      packages->addColumn(i18n("PACKAGES"),200);

      connect(packages, TQ_SIGNAL(selectionChanged ( TQListViewItem * )),
	    this, TQ_SLOT(slotSearch( TQListViewItem * )));

      layout->addStretch(1);
      for (i = 0; i < bnumber; i++) {
	layout->addWidget(Boxs[i],1);
      }
      layout->addWidget(new KSeparator(KSeparator::HLine, this), 2);

      TQBoxLayout *slayout = new TQBoxLayout(layout, TQBoxLayout::LeftToRight);
      slayout->addStretch(1);
      slayout->addWidget(Keep, 1);
      slayout->addStretch(1);

      layout->addWidget(new KSeparator(KSeparator::HLine, this), 2);

      TQBoxLayout *buttons = new TQBoxLayout(TQBoxLayout::LeftToRight);
      layout->addLayout(buttons);

      buttons->addWidget(installButton,2);
      buttons->addStretch(1);
      buttons->addWidget(cancelButton,2);
    }
    {
      term = new kpTerm(kpty,this);
      hlayout->addWidget(term, 1000);
    }
  }
  resize(800, 400);
}

void pkgOptions::setup(packageInfo *p, const TQString &type) {
  TQPtrList<packageInfo> *pl = new TQPtrList<packageInfo>;
  pl->append(p);
  setup(pl,type);
}

bool pkgOptions::setup(TQPtrList<packageInfo> *pl, const TQString &)
{
 TQString s;
 modified = false;

 packList = pl;

  packages->clear();
  packageInfo *p;

  TQStringList plist, rlist, clist;
  TQDict<TQString> dict;
  TQString mark("x");
  for ( p = pl->first(); p != 0; p = pl->next() ) {
    TQString file =  p->getFilename();
    plist += p->getProperty("name");
    if (file.isEmpty()) {
      clist += p->getProperty("name");
    }
    dict.insert(p->getProperty("name"), &mark);
  }

  packageInfo *pk;
  bool cancel;
  if (clist.count() > 0) {
    rlist = pkgInt->listInstalls(clist, installer, cancel);
    if (cancel) {
      reject();
      return false;
    }
    for ( TQStringList::Iterator it = rlist.begin(); it != rlist.end(); ++it ) {
      if (!dict[*it]) {
	plist.append(*it);
	TQString dirIndex = *it + pkgInt->typeID;
	if (installer) {
	  pk = kpackage->management->dirUninstPackages->find(dirIndex);
	} else {
	  pk = kpackage->management->dirInstPackages->find(dirIndex);
	}
	if (pk) {
	  //	  kdDebug() << "FF=" << dirIndex << "\n";
	  pl->append(pk);
	} else {
	  //	  kdDebug() << "uF=" << dirIndex << "\n";
	}
      }
    }
  }

 s = i18n("%1: 1 %2 Package","%1: %n %2 Packages",plist.count()).arg(insType,pkgInt->name);
 title->setText(s);

  for (TQStringList::Iterator pit = plist.begin(); pit != plist.end(); ++pit ) {
    //    kdDebug() << "P=" << *pit << "\n";
    new TQListViewItem(packages, *pit);
  }
  cancelButton->setGuiItem(KStdGuiItem::cancel());
  return true;
}

// install button has been clicked....so install the package
void pkgOptions::pkginstallButtonClicked()
{
  int i;
  TQStringList r;
  modified = true;

  // Collect data from check boxes
  int installFlags = 0;

  for (i = 0; i < bnumber; i++) {
    installFlags |= (Boxs[i]->isChecked()) << i;
  }

  test = false;
  TQString s = doPackages(installFlags, packList, test);
  // A "0=" or "1=" indicates it was actually (un)installed by the doPackages
  // routine instead of just returning a command to execute

  kdDebug() <<  "S=" << s << "\n";
  if (s == "0=") {
    cancelButtonClicked();
  } else if (s.left(2) == "1=") {
    term->textIn(s.mid(2), true);
  } else {
    connect(term,TQ_SIGNAL(result(TQStringList &, int)),
	 this,TQ_SLOT(slotResult(TQStringList &, int)));

    installButton->setEnabled(false);

    if (term->run(s, r)) {
      running = true;
      cancelButton->setGuiItem(KStdGuiItem::cancel());
    } else {
      reset();
    }
  }
}

void pkgOptions::slotSearch(TQListViewItem *item)
{
  TQString s = item->text(0);
  kdDebug() << "searchI=" << s << "h=" << pkgInt->head <<"\n";

  packageInfo *p;
  for ( p = packList->first(); p != 0; p = packList->next() ) {
    if (s == p->getProperty("name")) {
      kpackage->management->doChangePackage(p);
      break;
    }
  }
}

void pkgOptions::reset() {
  installButton->setEnabled(true);
  cancelButton->setGuiItem(KGuiItem(i18n("Done")));  //clear icon
  disconnect(term,TQ_SIGNAL(result(TQStringList &, int)),
	 this,TQ_SLOT(slotResult(TQStringList &, int)));
  running = false;
}

void pkgOptions::slotResult(TQStringList &, int ret)
{
  reset();
  if (ret == 0 && !test && !keep) {
    term->done();
    accept();
  }
}

void pkgOptions::terminate() {
  if (running) {
    term->cancel();
    reset();
  }
}

void pkgOptions::cancelButtonClicked()
{
  terminate();
  term->done();

  if (!modified || test)
    reject();
  else
    accept();
}

void pkgOptions::closeEvent ( TQCloseEvent * e ) {
  kdDebug() << "pkgOptions::TQCloseEvent\n";
  terminate();
   
  TQWidget::closeEvent (e);
}

void pkgOptions::showEvent ( TQShowEvent *e ) {
  //  kdDebug() << "pkgOptions::showEvent\n";
  getKeep();

  modified = false;
  running = false;

  TQWidget::showEvent(e);
}

void pkgOptions::keepToggle(bool kp)
{
  //  kdDebug() << "KEEP " << kp << "\n";

  TDEConfig *config = kapp->config();

  config->setGroup("Kpackage");
  config->writeEntry("keepIWin", kp);

  keep = kp;
}

void pkgOptions::getKeep()
{
    TDEConfig *config = kapp->config();
    config->setGroup("Kpackage");
    keep =  config->readBoolEntry("keepIWin", true);
  kdDebug() << "getKEEP " << keep << "\n";
    Keep->setChecked(keep);

}

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
pkgOptionsI::pkgOptionsI(pkgInterface *pkg, TQWidget *parent):
  pkgOptions(pkg, parent, i18n("Install"))
{
  insType = i18n("Install");
  installer = true;
  setupWidgets(pkg->paramsInst);
}

TQString pkgOptionsI::doPackages(int installFlags, TQPtrList<packageInfo> *p, bool &test)
{
  return pkgInt->install(installFlags, p, test);
}

///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
pkgOptionsU::pkgOptionsU(pkgInterface *pkg, TQWidget *parent):
  pkgOptions(pkg, parent, i18n("Uninstall"))
{
  insType = i18n("Uninstall");
  installer = false;
  setupWidgets(pkg->paramsUninst);
}

TQString pkgOptionsU::doPackages(int installFlags, TQPtrList<packageInfo> *p, bool &test)
{
  return pkgInt->uninstall(installFlags, p, test);
}
#include "pkgOptions.moc"
