/* packageDisplay.cpp
**
** Copyright (C) 1999,2000 Toivo Pedaste <toivo@ucs.uwa.edu.au>
**
// Author: Damyan Pepper
// Author: Toivo Pedaste
*/

/*
** 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., 59 Temple Place, Suite 330, Boston,
** MA 02111-1307, USA.
*/

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


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

// Qt headers

#include <qapplication.h>
#include <qfileinfo.h>
#include <qtextedit.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()
{
    delete blank;
}

void packageDisplayWidget::setupWidgets()
{
  proptab = new QVBox( this);
  curTab = proptab;
  fltab = new QVBox( this);
  cltab = 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 *)) );

  changeLog = new QTextEdit(cltab);

  addTab(proptab, i18n("Properties"));
  addTab(fltab, i18n("File List"));
  addTab(cltab, i18n("Change Log"));

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

  connect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *)));
}

void packageDisplayWidget::tabSelected(QWidget *tab)
{
  curTab = tab;
  tabSet(tab);
}

void packageDisplayWidget::tabSet(QWidget *tab)
{
  disconnect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *)));
  if(tab == proptab) {
    packageProperties->show();
    fileList->hide();
    changeLog->hide();
    setCurrentPage(0);
  } else if (tab == fltab) {
    packageProperties->hide();
    changeLog->hide();
    if (isTabEnabled(fltab)) {
      if (!initList) {
	updateFileList();
	initList = 1;
      } 
      fileList->show();
    } else {
      fileList->hide();
    }
    setCurrentPage(1);
  } else {
    fileList->hide();
    packageProperties->hide();
    if (isTabEnabled(cltab)) {
      updateChangeLog();
      changeLog->show();
    } else {
      changeLog->hide();
    }
    setCurrentPage(2);
  }
  connect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *)));
}

void packageDisplayWidget::noPackage()
{
  disconnect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *)));
  
  if (isTabEnabled(fltab)) {
    fileList->setColumnText(0,"");
    setTabEnabled(fltab,false);
  }
  if (isTabEnabled(proptab))
    setTabEnabled(proptab,false);
  if (isTabEnabled(cltab))
    setTabEnabled(cltab,false);

  packageProperties->changePackage(NULL);

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

  connect(this,SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *)));
}

// Change packages
void packageDisplayWidget::changePackage(packageInfo *p)
{

// 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;
	}
	package->interface = np->interface;
	delete np;
	package->updated = TRUE;
      }
    }

    initList = 0;
    packageProperties->changePackage(package);

    if (package->interface->changeTab(package))
      setTabEnabled(cltab,true);
    else
      setTabEnabled(cltab,false);

    if (package->interface->filesTab(package))
      setTabEnabled(fltab,true);
    else
      setTabEnabled(fltab,false);

    setTabEnabled(proptab,true);
 
    tabSet(curTab);


  }
  connect(fileList, SIGNAL(clicked(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );
  connect(fileList, SIGNAL(returnPressed(QListViewItem *)),
            this, SLOT( openBinding(QListViewItem *)) );

 }

void packageDisplayWidget::updateChangeLog()
{
  if (!package)
    return;

  QStringList lines;
  QString stmp;
  lines = package->interface->getChangeLog(package);


  changeLog->setTextFormat(Qt::LogText);
  changeLog->hide();
  if (lines.count() > 1) {
    changeLog->setText("");
    for (QStringList::ConstIterator it = lines.begin();
	 (it != lines.end());
	 it++) {
      if (! (*it).isEmpty())
	changeLog->append(*it);
      else
	changeLog->append(" ");
    }
  } else {
    changeLog->setText(i18n(" - No change log -"));
  }

  changeLog->show();
  changeLog->setContentsPos(0,0);

}

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)
{
    if ( !index )
        return;
    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"
