"""IC wrapper module, based on Internet Config 1.3"""

import icglue
import string
import sys
import Res
import macfs
import macostools

error=icglue.error

# From ictypes.h:
icPrefNotFoundErr = -666		# preference not found (duh!)
icPermErr = -667				# cannot set preference
icPrefDataErr = -668			# problem with preference data
icInternalErr = -669			# hmm, this is not good
icTruncatedErr = -670			# more data was present than was returned
icNoMoreWritersErr = -671		# you cannot begin a write session because someone else is already doing it */
icNothingToOverrideErr = -672	# no component for the override component to capture
icNoURLErr = -673				# no URL found
icConfigNotFoundErr = -674		# no configuration was found
icConfigInappropriateErr = -675	# incorrect manufacturer code

ICattr_no_change = -1

icNoPerm = 0
icReadOnlyPerm = 1
icReadWritePerm = 2
# End of ictypes.h

class ICOpaqueData:
	"""An unparseable IC entry"""
	def __init__(self, data):
		self.data = data

	def __repr__(self):
		return "ICOpaqueData(%s)"%`self.data`

_ICOpaqueDataType=type(ICOpaqueData(''))
		
def _decode_default(data, key):
	if len(data) == 0:
		return data
	if ord(data[0]) == len(data)-1:
		# Assume Pstring
		return data[1:]
	return ICOpaqueData(data)
	
	
def _decode_multistr(data, key):
	numstr = ord(data[0]) << 8 | ord(data[1])
	rv = []
	ptr = 2
	for i in range(numstr):
		strlen = ord(data[ptr])
		str = data[ptr+1:ptr+strlen+1]
		rv.append(str)
		ptr = ptr + strlen + 1
	return rv
	
def _decode_fontrecord(data, key):
	size = ord(data[0]) << 8 | ord(data[1])
	face = ord(data[2])
	namelen = ord(data[4])
	return size, face, data[5:5+namelen]
	
def _decode_boolean(data, key):
	return ord(data[0])
	
def _decode_text(data, key):
	return data
	
def _decode_charset(data, key):
	return data[:256], data[256:]
	
def _decode_appspec(data, key):
	namelen = ord(data[4])
	return data[0:4], data[5:5+namelen]

def _code_default(data, key):
	return chr(len(data)) + data
		
def _code_multistr(data, key):
	numstr = len(data)
	rv = chr((numstr>>8) & 0xff) + chr(numstr & 0xff)
	for i in data:
		rv = rv + _code_default(i)
	return rv
	
def _code_fontrecord(data, key):
	size, face, name = data
	return chr((size>>8) & 0xff) + chr(size & 0xff) + chr(face & 0xff) + \
		chr(0) + _code_default(name)
	
def _code_boolean(data, key):
	print 'XXXX boolean:', `data`
	return chr(data)
	
def _code_text(data, key):
	return data
	
def _code_charset(data, key):
	return data[0] + data[1]
	
def _code_appspec(data, key):
	return data[0] + _code_default(data[1])
	
_decoder_table = {
	"ArchieAll" : (_decode_multistr , _code_multistr),
	"UMichAll" : (_decode_multistr , _code_multistr),
	"InfoMacAll" : (_decode_multistr , _code_multistr),
	"ListFont" : (_decode_fontrecord , _code_fontrecord),
	"ScreenFont" : (_decode_fontrecord , _code_fontrecord),
	"PrinterFont" : (_decode_fontrecord , _code_fontrecord),
#	"DownloadFolder" : (_decode_filespec , _code_filespec),
	"Signature": (_decode_text , _code_text),
	"Plan" : (_decode_text , _code_text),
	"MailHeaders" : (_decode_text , _code_text),
	"NewsHeaders" : (_decode_text , _code_text),
#	"Mapping" 
	"CharacterSet" : (_decode_charset , _code_charset),
	"Helper\245" : (_decode_appspec , _code_appspec),
#	"Services" : (_decode_services, ????),
	"NewMailFlashIcon" : (_decode_boolean , _code_boolean),
	"NewMailDialog" : (_decode_boolean , _code_boolean),
	"NewMailPlaySound" : (_decode_boolean , _code_boolean),
#	"WebBackgroundColor" : _decode_color,
	"NoProxyDomains" : (_decode_multistr , _code_multistr),
	"UseHTTPProxy" : (_decode_boolean , _code_boolean),
	"UseGopherProxy": (_decode_boolean , _code_boolean),
	"UseFTPProxy" : (_decode_boolean , _code_boolean),
	"UsePassiveFTP" : (_decode_boolean , _code_boolean),
}

def _decode(data, key):
	if '\245' in key:
		key2 = key[:string.index(key, '\245')+1]
	else:
		key2 = key
	if _decoder_table.has_key(key2):
		decoder = _decoder_table[key2][0]
	else:
		decoder = _decode_default
	return decoder(data, key)

def _code(data, key):
	if type(data) == _ICOpaqueDataType:
		return data.data
	if '\245' in key:
		key2 = key[:string.index(key, '\245')+1]
	else:
		key2 = key
	if _decoder_table.has_key(key2):
		coder = _decoder_table[key2][1]
	else:
		coder = _code_default
	return coder(data, key)
	
class IC:
	def __init__(self, signature='Pyth', ic=None):
		if ic:
			self.ic = ic
		else:
			self.ic = icglue.ICStart(signature)
			if hasattr(self.ic, 'ICFindConfigFile'):
				self.ic.ICFindConfigFile()
		self.h = Res.Resource('')
			
	def keys(self):
		rv = []
		self.ic.ICBegin(icReadOnlyPerm)
		num = self.ic.ICCountPref()
		for i in range(num):
			rv.append(self.ic.ICGetIndPref(i+1))
		self.ic.ICEnd()
		return rv
		
	def has_key(self, key):
		try:
			dummy = self.ic.ICFindPrefHandle(key, self.h)
		except icglue.error:
			return 0
		return 1
		
	def __getitem__(self, key):
		attr = self.ic.ICFindPrefHandle(key, self.h)
		return _decode(self.h.data, key)
		
	def __setitem__(self, key, value):
		value = _code(value, key)
		self.ic.ICSetPref(key, ICattr_no_change, value)
		
	def launchurl(self, url, hint=""):
		self.ic.ICLaunchURL(hint, url, 0, len(url))
		
	def parseurl(self, data, start=None, end=None, hint=""):
		if start == None:
			selStart = 0
			selEnd = len(data)
		else:
			selStart = selEnd = start
		if end != None:
			selEnd = end
		selStart, selEnd = self.ic.ICParseURL(hint, data, selStart, selEnd, self.h)
		return self.h.data, selStart, selEnd
		
	def mapfile(self, file):
		if type(file) != type(''):
			file = file.as_tuple()[2]
		return self.ic.ICMapFilename(file)
		
	def maptypecreator(self, type, creator, filename=""):
		return self.ic.ICMapTypeCreator(type, creator, filename)
		
	def settypecreator(self, file):
		if type(file) == type(''):
			fss = macfs.FSSpec(file)
		else:
			fss = file
		name = fss.as_tuple()[2]
		record = self.mapfile(name)
		fss.SetCreatorType(record[2], record[1])
		macostools.touched(fss)
		
# Convenience routines
_dft_ic = None

def launchurl(url, hint=""):
	global _dft_ic
	if _dft_ic == None: _dft_ic = IC()
	return _dft_ic.launchurl(url, hint)
	
def parseurl(data, start=None, end=None, hint=""):
	global _dft_ic
	if _dft_ic == None: _dft_ic = IC()
	return _dft_ic.parseurl(data, start, end, hint)
	
def mapfile(filename):
	global _dft_ic
	if _dft_ic == None: _dft_ic = IC()
	return _dft_ic.mapfile(filename)
	
def maptypecreator(type, creator, filename=""):
	global _dft_ic
	if _dft_ic == None: _dft_ic = IC()
	return _dft_ic.maptypecreator(type, creator, filename)
	
def settypecreator(file):
	global _dft_ic
	if _dft_ic == None: _dft_ic = IC()
	return _dft_ic.settypecreator(file)
		
def _test():
	ic = IC()
	for k in ic.keys():
		try:
			v = ic[k]
		except error:
			v = '????'
		print k, '\t', v
	sys.exit(1)
	
if __name__ == '__main__':
	_test()
	
