#stub - to be completed.
import os, time
from types import ListType, StringType, TupleType

import pyRXP
from rlextra.radxml import xmlutils
import rlextra.forms
from rlextra.forms.qbase import QBase
from rlextra.forms.qwidget import DynamicQWidget

def findDtdDir():
    return os.path.dirname(rlextra.forms.__file__)

def parseQdfFile(filename, questionnaire,
                 dtdDir=None,prefix='', overrideName=None, eoCB=None):
    "Returns a QBase class from a file"
    from reportlab.lib.utils import open_and_read
    xmlText = open_and_read(filename, 't')
    return parseQdfText(xmlText,questionnaire,dtdDir,prefix,overrideName,eoCB=eoCB)

def parseQdfText(text, questionnaire,
                 dtdDir=None,prefix='', overrideName=None, eoCB=None):
    "Returns a QBase class from text xml input"
    if dtdDir or dtdDir is None:
        cwd = os.getcwd()
        if not dtdDir: dtdDir=findDtdDir()
        os.chdir(dtdDir)
    else:
        cwd = None

    if pyRXP.version>='0.5':
        parser = pyRXP.Parser(eoCB=eoCB)
        tree = parser.parse(text)
    else:
        tree = pyRXP.parse(text)

    if cwd: os.chdir(cwd)
    xmlutils.stripWhitespace(tree)
    return makeObjects(tree, questionnaire, prefix=prefix, overrideName=overrideName)

def makeObjects(tagTree, questionnaire, defaultClass=QBase, prefix='',overrideName=None):
    """Generic routine for mapping XML onto a tree of objects.

    For each tag it tries to find a corresponding class, and
    instantiates one.  If it cannot do so, it uses the default
    class passed in using the None dictionary key in the class map."""
    #started = time.clock()
    (tagName, attrs, children, stuff) = tagTree
    nameAttr = attrs.get('name')
    object = questionnaire.createQbase(prefix, tagName, nameAttr, defaultClass)
    if attrs is not None:
        for (key, value) in attrs.items():
            setattr(object, key, value)
    if overrideName:
        #print 'makeObjects on tag %s called with overrideName %s, prefix=%s' % (tagName, overrideName, prefix)
        object.name = overrideName

    if children not in (None, []):
        #what to do with them?
        prefix = (prefix and prefix + '.' or '') + object.name
        converted = []
        for child in children:
            if type(child) in (ListType, TupleType):
                converted.append(makeObjects(child, questionnaire, defaultClass=defaultClass, prefix=prefix))
            else: #string
                converted.append(child)

        if hasattr(object, 'addChild'):
            for childObject in converted:
                object.addChild(childObject)
        else:
            object.children = converted

    if hasattr(object, 'postInit'):
        object.postInit()
    #finished = time.clock()
    #print 'constructed <%s> and contents in %0.4f seconds' % (tagName, finished-started)
    return object

def test():
    import time
    started = time.clock()
    q = parseQdfFile('test\\example2_fund.qdf')
    finished = time.clock()
    print 'parsed in %0.4f seconds' % (finished-started)
    return q

if __name__=='__main__':
    test()
