# GLINT graphical package management
# Copyright (C) 1995 Red Hat, Inc
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.

from package import *
from rpmdb import *
from rhtkinter import RHFrame
from scale import Scale

class PackageSet:
    def containsLabel(self, label):
	return self.packages.has_key(label)
	
    def getPackage(self, label):
	if (self.packages.has_key(label)):
	    return self.packages[label]
	else:
	    return None

    def addChangeCallback(self, cb, owner, data):
	self.changeCallbacks[owner] = (cb, data)
	
    def removeChangeCallback(self, owner):
	del self.changeCallbacks[owner]
	
    def addPackage(self, package):
	self.packages[package.getLabel()] = package
	changes = [ ( '+', package),  ]
	for cbinfo in self.changeCallbacks.values():
	    (cb, data) = cbinfo
	    cb(self, data, changes)

    def removePackage(self, label):
	package = self.packages[label]
	del self.packages[label]
	change = [ ( '-', package) ]
	for cbinfo in self.changeCallbacks.values():
	    (cb, data) = cbinfo
	    cb(self, data, change)

    def concat(self, ps):
	for p in ps.getPackages():
	    self.addPackage(p)
	
    def getPackages(self):
        return self.packages.values()

    def selectedPackages(self):
	ps = PackageSet()
	for p in self.packages.values():
	    if p.isSelected():
		ps.addPackage(p)
	return ps

    def addPackageFromCache(self, label):
	if (self.packageCache.has_key(label) and 
		(not self.packages.has_key(label))):
	    self.addPackage(self.packageCache[label])

    def cacheCurrentSet(self):
	self.packageCache = {}
	for label in self.packages.keys():
	    self.packageCache[label] = self.packages[label]

    def setDiff(self, subset):
	p = PackageSet()

	for label in self.packages.keys():
	    if (subset.getPackage(label)):
		self.removePackage(label)

    def unselectAll(self):
	for p in self.packages.values():
	    p.unselect()

    def selectAll(self):
	for p in self.packages.values():
	    p.select()

    def numPackages(self):
	return len(self.packages)

    def numSelected(self):
	res = 0
	for p in self.packages.values():
	    if p.isSelected():
		res = res + 1
	return res

    def __init__(self):
	self.packages = {}
	self.changeCallbacks = {}
	self.packageCache = None

class InstalledPackageSet(PackageSet):

    def mightNowHave(self, label):
	if (self.db.containsPackageLabel(label)):
	    package = InstalledPackage(label, self.db)
	    self.addPackage(package)

    def mightNotHave(self, label):
	if (not self.db.containsPackageLabel(label)):
	    self.removePackage(label)

    def reloadPackages(self):
	labels = self.db.packageLabels()
	for label in labels:
	    package = InstalledPackage(label, self.db)
	    self.addPackage(package)

    def close(self):
	self.db.close()

    def reopen(self):
	self.db.reopen()

    def __init__(self, prefix="/var/lib/rpm"):
	PackageSet.__init__(self)
	self.db = RPMDatabase(prefix)
	self.reloadPackages()

class PackagePathSet(PackageSet):

    def setPath(self, path):
	list = glob.glob(path + "/*")

	if len(list):
	    w = ScanningWindow("Scanning", len(list), Toplevel());
	    num = 0
	    w.setAmount(num)
	    for file in list:
		try:
		    package = AvailablePackage(file)
		    self.addPackage(package)
		except IOError, mesg:
		    pass
		num = num + 1
		w.setAmount(num)
	    w.quit()

    def __init__(self, path):
	PackageSet.__init__(self)
	self.setPath(path)

class ScanningWindow(RHFrame):

    def createWidgets(self, total):
	self.message = Label(self, { 'text' : 
				'Scanning available packages...', 
						'anchor' : 'w' } )

	self.message.pack()

	self.scale = Scale(100, 20, total, self)
	self.scale.pack()

	self.pack()

    def setAmount(self, amount):
	self.scale.set(amount)
	self.update()

    def __init__(self, title, num, Master = None):
	RHFrame.__init__(self, Master)
	self.createWidgets(num)

	if (Master):
	    Master.title(title)
