# 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.

import sys
import string
import glob
import regex
import os
import rpm

from regex_syntax import RE_SYNTAX_AWK
from struct import *
from icon import *
from speci import *

class Package:
    def getSize(self):
	return self.size

    def getIcon(self):
	return self.icon

    def getGroup(self):
	if (self.group):
	    return self.group
	else:
	    return "None"

    def getVersion(self):
	return self.version

    def getRelease(self):
	return self.release

    def getName(self):
	return self.name

    def getIdent(self):
	return self.name + "-" + self.version + "-" + self.release
 
    def getLabel(self):
	return self.name + ":" + self.version + ":" + self.release
 
    def getRevision(self):
	return self.version + "-" + self.release

    def unselect(self):
	if (self.selected):
	    self.selected = 0
	    for key in self.callbacks.keys():
		(cb, data) = self.callbacks[key]
		cb(0, data)

    def select(self):
	if (not self.selected):
	    self.selected = 1
	    for key in self.callbacks.keys():
		(cb, data) = self.callbacks[key]
		cb(1, data)

    def isSelected(self):
	return self.selected

    def toggleSelect(self):
	if (self.selected):
	    self.unselect()
	else:
	    self.select()

    def addSelectCallback(self, cb, owner, data):
	self.callbacks[owner] = (cb, data)

    def removeSelectCallback(self, owner):
	del self.callbacks[owner]
    
    def __init__(self):
	self.selected = 0
	self.size = -1
	self.callbacks = {}
	self.icon = None

class HeaderPackage(Package):
    def getSize(self):
	return self.h[rpm.RPMTAG_SIZE]

    def getIcon(self):
	return self.h[rpm.RPMTAG_GIF]

    def getGroup(self):
	if (self.h[rpm.RPMTAG_GROUP]):
	    return self.h[rpm.RPMTAG_GROUP]
	else:
	    return "None"

    def getVersion(self):
	return self.h[rpm.RPMTAG_VERSION]

    def getRelease(self):
	return self.h[rpm.RPMTAG_RELEASE]

    def getName(self):
	return self.h[rpm.RPMTAG_NAME]

    def getDescription(self):
	return self.h[rpm.RPMTAG_DESCRIPTION]

    def getBuildhost(self):
	return self.h[rpm.RPMTAG_BUILDHOST]

    def getBuilddate(self):
	return self.h[rpm.RPMTAG_BUILDTIME]

    def getDistribution(self):
	return self.h[rpm.RPMTAG_DISTRIBUTION]

    def getVendor(self):
	return self.h[rpm.RPMTAG_VENDOR]

    def getIdent(self):
	return (self.getName() + "-" + self.getVersion() + "-" + 
		self.getRelease())
 
    def getLabel(self):
	return (self.getName() + ":" + self.getVersion() + ":" + 
		self.getRelease())
 
    def getRevision(self):
	return self.getVersion() + "-" + self.getRelease()

    def getFileEntries(self):
	if (self.fileEntriesCache):
	    return self.fileEntriesCache

	fileNames = self.h[rpm.RPMTAG_FILENAMES]
	fileSizes = self.h[rpm.RPMTAG_FILESIZES]
	fileMd5s = self.h[rpm.RPMTAG_FILEMD5S]
	fileLinks = self.h[rpm.RPMTAG_FILELINKTOS]
	fileMtimes = self.h[rpm.RPMTAG_FILEMTIMES]
	fileModes = self.h[rpm.RPMTAG_FILEMODES]
	fileFlags = self.h[rpm.RPMTAG_FILEFLAGS]
	fileStates = self.h[rpm.RPMTAG_FILESTATES]
	self.fileEntriesCache = []
	for i in range(len(fileNames)):
	    if (fileFlags[i] & rpm.RPMFILE_DOC): 
		isDoc = "1"
	    else:
		isDoc = None;

	    if (fileFlags[i] & rpm.RPMFILE_CONFIG): 
		isConf = "1"
	    else:
		isConf = None;

	    if (fileFlags[i] == rpm.RPMFILE_STATE_REPLACED):
		s = 'replaced'
	    elif (fileFlags[i] == rpm.RPMFILE_STATE_NOTINSTALLED):
		s = 'not installed'
	    else:
		s = 'normal'
	
	    f = File((fileNames[i], fileSizes[i], fileMtimes[i], fileMd5s[i], 
			fileModes[i], 0, 0, isConf, isDoc, 0, fileLinks[i]))
	    f.setState(s)
	    self.fileEntriesCache.append(f)

	return self.fileEntriesCache
   
    def verifyFile(self, fileNumber):
	return self.h.verifyFile(fileNumber)

    def unselect(self):
	if (self.selected):
	    self.selected = 0
	    for key in self.callbacks.keys():
		(cb, data) = self.callbacks[key]
		cb(0, data)

    def select(self):
	if (not self.selected):
	    self.selected = 1
	    for key in self.callbacks.keys():
		(cb, data) = self.callbacks[key]
		cb(1, data)

    def isSelected(self):
	return self.selected

    def toggleSelect(self):
	if (self.selected):
	    self.unselect()
	else:
	    self.select()

    def addSelectCallback(self, cb, owner, data):
	self.callbacks[owner] = (cb, data)

    def removeSelectCallback(self, owner):
	del self.callbacks[owner]
    
    def __init__(self, header):
	self.h = header
	self.selected = 0
	self.size = -1
	self.callbacks = {}
	self.icon = None
	self.fileEntriesCache = None

class PackageNamed(Package):

    def __init__(self, name):
	Package.__init__(self)
	self.name = name

class AvailablePackage(HeaderPackage):

    def getPath(self):
	return self.filename

    def __init__(self, filename):

	self.filename = filename

	try:
	    (header, isSource) = rpm.headerFromFile(filename)
	except rpm.error:
	    header = None

	if (isSource):
	    return None

	if (header == None):
	    raise IOError, "cannot read package header"

	HeaderPackage.__init__(self, header)
