/*
 * kdpkg.cpp
 *
 * Copyright (c) 2007 Fabian Wuertz
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#include <tdefiledialog.h>
#include <tdemessagebox.h>
#include <kgenericfactory.h>
#include <tdeaboutapplication.h>
#include <kurlrequester.h>

#include <tqlabel.h>
#include <tqlineedit.h>
#include <tqlistview.h>
#include <tqlistbox.h>
#include <tqtextbrowser.h>
#include <tqwidgetstack.h>
#include <tqprocess.h>
#include <tqregexp.h>
#include <tqfiledialog.h>



#include "kdpkg.h"


kdpkg::kdpkg( const TQString &url, TQWidget *parent, const char *name, const TQStringList &)
:KdpkgDialog(parent, name)
{
	

	if( !url )
		path = KFileDialog::getOpenFileName( TQString(), TQString("*.deb|") + i18n("Debian Package (*.deb)"), this, i18n("Choose a Debian package file to open"));
	else
		path = url;

	this->shell = new Process();


	// show fields
	this->shell->setCommand("dpkg -f "+path);
	this->shell->start(true);
	fields =  TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() );
	showFields();


	// show files
	this->shell->setCommand("dpkg -c "+path);
	this->shell->start(true);
	TQStringList files = TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() );
	TQString tmp;
	for(uint i = 0; i < files.count(); i++)
		tmp += TQStringList::split( ".", files[i])[1]+"<br>";
	filesTextBrowser->setText( tmp ) ;


}


//----------------------------------------------------------------------------//
//--- show info --------------------------------------------------------------//
//----------------------------------------------------------------------------//


void kdpkg::showFields()
{

	// checkArchitecture
	//-------------------
	checkArchitecture( fields.grep("Architecture:")[0].mid(14) );


	// common
	//--------
	TQString pkgName = fields.grep("Package:")[0].mid(9);
	TQString pkgVersion = fields.grep("Version:")[0].mid(9);
	TQStringList versions = getVersions(fields.grep("Package:")[0].mid(9));
	TQString sysVersion = versions[0];
	TQString repVersion = versions[1];

	package2TextLabel->setText( pkgName );
	version2TextLabel->setText( pkgVersion+" (Package)<br>"+sysVersion+" (System)<br>"+repVersion+" (Repository)");
	maintainer2TextLabel->setText( fields.grep("Maintainer:")[0].mid(12) );
	section2TextLabel->setText( fields.grep("Section:")[0].mid(9)+" ("+fields.grep("Priority:")[0].mid(10)+")" );
	size2TextLabel->setText( fields.grep("Installed-Size:")[0].mid(16)+" kb" );


	// description
	//-------------
	TQStringList tmp = fields.grep( TQRegExp("^ ") );
	TQString description = "<b>"+fields.grep("Description:")[0].mid(13)+"</b><br><br>";
	for(uint i = 0; i < tmp.count(); i++)
	{
		if( tmp[i] == " ." )
			description += "<br>";
		else
			description += tmp[i].mid(1)+"<br>";
	}
	descriptionTextBrowser->setText(description );


	// dependencies
	//--------------
	types.append("Depends");
	types.append("Recommends");
	types.append("Suggests");
	types.append("Enhances");
	types.append("Pre-Depends");
	types.append("Provides");
	types.append("Conflicts");
	types.append("Replaces");

	for( TQStringList::Iterator it = types.begin(); it != types.end(); ++it )
		dependencies.append(fields.grep(*it+":")[0]);
	showDependencies(0);
}


//----------------------------------------------------------------------------//
//--- show dependencies ------------------------------------------------------//
//----------------------------------------------------------------------------//


void kdpkg::showDependencies(int i)
{

	dependenciesListBox->clear();


	if(i ==  0) // all
	{

		for( TQStringList::Iterator it = dependencies.begin(); it != dependencies.end(); ++it )
		{
			TQStringList tmp = TQStringList::split(  ", ", *it );
			TQString type = TQStringList::split(  ":", tmp[0])[0];
			tmp[0] = TQStringList::split(  ": ", tmp[0] )[1];
			for(uint i = 0; i < tmp.count(); i++)
				dependenciesListBox->insertItem( type+": "+tmp[i] );
		}
	}
	else
	{
		TQString choice = types[i-1];
		dependenciesListBox->insertStringList( TQStringList::split( ", ", dependencies.grep(choice+":")[0].mid(choice.length()+2) ) );
	}
}


//----------------------------------------------------------------------------//
//--- get --------------------------------------------------------------------//
//----------------------------------------------------------------------------//

TQStringList kdpkg::getVersions(TQString package)
{
	this->shell->setCommand("apt-cache policy "+package);
	this->shell->start(true);
	TQStringList input = TQStringList::split( "\n", this->shell->getBuffer().stripWhiteSpace() );

	TQString sysVersion = input[1];
	sysVersion = TQStringList::split( ":", sysVersion)[1].replace(" ","");

	if( sysVersion.contains("(") || sysVersion == "" )
		sysVersion = i18n("not installed");


	TQString repVersion = input[2];
	repVersion = TQStringList::split( ":", repVersion)[1].replace(" ","");

	if( repVersion.contains("(") || repVersion == "" )
		repVersion = i18n("not available");


	TQStringList versions;
	versions.append(sysVersion);
	versions.append(repVersion);

	return versions;
}


//----------------------------------------------------------------------------//
//--- architecture -----------------------------------------------------------//
//----------------------------------------------------------------------------//


void kdpkg::checkArchitecture(TQString arch)
{
	if(arch == "all")
		return;

	// get architecture
	this->shell->setCommand("dpkg --print-architecture");
	this->shell->start(true);

	if( arch == this->shell->getBuffer().stripWhiteSpace() )
		return;

	KMessageBox::information(this, i18n("The architecture of the package and the system doesn't match! You will not be able to install this package!"));

	installPushButton->setEnabled(false);
}


//----------------------------------------------------------------------------//
//--- about ------------------------------------------------------------------//
//----------------------------------------------------------------------------//


void kdpkg::about()
{

	TDEAboutApplication* about = new TDEAboutApplication ( this );
	about->show();
}


//------------------------------------------------------------------------------
//--- install ------------------------------------------------------------------
//------------------------------------------------------------------------------


void kdpkg::install()
{
	this->shell->setCommand("su-to-root -X -c \"kdpkg-install "+path+"\"&");
	this->shell->start(true);
	close();
}



#include "kdpkg.moc"
