# -*- coding:utf-8 -*-
import os, json
from collections import OrderedDict
from TExcelParser import CExcelParser
from ssat_sdk.utils.string_util import strToList

from xlsConst import xlsConst as xlsc
from BaseLog import CBaseLog
from ExtraData import CExtraData


def parseMoveKey(keyStr):
    return strToList(keyStr, ";")


g_level = ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth',
           'Seventh', 'Eighth', 'Ninth', 'Tenth', 'Eleventh', 'Twelfth']


class CPathParams(CBaseLog):
    def __init__(self):
        CBaseLog.__init__(self)
        self.paths = OrderedDict()

    def addParent(self, level, pDict):
        if level not in self.paths:
            self.paths[level] = {}
        # endif
        pDict["value"] = []
        pDict[xlsc.move_key] = parseMoveKey(pDict[xlsc.move_key])
        if pDict[xlsc.parent] in self.paths:
            self.error("Parent %s conflict." % (pDict[xlsc.parent]))
        self.paths[level][pDict[xlsc.parent]] = pDict

    def addOption(self, level, pDict):
        if level in self.paths:
            if pDict[xlsc.parent] in self.paths[level]:
                if pDict[xlsc.option].__len__() > 0:
                    self.paths[level][pDict[xlsc.parent]]["value"].append(pDict)
            else:
                self.error("Parent %s not exist." % (pDict[xlsc.parent]))
        else:
            self.error("Level %s not exist." % level)


class CValueParams(CBaseLog):
    def __init__(self):
        CBaseLog.__init__(self)
        self.values = OrderedDict()

    def addParent(self, pDict):
        if pDict[xlsc.value_name] in self.values:
            self.error("Parent %s conflict." % (pDict[xlsc.value_name]))
        pDict["value"] = []
        pDict[xlsc.move_key] = parseMoveKey(pDict[xlsc.move_key])
        self.values[pDict[xlsc.value_name]] = pDict

    def addOption(self, pDict):
        if pDict[xlsc.value_name] in self.values:
            if pDict[xlsc.value].__len__() > 0:
                self.values[pDict[xlsc.value_name]]["value"].append(pDict)
        else:
            self.error("Parent %s not exist." % (pDict[xlsc.value_name]))


class CDialogParams(CBaseLog):
    def __init__(self):
        CBaseLog.__init__(self)
        self.dialogs = OrderedDict()

    def addParent(self, level, pDict):
        # endif
        if pDict[xlsc.parent] in self.dialogs:
            self.error("Parent %s conflict." % (pDict[xlsc.parent]))
        pDict["value"] = []
        pDict[xlsc.move_key] = parseMoveKey(pDict[xlsc.move_key])
        self.dialogs[pDict[xlsc.parent]] = pDict

    def addOption(self, level, pDict):
        if pDict[xlsc.parent] in self.dialogs:
            if pDict[xlsc.option].__len__() > 0:
                self.dialogs[pDict[xlsc.parent]]["value"].append(pDict)
        else:
            self.error("Parent %s not exist." % pDict[xlsc.parent])


# 注意:所有不对外暴露的变量和函数需要私有化,以明确哪些接口和参数是对外的。
# 这样便于后期维护时,根据对外的变量和函数来做处理。
class COptionExcel(CBaseLog):
    def __init__(self, exData):
        CBaseLog.__init__(self)
        self.__excelParse = CExcelParser(self)
        self.__exData = exData
        self.__pathParams = CPathParams()
        self.__valueParams = CValueParams()
        self.__dialogParams = CDialogParams()
        # 加载excel;
        self.loadExcel()

    @property
    def pathParams(self):
        return self.__pathParams

    @property
    def valueParams(self):
        return self.__valueParams

    @property
    def dialogParams(self):
        return self.__dialogParams

    # 加载已知表格;
    def loadExcel(self):
        self.info(u"加载excel表")
        if self.__exData.listExcelPath.__len__() == 0:
            self.error(u"没有任何excel表格可加载")

        for xls in self.__exData.listExcelPath:
            self.info(u"当前加载:%s" % xls)
            self.__excelParse.read_excel(xls)

    # 加载其他表格;
    def addExcel(self, xlsPath):
        self.__excelParse.read_excel(xlsPath)

    '''
    函数:获取指定option下的所有子项名称(option作为parent,获取该父项下的所有option字段)
    参数:optionName   作为parent的option;
    返回:该option作为父节点的所有子option名称数组;
        示例:['picture_preset', 'brightness', 'backlight']    
    
    测试:通过。 对应UIT_tree.py中的getSubOptionList。
    '''

    def getOptionAllChildItemName(self, optionName):
        optionList = []
        paths = self.__pathParams.paths
        for level in paths:
            if optionName in paths[level]:
                optionDictList = paths[level][optionName]["value"]
                for optionDict in optionDictList:
                    optionList.append(optionDict["option"])
        return optionList

    '''
        函数:获取指定option/value_name下的所有子项(option/value)的ocr值, 1d表示One-dimensional(一维数组);
        参数:
            optionName      指定的option节点(也可以是value name);
            isOption        是否为路径节点,True路径节点,False为value表的value name节点;
        返回:数组
        示例:
            [
                ['suboption1 ocr', 'ocr2', 'ocr3'],
                ['suboption2 ocr'], 
                ['suboption3 orc']
            ]

        测试:通过。UIT_tree中的x
    '''

    def getOptionAllChildItemTextList1d(self, optionName, isOption=True):
        if type(optionName) == str:
            optionName = unicode(optionName)

        list_ocr = []
        # 路径表或值表;
        if isOption is True:
            found = False
            for lev in self.__pathParams.paths:
                for parent in self.__pathParams.paths[lev]:
                    if parent.lower() == optionName.lower():
                        found = True
                        for item in self.__pathParams.paths[lev][optionName]["value"]:
                            list_ocr.extend(item['option_for_ocr'].split(';'))
                        break
                    # endif
                # endfor
                if found is True:
                    break
            # endfor
        else:
            if optionName in self.__valueParams.values:
                self.info(u"找到%s的value表数据" % optionName)
                for item in self.__valueParams.values[optionName]["value"]:
                    list_ocr.extend(item['value_for_ocr'].split(';'))
            else:
                self.error(u"没有找到%s的value表数据" % optionName)
        # endif
        return list_ocr

    '''
    函数:获取指定option/value_name下的所有子项(option/value)的ocr值,2d表示Two-dimensional(二维数组);
    参数:
            optionName      指定的option节点(也可以是value name);
            isOption        是否为路径节点,True路径节点,False为value表的value name节点;
    返回:字典
    示例:
        [
            ['suboption1 ocr', 'ocr2', 'ocr3'],
            ['suboption2 ocr'], 
            ['suboption3 orc']
        ]

    测试:通过。对应UIT_tree中的get_ocr_list
    '''

    def getOptionAllChildItemTextList2d(self, optionName, isOption=True):
        if type(optionName) == str:
            optionName = unicode(optionName)

        list_ocr = []
        # 路径表或值表;
        if isOption is True:
            found = False
            for lev in self.__pathParams.paths:
                for parent in self.__pathParams.paths[lev]:
                    if parent.lower() == optionName.lower():
                        found = True
                        for item in self.__pathParams.paths[lev][optionName]["value"]:
                            list_ocr.append(item['option_for_ocr'].split(';'))
                        break
                    # endif
                # endfor
                if found is True:
                    break
            # endfor
        else:
            if optionName in self.__valueParams.values:
                self.info(u"找到%s的value表数据" % optionName)
                for item in self.__valueParams.values[optionName]["value"]:
                    list_ocr.append(item['value_for_ocr'].split(';'))
            else:
                self.error(u"没有找到%s的value表数据" % optionName)
        # endif
        return list_ocr

    '''
    函数:获取指定option/value_name下的所有子项(option/value)的ocr键对值;
    参数:
        optionName      指定的option节点(也可以是value name);
        isOption        是否为路径节点,True路径节点,False为value表的value name节点;
    返回:数组
    示例:
        optionName = option
        isOption = True
        返回:
        [
            {'childoption1': 'childoption1 for ocr'}, 
            {'childoption2': 'childoption2 for ocr'},
            {'childoption3': 'childoption3 for ocr'},
        ]
    
    测试:通过。对应UIT_tree中的get_pair_values
    '''

    def getOptionAllChildItemMap(self, optionName, isOption=True):
        if type(optionName) == str:
            optionName = unicode(optionName)
        pairs = []
        # 路径表或值表;
        if isOption is True:
            found = False
            for lev in self.__pathParams.paths:
                for item in self.__pathParams.paths[lev]:
                    if item.lower() == optionName.lower():
                        found = True
                        for item in self.__pathParams.paths[lev][optionName]["value"]:
                            pairs.append({item['option']: item['option_for_ocr'].split(';')})
                        break
                    # endif
                # endfor
                if found is True:
                    break
            # endfor
        else:
            if optionName in self.__valueParams.values:
                for item in self.__valueParams.values[optionName]["value"]:
                    pairs.append({item['value']: item['value_for_ocr'].split(';')})
        # endif

        return pairs

    '''
    函数:获取指定option/value_name下的所有兄弟项(相同parent)的ocr键对值;
    参数:
        optionName      指定的option节点(也可以是value name);
        isOption        是否为路径节点,True路径节点,False为value表的value name节点;
    返回:数组
    示例:
        [
            {'sibling option1': 'sibling option1 for ocr'}, 
            {'sibling option2': 'sibling option2 for ocr'}
        ]
    
    测试:。
    '''

    def getOptionAllSiblingItemMap(self, optionName, isOption=True):
        pass

    '''
    函数:获取指定option/value_name下的所有兄弟项(包括自己,相同parent)的 ocr:option 字典值;
    参数:
        optionName      指定的option节点(也可以是value name);
        isOption        是否为路径节点,True路径节点,False为value表的value name节点;
    注:value表中的option实际并没有兄弟项,取的是该option(value name)所有value项
    返回:字典
    示例:
        {
            'sibling option1_ocr': 'sibling option1', 
            'sibling option2_ocr': 'sibling option2',
            'sibling option3_ocr': 'sibling option3',
        }
    
    测试:通过。对应UIT_tree中的get_parent_ocr_dict
    '''

    def getOptionAllSiblingItemDict(self, optionName, isOption=True):
        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        found = False
        dict_ocr = {}
        list_ocr = []
        if isOption is True:
            # 首先,字典不排序,需要倒序;
            paths = reversed(self.__pathParams.paths)
            for level in paths:
                for parent in self.__pathParams.paths[level]:
                    for vals in self.__pathParams.paths[level][parent]["value"]:
                        if vals['option'].lower() == optionName.lower():
                            found = True
                            break
                    # endfor
                    # 找到退出;
                    if found is True:
                        break
                # endfor
                # 找到退出;
                if found is True:
                    break

            # 遍历value列表;
            if found is True:
                for val in self.__pathParams.paths[level][parent]["value"]:
                    list_ocr = val['option_for_ocr'].split(';')
                    for ocr in list_ocr:
                        dict_ocr[ocr.lower()] = val['option']
        else:
            if optionName in self.__valueParams.values:
                for val in self.__valueParams.values[optionName]["value"]:
                    list_ocr = val['value_for_ocr'].split(';')
                    for ocr in list_ocr:
                        dict_ocr[ocr.lower()] = val['value']

        print 'unsorted=', dict_ocr
        # 按长度排序;
        list_ocr = sorted(dict_ocr.keys(), key=lambda key: len(key), reverse=True)
        dict_reuslt = OrderedDict()
        for ocr in list_ocr:
            dict_reuslt[ocr] = dict_ocr[ocr]
        # 返回结果;
        return dict_reuslt

    '''
    函数:获取指定option所有兄弟项(相同parent)的ocr值, 1d表示One-dimensional(一维数组);
    参数:
            optionName      指定的option节点(也可以是value name);
            isOption        是否为路径节点,True路径节点,False为value表的value name节点;
    返回:数组
    示例:
        [
            ['option1 ocr', 'ocr2', 'ocr3'],
            ['option2 ocr'], 
            ['option3 orc']
        ]
        
    测试:通过。对应UIT_tree中的get_parent_ocr_list
    
    '''

    def getOptionAllSiblingItemTextList1d(self, optionName):
        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        found = False
        list_ocr = []
        # 首先,字典不排序,需要倒序;
        paths = reversed(self.__pathParams.paths)
        for level in paths:
            for parent in self.__pathParams.paths[level]:
                for vals in self.__pathParams.paths[level][parent]["value"]:
                    if vals['option'].lower() == optionName.lower():
                        found = True
                        break
                # endfor
                # 找到退出;
                if found is True:
                    break
            # endfor
            # 找到退出;
            if found is True:
                break
        # endfor

        # 遍历value列表;
        if found is True:
            for val in self.__pathParams.paths[level][parent]["value"]:
                list_ocr.extend(val['option_for_ocr'].split(';'))
        # 按长度排序;
        list_ocr.sort(key=lambda i: len(i), reverse=True)
        # 返回结果;
        return list_ocr

    def getOptionAllSiblingItemTextList2d(self, optionName):
        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        found = False
        list_ocr = []
        # 首先,字典不排序,需要倒序;
        paths = reversed(self.__pathParams.paths)
        for level in paths:
            for parent in self.__pathParams.paths[level]:
                for vals in self.__pathParams.paths[level][parent]["value"]:
                    if vals['option'].lower() == optionName.lower():
                        found = True
                        break
                # endfor
                # 找到退出;
                if found is True:
                    break
            # endfor
            # 找到退出;
            if found is True:
                break
        # endfor

        # 遍历value列表;
        if found is True:
            for val in self.__pathParams.paths[level][parent]["value"]:
                list_ocr.append(val['option_for_ocr'].split(';'))
        # 按长度排序;
        list_ocr.sort(key=lambda i: len(i), reverse=True)
        # 返回结果;
        return list_ocr

    '''
    函数:获取指定option的所有兄弟项名称;
    参数:
    返回:
    '''
    def getOptionAllSiblingItemName(self, optionName):
        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        found = False
        listName = []
        # 首先,字典不排序,需要倒序;
        paths = reversed(self.__pathParams.paths)
        for level in paths:
            for parent in self.__pathParams.paths[level]:
                for vals in self.__pathParams.paths[level][parent]["value"]:
                    if vals['option'].lower() == optionName.lower():
                        found = True
                        break
                # endfor
                # 找到退出;
                if found is True:
                    break
            # endfor
            # 找到退出;
            if found is True:
                break
        # endfor

        # 遍历value列表;
        if found is True:
            for val in self.__pathParams.paths[level][parent]["value"]:
                listName.append(val['option'])

        # 返回结果;
        return listName

    '''
    函数:获取指定option的ocr文本描述,以list返回
    参数:optionName   要返回文本描述的option节点
    返回:数据
    示例:optionName = 'picture_reset'时,返回['picture reset', 'plcture reset']
        
    测试:通过。对应UIT_tree.py中的getOptionTextList、get_option_ocr(这两个函数返回值一样,参数不一样而已)。
    '''

    def getOptionText(self, optionName):
        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        found = False
        list_ocr = []
        # 首先,字典不排序,需要倒序;
        paths = reversed(self.__pathParams.paths)
        for level in paths:
            for parent in self.__pathParams.paths[level]:
                for vals in self.__pathParams.paths[level][parent]["value"]:
                    if vals['option'].lower() == optionName.lower():
                        list_ocr = vals['option_for_ocr'].split(';')
                        found = True
                        break
                # endfor
                # 找到退出;
                if found is True:
                    break
            # endfor
            # 找到退出;
            if found is True:
                break
        # endfor
        # 返回结果;
        return list_ocr

    '''
        函数:获取指定option的value表详细数据,如果参数value未指定具体值则获取全部valueName的详细数据;
        参数:
            optionName      指定的value表中的option(即value name)名称
            value           要获取的值名称,如果空则获取全部值
        返回:自定义的字典
        示例:
        {
            "option":"option名称",
            "values":[option在value表中的所有value字段],
            "value_for_ocr":[option在value表中所有value_for_ocr字段],
            "enter_key":"",
            "move_key":"",
            "others":"",
        }
        
        测试:通过。对应UIT_tree中的get_value
    '''

    def getOptionValueInfo(self, optionName, value=""):
        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        # option/value name是否在value表中的;
        if optionName not in self.__valueParams.values:
            return []

        optValues = self.__valueParams.values[optionName]["value"]
        valueList = []
        valueOcrList = []
        for item in optValues:
            valueList.append(item["value"])
            valueOcrList.append(item["value_for_ocr"])

        vp = {
            "option": optionName,
            "value": valueList,
            "value_for_ocr": valueOcrList,
            "enter_key": self.__valueParams.values[optionName]["enter_key"],
            "move_key": self.__valueParams.values[optionName]["move_key"],
            "others": self.__valueParams.values[optionName]['others'],
            # toparent_key,有则读取,无则留空
            "toparent_key": self.__valueParams.values[optionName]['toparent_key'] \
                if 'toparent_key' in self.__valueParams.values[optionName]\
                else "",
            "layout": self.__valueParams.values[optionName]['layout'] \
                if 'layout' in self.__valueParams.values[optionName]\
                else ""
        }

        bFound = False
        # 找到value对应的ocr;
        if value is not None and value != "":
            vp["value"] = value
            for item in self.__valueParams.values[optionName]["value"]:
                if "range(" in item["value"]:
                    bFound = True
                    vp["value_for_ocr"] = item["value_for_ocr"].split(';')
                    break
                elif item["value"].lower() == value.lower():
                    bFound = True
                    vp["value_for_ocr"] = item["value_for_ocr"].split(';')
                    break
            # endfor
        else:
            bFound = True

        # 返回结果;
        return vp if bFound else []

    '''
    函数:获取value表中的指定option(value name)的value的文本内容;
    参数:
        optionName      指定value中的option(value name)
        value           指定option的value字段名称;
    返回:数组
    示例:
    
    测试:通过。对应UIT_tree中的getValueTextList。
    '''

    def getOptionValueText(self, optionName, value=""):
        if optionName is None or optionName.__len__() == 0:
            self.error(u"optionName空,退出执行")
            return []

        # 如果是整数或浮点数,退出;
        if type(value) == int or type(value) == float:
            self.info(u"value类型是整数或浮点数")

        valueTextList = []
        if optionName in self.__valueParams.values:
            valueDictList = self.valueParams.values[optionName]["value"]
            for valueDict in valueDictList:
                if value is None or value == "":
                    value_for_ocr = valueDict["value_for_ocr"]
                    valueTextList.extend(value_for_ocr.split(';'))
                else:
                    # 如果是字符串;
                    if type(value) == str:
                        if valueDict["value"].lower() == value.lower():
                            value_for_ocr = valueDict["value_for_ocr"]
                            valueTextList = value_for_ocr.split(';')
                            break
                    # 如果是整数或浮点数;
                    elif type(value) == int or type(value) == float:
                        value_for_ocr = valueDict["value_for_ocr"]
                        if "range" in value_for_ocr:
                            value_for_ocr = value_for_ocr.replace("range", "")
                            valueTextList = list(eval(value_for_ocr))
                            break
                # endif
            # endfor
        # endif
        # 返回结果;
        return valueTextList

    '''
        函数:获取指定option的详细信息;
        参数:
            optionName      指定的路径表中的option名称
        返回:字典
        示例:
        {
            "layers":"第几层",
            "level":"",
            "parent":"",  
            "first_parent": "",         
            "enter_key":"",
            "move_key":"",
            "others":"",
            "option_move_key":"",
            "option_enter_key":"",
            "option_others":"",
            "option_ocr":[],
        }

        测试:通过。对应UIT_tree中的get_option
    '''

    def getOptionInfo(self, optionName, paths=None):
        # 参数校验;
        if optionName is None or optionName.__len__() == 0:
            self.error(u"optionName空,退出执行")
            return False, {}

        # 编码转换;
        if type(optionName) == str:
            optionName = unicode(optionName)

        found = False
        dict_option = {}
        if paths is None:
            # 首先,字典不排序,需要倒序;
            paths = reversed(self.__pathParams.paths)
            for level in paths:
                for parent in self.__pathParams.paths[level]:
                    # 如果找到的是顶层信息(如source).
                    if level == "First" and parent.lower() == optionName.lower():
                        found = True
                        dict_option['level'] = level
                        dict_option['parent'] = parent
                        dict_option['others'] = self.__pathParams.paths[level][parent]['others']
                        dict_option['enter_key'] = self.__pathParams.paths[level][parent]['enter_key']
                        dict_option['move_key'] = self.__pathParams.paths[level][parent]['move_key']
                        # 根节点没有以下信息,置空。
                        # 读取toparent_key
                        if 'toparent_key' in self.__pathParams.paths[level][parent]:
                            dict_option['toparent_key'] = self.__pathParams.paths[level][parent]['toparent_key']
                        else:
                            dict_option['toparent_key'] = ''
                        # 读取layout
                        if 'layout' in self.__pathParams.paths[level][parent]:
                            dict_option['layout'] = self.__pathParams.paths[level][parent]['layout']
                        else:
                            dict_option['layout'] = ''
                        dict_option['option_ocr'] = []
                        dict_option['option_move_key'] = []
                        dict_option['option_enter_key'] = []
                        dict_option['option_others'] = []
                        dict_option['layers'] = g_level.index(level)
                        option = parent
                        break
                    else:
                        for vals in self.__pathParams.paths[level][parent]["value"]:
                            if vals['option'].lower() == optionName.lower():
                                if dict_option.__len__() == 0:
                                    found = True
                                    dict_option['level'] = level
                                    dict_option['parent'] = parent
                                    dict_option['others'] = self.__pathParams.paths[level][parent]['others']
                                    dict_option['enter_key'] = self.__pathParams.paths[level][parent]['enter_key']
                                    dict_option['move_key'] = self.__pathParams.paths[level][parent]['move_key']
                                    # 读取toparent_key
                                    if 'toparent_key' in self.__pathParams.paths[level][parent]:
                                        dict_option['toparent_key'] = self.__pathParams.paths[level][parent]['toparent_key']
                                    else:
                                        dict_option['toparent_key'] = ''
                                    # 读取layout
                                    if 'layout' in self.__pathParams.paths[level][parent]:
                                        dict_option['layout'] = self.__pathParams.paths[level][parent]['layout']
                                    else:
                                        dict_option['layout'] = ''
                                    dict_option['option_ocr'] = vals['option_for_ocr'].split(';')
                                    dict_option['option_move_key'] = vals['move_key']
                                    dict_option['option_enter_key'] = vals['enter_key']
                                    dict_option['option_others'] = vals['others']
                                    dict_option['layers'] = g_level.index(level)
                                option = parent
                                break
                        # endfor
                    # endif
                # endfor
            # endfor
            if found is True:
                # first层次的parent名称;
                dict_option['first_parent'] = option
        else:
            for level in paths:
                if paths[level]['option'].lower() == optionName.lower():
                    found = True
                    dict_option['layers'] = g_level.index(level)
                    dict_option['first_parent'] = paths['First']['parent']
                    dict_option['level'] = level
                    dict_option['parent'] = paths[level]['parent']
                    dict_option['others'] = paths[level]['others']
                    dict_option['enter_key'] = paths[level]['enter_key']
                    dict_option['move_key'] = paths[level]['move_key']
                    if 'toparent_key'in paths[level]:
                        dict_option['toparent_key'] = paths[level]['toparent_key']
                    else:
                        dict_option['toparent_key'] = ''
                    if 'layout'in paths[level]:
                        dict_option['layout'] = paths[level]['layout']
                    else:
                        dict_option['layout'] = ''
                    dict_option['option_ocr'] = paths[level]['option_for_ocr']  # 已经是list了。
                    dict_option['option_move_key'] = paths[level]['move_key']
                    dict_option['option_enter_key'] = paths[level]['enter_key']
                    dict_option['option_others'] = paths[level]['others']
                    break
                # endif
            # endfor
        # endif
        # 返回结果;
        return found, dict_option

    '''
        函数:获取指定parent的详细信息;
        参数:
            parentName      指定的路径表中的parent名称
        返回:字典
        示例:
        {
            "layers":"第几层",
            "level":"",
            "others":"",
            "toparent_key": "",
            "enter_key":"",
            "move_key":"",
			"layout":"",
            "option":[parent下的optionName列表],
        }

        测试:通过。对应UIT_tree中的get_option
    '''
    def getParentInfo(self, parentName):
        # 参数校验;
        if parentName is None or parentName.__len__() == 0:
            self.error(u"optionName空,退出执行")
            return False, {}
        # 编码转换;
        if type(parentName) == str:
            parentName = unicode(parentName)

        found = False
        dict_parent = {}
        # 先读取非value层的parent;
        paths = reversed(self.__pathParams.paths)
        for level in paths:
            for parent in self.__pathParams.paths[level]:
                if parent.lower() == parentName.lower():
                    found = True
                    dict_parent['level'] = level
                    dict_parent['others'] = self.__pathParams.paths[level][parent]['others']
                    dict_parent['enter_key'] = self.__pathParams.paths[level][parent]['enter_key']
                    dict_parent['move_key'] = self.__pathParams.paths[level][parent]['move_key']
                    # 读取toparent_key
                    if 'toparent_key' in self.__pathParams.paths[level][parent]:
                        dict_parent['toparent_key'] = self.__pathParams.paths[level][parent]['toparent_key']
                    else:
                        dict_parent['toparent_key'] = ''
                    # 读取layout
                    if 'layout' in self.__pathParams.paths[level][parent]:
                        dict_parent['layout'] = self.__pathParams.paths[level][parent]['layout']
                    else:
                        dict_parent['layout'] = ''
                    dict_parent['layers'] = g_level.index(level)
                    optionList = []
                    for val in self.__pathParams.paths[level][parent]['value']:
                        if 'option' in val:
                            optionList.append(val['option'])
                    dict_parent['option'] = optionList
                    return found, dict_parent

        return found, dict_parent


    '''
    函数:获取指定的option在value表中的所有value字段;
    参数:
        optionName  指定value表中的option(value name)名称。
    返回:数组
    示例:
    
    测试:通过。对应UIT_tree中的getSubValueList
    '''

    def getOptionAllValueName(self, optionName):
        valueList = []
        if optionName in self.valueParams.values:
            valueDictList = self.valueParams.values[optionName]["value"]
            for valueDict in valueDictList:
                valueList.append(valueDict["value"])
        # print "valueList:", valueList, type(valueList)
        if valueList.__len__() == 1 and "range(" in valueList[0]:
            value_for_ocr_low = str(valueList[0]).lower()
            str_num = value_for_ocr_low.replace("range", "")
            list_num = eval(str_num)
            min_num = list_num[0]
            max_num = list_num[1]
            return [min_num, max_num]

        return valueList

    '''
    函数:获取指定option的路径。
    参数:
    返回:
    示例:
    
    测试:。
    '''

    def getOptionPaths(self, optionName):
        # 对参数进行校验;
        if optionName is None or optionName.__len__() == 0:
            self.error('optionName空,执行退出')
            return None
        # pp必须不排序;
        pp = OrderedDict()
        # 首先,字典不排序,需要倒序;
        paths = reversed(self.__pathParams.paths)
        for level in paths:
            found = False
            for parent in self.__pathParams.paths[level]:
                for item in self.__pathParams.paths[level][parent]["value"]:
                    if item["option"].lower() == optionName.lower():
                        pp[level] = {
                            "parent": parent,
                            "move_key": self.__pathParams.paths[level][parent][xlsc.move_key],
                            "enter_key": self.__pathParams.paths[level][parent][xlsc.enter_key],
                            "others": self.__pathParams.paths[level][parent][xlsc.others],
                            "toparent_key": self.__pathParams.paths[level][parent][xlsc.toparent_key]\
                                if xlsc.toparent_key in self.__pathParams.paths[level][parent]\
                                else "",
                            "layout": self.__pathParams.paths[level][parent][xlsc.layout]\
                                if xlsc.layout in self.__pathParams.paths[level][parent]\
                                else "",
                            "option": item[xlsc.option],
                            "option_for_ocr": item[xlsc.option_for_ocr].split(';'),
                            "option_move_key": item[xlsc.move_key],
                            "option_enter_key": item[xlsc.enter_key],
                            "option_others": item[xlsc.others]
                        }
                        optionName = parent
                        found = True
                        break
                if found:
                    break
                else:
                    if level == "First" and parent == optionName:
                        pp[level] = {
                                    "parent": parent,
                                    "move_key": self.__pathParams.paths[level][parent][xlsc.move_key],
                                    "enter_key": self.__pathParams.paths[level][parent][xlsc.enter_key],
                                    "others": self.__pathParams.paths[level][parent][xlsc.others],
                                    "toparent_key": self.__pathParams.paths[level][parent][xlsc.toparent_key]\
                                        if xlsc.toparent_key in self.__pathParams.paths[level][parent]\
                                        else "",
                                    "layout": self.__pathParams.paths[level][parent][xlsc.layout]\
                                        if xlsc.layout in self.__pathParams.paths[level][parent]\
                                        else "",
                                    # 根结点没有以下信息,置空;
                                    "option": parent,
                                    "option_for_ocr": [],
                                    "option_move_key": [],
                                    "option_enter_key": [],
                                    "option_others": []
                                }    
                        found = True
                        break
                    # endif
            # endfor
        # endfor
        # 需要对path倒序使用;
        # dict_pp = OrderedDict()
        # # 逆序路径key;
        # revpp = reversed(pp)
        # for path in revpp:
        #     dict_pp[path] = {"parent": pp[path]['parent'],"move_key": pp[path]['move_key'],"enter_key": pp[path]['enter_key'],"others":pp[path]['others'],"option": pp[path]['option'],"option_for_ocr": pp[path]['option_for_ocr']}
        # # 返回逆序后的结果;
        # return dict_pp
        return pp

    '''
    函数:获取指定option和value的路径及value信息。
    参数:
    返回:
    示例:
    
    测试:通过。
    '''

    def getOptionPathsAndValue(self, optionName, value):
        # 对参数进行校验;
        if optionName is None or optionName.__len__() == 0:
            self.error('optionName空,执行退出')
            return None, None
        if value.__len__() == 0:
            self.error('value空,执行退出')
            return {}, OrderedDict()

        vp = self.getOptionValueInfo(optionName, value)
        pp = self.getOptionPaths(optionName)

        return vp, pp

    '''
    函数:检验路径是否有效。
    参数:
    返回:
    示例:
 
    测试:通过。
    '''

    def checkOptionPaths(self, optionNameOrPaths):
        optionPathResult = "Fail"
        # 进行参数校验;
        if optionNameOrPaths is None or optionNameOrPaths.__len__() == 0:
            self.error('optionNameOrPaths空,执行退出')
            return None, optionPathResult
        path_params = optionNameOrPaths
        if type(optionNameOrPaths) == str:
            path_params = self.getOptionPaths(optionNameOrPaths)
        # 如果传入的option不存在则直接返回
        if path_params.__len__() <= 0:
            optionPathResult = "NoExit"
            optionPath = u"表格中不存在到达Option:   %s   的路径" % str(optionNameOrPaths)
            return optionPath, optionPathResult
        else:
            optionPath = str(path_params)
            # 逆序路径key;
            revpp = reversed(path_params)
            level_count = 0
            for level in revpp:
                if str(level) == str(g_level[level_count]):
                    level_count = level_count + 1
                else:
                    # 如果执行路径不是按照First、Second......执行则返回执行出错
                    return optionPath, optionPathResult
            optionPathResult = "Pass"
            return optionPath, optionPathResult


if __name__ == "__main__":
    exData = CExtraData()
    opxls = COptionExcel(exData)
    # print json.dumps(opxls.pathParams.paths)
    # print "getOptionAllChildItemName", opxls.getOptionAllChildItemName('source')
    # print "getOptionAllChildItemTextList1d", opxls.getOptionAllChildItemTextList1d('picture')
    # print "getOptionAllChildItemTextList2d", opxls.getOptionAllChildItemTextList2d('picture')
    # print "getOptionAllChildItemMap", opxls.getOptionAllChildItemMap('picture')
    # print "getOptionAllSiblingItemMap", opxls.getOptionAllSiblingItemMap('picture')
    # print u"getOptionAllSiblingItemDict", opxls.getOptionAllSiblingItemDict('picture')
    # print u"getOptionAllSiblingItemTextList1d", opxls.getOptionAllSiblingItemTextList1d('picture')
    # print u"getOptionText", opxls.getOptionText('picture')
    # print "getOptionValueInfo", opxls.getOptionValueInfo('source')
    # print "getOptionValueText", opxls.getOptionValueText('source', 'atv')
    # print "getOptionValueText", opxls.getOptionValueText('source', 'dtv')
    print "getParentInfo", opxls.getParentInfo('picture_preset')
    # print "getOptionInfo", opxls.getOptionInfo('picture_preset')
    # print "getOptionInfo", opxls.getOptionInfo('picture')
    # print "getOptionAllValueName", opxls.getOptionAllValueName('source')
    # ##########################################
    # paths = opxls.getOptionPaths('source')
    # print "getOptionPaths", paths
    # print "checkOptionPaths", opxls.checkOptionPaths('sharpness')
    # print "checkOptionPaths", opxls.checkOptionPaths(opxls.getOptionPaths('sharpness'))
    # print "getOptionPathsAndValue", opxls.getOptionPathsAndValue('picture', 'sharpness')