import sys
import string
import glob
import regex
import os
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 getSpeci(self):
	pass

    def getIcon(self):
	return self.icon

    def getGroup(self):
	return self.group

    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 PackageNamed(Package):

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

class AvailablePackage(Package):
    regex.set_syntax(RE_SYNTAX_AWK)
    oldlabelex = regex.compile("(.*):(.*):(.*)")
    labelex = regex.compile("(.*)-([^-]*)-([^-]*)")

    def readHeader(self):
	package = open(self.filename)

	magic = nostoi(package.read(4))
	self.major = ord(package.read(1))
	self.minor = ord(package.read(1))

	if (self.major > 1):
	    raise IOError, ("Cannot read package version %d -- upgrade me"
		% self.major)

	self.type = nostos(package.read(2))
	self.cpu = nostos(package.read(2))
	label = package.read(66)
	label = label[0:string.find(label,"\0")]
	if (self.labelex.search(label) == -1) :
	    if (self.oldlabelex.search(label) == -1) :
	        raise IOError, "Invalid binary package - " + filename
	    else:
		(self.name, self.version, self.release) = \
			self.oldlabelex.group(1, 2, 3)
	else:
	    (self.name, self.version, self.release) = \
		self.labelex.group(1, 2, 3)

	self.specoff = nostoi(package.read(4))
	self.speclen = nostoi(package.read(4))
	self.archiveoffset = nostoi(package.read(4))
	self.size = nostoi(package.read(4))
	self.os = nostoi(package.read(4))

	if (self.minor > 0):
	    groupLength = nostoi(package.read(4))
	    iconLength = nostoi(package.read(4))
	    if (not groupLength):
		self.group = "Unknown"
	    else:
		self.group = package.read(groupLength)
	    if (iconLength):
		self.icon = package.read(iconLength)
	else:
	    self.group = "Old Packages"

	package.close()

    def parseSpeci(self):
	package = open(self.filename)

	package.seek(self.specoff, 0)
	str = (package.read(self.speclen))
	str = str[0:string.find(str,"\0")]
	self.speci = SpeciFromFile(str)
	self.speci.parse()
	package.close()
	self.parsedSpeci = 1

    def getSpeci(self):
	if (not self.parsedSpeci):
	    self.parseSpeci()

	return self.speci

    def getPath(self):
	return self.filename
	
    def __init__(self, filename):
	Package.__init__(self)

	self.filename = filename
	self.readHeader()
	self.parsedSpeci = 0

def nostoi(str):
    (a, b, c, d) = unpack("4c", str)
    return (ord(a) << 24) + (ord(b) << 16) + (ord(c) << 8) + ord(d);

def nostos(str):
    (a, b) = unpack("2c", str)
    return ((ord(a) << 8) + ord(b))
