////////////////////////////////////////////////////////////////////////////////
//      $Id: packageDisplay.cpp,v 1.34 2002/02/18 10:58:01 mlaurent Exp $ 
// File  : packageDisplay.cpp
// Author: Damyan Pepper
// Author: Toivo Pedaste
//
///////////////////////////////////////////////////////////////////////////////

#include "../config.h"
// Standard headers
#include <stdio.h>

// Qt headers

#include <qapplication.h>
#include <qfileinfo.h> 

#include <kiconloader.h> 
#include <kglobal.h>
#include <krun.h>
#include <kopenwith.h>
// kpackage.headers
#include "kpackage.h"
#include "packageDisplay.h"
#include "packageProperties.h"
#include "pkgInterface.h"
#include "utils.h"
#include "options.h"
#include <klocale.h>

extern Opts *opts;

// constructor
packageDisplayWidget::packageDisplayWidget(QWidget *parent)
  : QTabWidget(parent)
{
  // Initially we're not dealing with any package
  package=NULL;

  // Set up the widgets
  setupWidgets();

  // Load the pixmaps
  tick = UserIcon("ptick");
  cross = UserIcon("cross");
  question = UserIcon("question");
  blank = new QPixmap();

}

packageDisplayWidget::~packageDisplayWidget()
{
}

void packageDisplayWidget::setupWidgets()
{
  proptab = new QVBox( this);
  fltab = new QVBox( this);

  packageProperties = new packagePropertiesWidget(proptab);

  fileList = new KListView(fltab);
  fileList->hide();
  fileList->addColumn("name");
  connect(fileList, SIGNAL(clicked(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );
  connect(fileList, SIGNAL(returnPressed(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );
  addTab(proptab, i18n("Properties"));
  addTab(fltab, i18n("File List"));

  if (isTabEnabled(fltab))
    setTabEnabled(fltab,false);
  if (isTabEnabled(proptab))
    setTabEnabled(proptab,false);

  connect(this,SIGNAL(selected(const QString &)), SLOT(tabSelected(const 
QString &)));
}

void packageDisplayWidget::tabSelected(const QString &tab)
{
  if(tab == i18n("Properties"))
    {
      packageProperties->show();
      fileList->hide();
    }
  else
    {
      packageProperties->hide();
      if (!initList) {
	updateFileList();
	initList = 1;
      }
      fileList->show();
    }
}

void packageDisplayWidget::noPackage()
{
  if (isTabEnabled(fltab)) {
    fileList->setColumnText(0,"");
    setTabEnabled(fltab,false);
  }
  if (isTabEnabled(proptab))
    setTabEnabled(proptab,false);

  packageProperties->changePackage(NULL);

  packageProperties->setText("");
  fileList->clear();
}

// Change packages
void packageDisplayWidget::changePackage(packageInfo *p)
{
  bool tfl = fileList->isVisible();

// This is to stop selectionChanged firing off here
  disconnect(fileList, SIGNAL(clicked(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );
  disconnect(fileList, SIGNAL(returnPressed(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );

   if (package && package != p) {
     if (!package->getItem() && !kpackage->management->allPackages->find(package)) {
       delete package;
       package = 0;
     }
  }

  package = p;
  if (!p) {			// change to no package
    noPackage();
  } else {
    QString u = package->getFilename();
    if (!package->updated &&  !u.isEmpty()) {
      packageInfo *np = package->interface->getPackageInfo('u', u, 0);

      if (np) {
	QDictIterator<QString> it(*(np->getDict())); // update info entries in p
	while (it.current()) {
	  package->info->replace(it.currentKey(),new QString(*(it.current())));
	  ++it;
	}
	delete np;
	package->updated = TRUE;
      }
    }

    initList = 0;
    packageProperties->changePackage(package);
    setTabEnabled(fltab,true);
    setTabEnabled(proptab,true);

    if (tfl)
      tabSelected(i18n("File List"));          
  }
  connect(fileList, SIGNAL(clicked(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );
  connect(fileList, SIGNAL(returnPressed(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );
 }

// update the file list
void packageDisplayWidget::updateFileList()
{
  if (!package)
    return;

  // Get a list of files in the package
  QStringList files;
  QStringList errorfiles;

  // set the status
  kpackage->setStatus(i18n("Updating File List"));

  // clear the file list
  fileList->clear();

  // Check if the package is installed
  int installed;
  if(package->getFilename().isEmpty()) {
    if(package->packageState == packageInfo::UPDATED) {
      fileList->setColumnText(0, "");
      return;
    } else
      installed=1;
  } else
    installed=0;

  files = package->interface->getFileList(package);

  if (files.count() == 0)
    return;

  // Get a list of files that failed verification
  if(installed && opts->VerifyFL) {
    errorfiles = package->interface->verify(package, files);
  } 

  kpackage->setStatus(i18n("Updating File List"));
  
  uint c=0, p=0;
  uint step = (files.count() / 100) + 1;

  QString ftmp;
  ftmp.setNum(files.count());
  ftmp += i18n(" files");

  fileList->setColumnText(0, ftmp);

  QListViewItem *q;

  // Go through all the files
  for (QStringList::ConstIterator it = files.begin(); 
       (it != files.end()); 
       it++) {
    // Update the status progress
    c++;
    if(c > step) {
      c=0;
      p++;
      kpackage->setPercent(p);
    }

    int error=0;
    if (installed) { // see if file failed verification,

      if ( errorfiles.count() > 0) {
	for( QStringList::ConstIterator itError = errorfiles.begin();
	     (itError != errorfiles.end());
	     (itError++) ) {
	  if (*it == *itError) {
	    error = 1;
	  }
	}
      }

      // insert file in tree list with correct pixmap
      if(error) {
	q =  new QListViewItem(fileList, *it);
	q->setPixmap(0,cross);
      } else {
	q =  new QListViewItem(fileList, *it);
	q->setPixmap(0,tick);
      }
    } else {
      q =  new QListViewItem(fileList, *it);
      q->setPixmap(0,question);
    } 
  }

  kpackage->setPercent(100);
}

void packageDisplayWidget::openBinding(QListViewItem *index)
{
    KURL url;
    if (package && package->packageState == packageInfo::INSTALLED) {
      url.setPath( index->text(0) ); // from local file to URL
      if ( !KOpenWithHandler::exists() ) {
	(void) new KFileOpenWithHandler(); // in case of open-with dialog needed
      }
      (void) new KRun ( url ); // run the URL
    }
}


#include "packageDisplay.moc"
