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

from warnings import warnpy3k
warnpy3k("In 3.x, the ic module is removed.", stacklevel=2)

import icglue
import string
import sys
import os
from Carbon import Res
import Carbon.File
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(%r)"%(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:', repr(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 key2 in _decoder_table:
        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 key2 in _decoder_table:
        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):
        return self.__contains__(key)

    def __contains__(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=""):
        # Work around a bug in ICLaunchURL: file:/foo does
        # not work but file:///foo does.
        if url[:6] == 'file:/' and url[6] != '/':
            url = 'file:///' + url[6:]
        self.ic.ICLaunchURL(hint, url, 0, len(url))

    def parseurl(self, data, start=None, end=None, hint=""):
        if start is None:
            selStart = 0
            selEnd = len(data)
        else:
            selStart = selEnd = start
        if end is not 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):
        file = Carbon.File.pathname(file)
        record = self.mapfile(os.path.split(file)[1])
        MacOS.SetCreatorAndType(file, record[2], record[1])
        macostools.touched(fss)

# Convenience routines
_dft_ic = None

def launchurl(url, hint=""):
    global _dft_ic
    if _dft_ic is None: _dft_ic = IC()
    return _dft_ic.launchurl(url, hint)

def parseurl(data, start=None, end=None, hint=""):
    global _dft_ic
    if _dft_ic is None: _dft_ic = IC()
    return _dft_ic.parseurl(data, start, end, hint)

def mapfile(filename):
    global _dft_ic
    if _dft_ic is None: _dft_ic = IC()
    return _dft_ic.mapfile(filename)

def maptypecreator(type, creator, filename=""):
    global _dft_ic
    if _dft_ic is None: _dft_ic = IC()
    return _dft_ic.maptypecreator(type, creator, filename)

def settypecreator(file):
    global _dft_ic
    if _dft_ic is 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()
