# -*- coding:utf-8 -*-
import os
from BaseLog import CBaseLog
from TConfig import TConfig
from ExtraData import CExtraData
from OptionExcel import COptionExcel


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


# 注意:所有不对外暴露的变量和函数需要私有化,以明确哪些接口和参数是对外的。
# 这样便于后期维护时,根据对外的变量和函数来做处理。
class COptionConfig(TConfig, CBaseLog):
    def __init__(self, exData, optionExcel):
        CBaseLog.__init__(self)
        self.__exData = exData
        self.__optionExcel = optionExcel
        if self.__optionExcel is None:
            self.error(u"路径参数错误:None")
        # 状态:False表示路径值失败;
        self.status = False
        # menuTree目录;
        self.__uiTreeDir = self.__exData.menuTreeDir
        # 判断是否为目录;
        if not os.path.isdir(self.__uiTreeDir):
            self.error(u"%s 不是menuTree目录" % self.__uiTreeDir)
        # 判断目录是否存在;
        if not os.path.exists(self.__uiTreeDir):
            self.error(u"menuTree(%s)目录不存在" % self.__uiTreeDir)
        # 判断配置文件是否存在;
        self.__configPath = os.path.join(self.__uiTreeDir, "menutree.ini")
        if os.path.exists(self.__configPath):
            self.status = True
        else:
            self.error(u"menutree配置文件不存在:%s" % self.__configPath)
        # 初始化父类;
        TConfig.__init__(self, self.__configPath)

    # 获取超级密码;
    def getSuperPassword(self):
        return self.get_value("Password", "super")

    # 获取普通密码;
    def getOrdinaryPassword(self):
        return self.get_value("Password", "ordinary")

    # 获取父节点等待进入子节点时间;
    def getParentWaitTime(self, parent):
        optionName = parent + "WaitTime"
        try:
            waitTime = float(self.get_value("waitTime", optionName))
        except Exception:
            waitTime = 1.0
            self.error(u"获取%s界面的等待界面时间失败,使用默认值1.0s" % str(parent))
        return waitTime

    # 获取阀值字典;
    '''
    函数:获取指定option的阀值字典
    参数:
        optionName      节点名称;
    返回:字典。
    '''
    def getThresholdDict(self, optionName):
        section = "Threshold"
        thresholdDict = {}
        value = self.get_value(section, optionName)
        self.info("value:%s,%s" % (value, type(value)))
        if not value:
            return thresholdDict
        value_str = str(value)
        self.info("value_str:%s,%s" % (value_str, type(value_str)))
        value_dict = eval(value_str)
        self.info("value_dict:%s,%s" % (value_dict, type(value_dict)))
        return value_dict

    '''
    函数:获取Option的图片配置,方式1
    参数:
    返回:Boolean, 字典
    示例:True, {"icon_path": "", "dcfg": {}, "dir_path": ""}
    
    说明:
        查找顺序:
            [当前父节点][当前层级][当前节点] ->[当前父节点][当前层级] ->[根节点][当前层级][当前节点]
            [curParent][curLevel][curOption] ->[curParent][curLevel] ->[firstParent][curLevel][curOption]
    '''
    def __getICONConfig1(self, optionName, is_value_sheet=False):
        # 默认值;
        def_cfg = {"icon_path": "", "dcfg": {}, "dir_path": ""}
        paths = self.__optionExcel.getOptionPaths(optionName)
        # 判断路径节点是否空;
        if paths.__len__() == 0:
            self.error(u"当前【%s】的路径节点空,使用默认的配置值%s" % (optionName, def_cfg))
            return False, def_cfg

        # 获取first parent;
        first_parent = paths[g_level[0]]['parent']
        # 获取当前option的level;
        cur_level = g_level[paths.__len__() - 1]
        # 当前option的父节点名称;
        cur_parent = paths[cur_level]['parent']
        if is_value_sheet is True:
            cur_level = "value"

        # option聚焦的首配图片路径;
        icon_path = os.path.join(self.__uiTreeDir, "icon\\", cur_parent + "." + cur_level + "_" + optionName + ".png")
        # option聚焦的dir首配图片路径;
        icon_dir_path = os.path.join(self.__uiTreeDir, "icon\\" + cur_parent + "." + cur_level + "_" + optionName + ".dir.png")
        # 图片聚焦时的定位参数;
        opc_cfg = self.get_value_dict(cur_level, cur_parent + '.' + optionName)

        # 首配图片判断是否存在,不存在取用次配图片路径;
        if not os.path.exists(icon_path):
            # 使用次配图片,父级配图;
            self.warn(u"Option(%s)首配图片不存在:%s" % (optionName, icon_path))
            icon_path = os.path.join(self.__uiTreeDir, "icon\\" + cur_parent + "." + cur_level + ".png")
            icon_dir_path = os.path.join(self.__uiTreeDir, "icon\\" + cur_parent + "." + cur_level + ".dir.png")

            if opc_cfg.__len__() == 0:
                opc_cfg = self.get_value_dict(cur_level, cur_parent)
            self.warn(u"Option(%s)首配图片不存在,尝试使用次配图(%s):%s,配置%s" % (optionName, cur_parent, icon_path, opc_cfg))
            # 如果次配都不存在,使用顶层配图;
            if not os.path.exists(icon_path):
                self.warn(u"Option(%s)次配图片不存在:%s" % (optionName, icon_path))
                # 使用顶层配图(first parent)
                icon_path = os.path.join(self.__uiTreeDir, "icon\\" + first_parent + "." + cur_level + "_" + optionName + ".png")
                icon_dir_path = os.path.join(self.__uiTreeDir, "icon\\" + first_parent + "." + cur_level + "_" + optionName + ".dir.png")
                if opc_cfg.__len__() == 0:
                    opc_cfg = self.get_value_dict(cur_level, first_parent)
                self.warn(u"Option(%s)次配图片不存在,尝试使用顶层配图(%s):%s,配置%s" % (optionName, first_parent, icon_path, opc_cfg))
                # 如果顶层配图不存在,退出;
                if not os.path.exists(icon_path):
                    self.error(u"%s对应的顶层菜单配图不存在%s,使用默认配置%s" % (optionName, icon_path, def_cfg))
                    return False, def_cfg
                # endif
            # endif
        # endif

        if opc_cfg.__len__() == 0:
            opc_cfg = {"offset": 20, "minPeri": 0, "maxPeri": 0, "minArea": 0, "maxArea": 0, "morphology": []}

        return True, {"icon_path": icon_path, "dcfg": opc_cfg, "dir_path": icon_dir_path}

    '''
    函数:获取Option的图片配置,方式2
    参数:
    返回:Boolean, 字典
    示例:True, {"icon_path": "", "dcfg": {}, "dir_path": ""}

    说明:
        查找顺序:
            [根节点][当前层级][当前节点] ->[根节点][当前层级] ->[根节点][根层级]
            [firstParent][curLevel][curOption] ->[firstParent][curLevel] ->[firstParent][firstLevel]
    '''
    def __getICONConfig2(self, optionName, is_value_sheet=False):
        # 默认值;
        def_cfg = {"icon_path": "", "dcfg": {}, "dir_path": ""}
        paths = self.__optionExcel.getOptionPaths(optionName)
        # 判断路径节点是否空;
        if paths.__len__() == 0:
            self.error(u"当前【%s】的路径节点空,使用默认的配置值%s" % (optionName, def_cfg))
            return False, def_cfg

        # 获取first parent;
        first_parent = paths[g_level[0]]['parent']
        # 获取当前option的level;
        cur_level = g_level[paths.__len__() - 1]
        # 当前option的父节点名称;
        cur_parent = paths[cur_level]['parent']
        if is_value_sheet is True:
            cur_level = "value"

        # option聚焦的首配图片路径;
        icon_path = os.path.join(self.__uiTreeDir, "icon\\",
                                 first_parent + "." + cur_level + "_" + optionName + ".png")
        # option聚焦的dir首配图片路径;
        icon_dir_path = os.path.join(self.__uiTreeDir,
                                     "icon\\" + first_parent + "." + cur_level + "_" + optionName + ".dir.png")
        # 图片聚焦时的定位参数;
        opc_cfg = self.get_value_dict(cur_level, first_parent)

        # 首配图片判断是否存在,不存在取用次配图片路径;
        if not os.path.exists(icon_path):
            # 使用次配图片,父级配图;
            self.warn(u"Option(%s)首配图片不存在:%s" % (optionName, icon_path))
            icon_path = os.path.join(self.__uiTreeDir, "icon\\" + first_parent + "." + cur_level + ".png")
            icon_dir_path = os.path.join(self.__uiTreeDir, "icon\\" + first_parent + "." + cur_level + ".dir.png")
            self.warn(u"Option(%s)首配图片不存在,尝试使用次配图(%s):%s,配置%s" % (optionName, cur_parent, icon_path, opc_cfg))
            # 如果次配都不存在,使用顶层配图;
            if not os.path.exists(icon_path):
                self.warn(u"Option(%s)次配图片不存在:%s" % (optionName, icon_path))
                # 使用顶层配图(first parent)
                icon_path = os.path.join(self.__uiTreeDir, "icon\\" + first_parent + "." + "First.png")
                icon_dir_path = os.path.join(self.__uiTreeDir, "icon\\" + first_parent + "." + "First.dir.png")
                self.warn(
                    u"Option(%s)次配图片不存在,尝试使用顶层配图(%s):%s,配置%s" % (optionName, first_parent, icon_path, opc_cfg))
                # 如果顶层配图不存在,退出;
                if not os.path.exists(icon_path):
                    self.error(u"%s对应的顶层菜单配图不存在%s,使用默认配置%s" % (optionName, icon_path, def_cfg))
                    return False, def_cfg
                # endif
            # endif
        # endif

        if opc_cfg.__len__() == 0:
            opc_cfg = {"offset": 20, "minPeri": 0, "maxPeri": 0, "minArea": 0, "maxArea": 0, "morphology": []}

        return True, {"icon_path": icon_path, "dcfg": opc_cfg, "dir_path": icon_dir_path}

    '''
    函数:获取Option的图片配置
    参数:
        optionName      要获取的option。
    返回:Boolean, {}
    '''
    def getOptionICONConfig(self, optionName):
        outResutl, outData = self.__getICONConfig1(optionName, False)
        if outResutl is False:
            return self.__getICONConfig2(optionName, False)

        return outResutl, outData

    '''
    函数:获取Value的图片配置
    参数:
        valueName      要获取的value名称。
    返回:Boolean, {}
    '''
    def getValueICONConfig(self, valueName):
        outResutl, outData = self.__getICONConfig1(valueName, True)
        if outResutl is False:
            return self.__getICONConfig2(valueName, True)

        return outResutl, outData

    '''
    函数:获取Option的OCR配置
    参数:
        optionName      要获取的option名称
    返回:字典
    '''
    def getOptionOCRConfig(self, optionName):
        ocr_dict = []
        # 默认的ocr配置;
        def_orc = [{"lan": "ChinesePRC+English", "type": 10000},{"lan": "ChinesePRC+English", "type": 10001}]
        paths = self.__optionExcel.getOptionPaths(optionName)
        # 判断路径节点是否空;
        if paths.__len__() == 0:
            self.error(u"当前【%s】的路径节点空,将使用默认的ocr配置%s" % (optionName, def_orc))
        else:
            # 如果状态False,退出;
            if self.status is False:
                self.warn(u"配置文件(%s)不存在,%s使用默认的ocr配置%s" % (self.__configPath, optionName, def_orc))
            else:
                # 获取当前option的level;
                cur_level = g_level[paths.__len__() - 1]
                # 获取first parent;
                first_parent = paths[g_level[0]]['parent']
                # 当前option的父节点名称;
                cur_parent = paths[cur_level]['parent']

                # 优先级逻辑解释:

                # 是否有当前option的ocr配置;
                if self.has_option(cur_level, optionName + '.ocr'):
                    ocr_dict = self.get_dict(self.get_value(cur_level, optionName + '.ocr'))
                    self.warn(u"%s使用自身的ocr配置%s" % (optionName, ocr_dict))
                else:
                    # 如果option本身没有配置,获取其父节点的配置;
                    if self.has_option(cur_level, cur_parent + '.ocr'):
                        ocr_dict = self.get_dict(self.get_value(cur_level, cur_parent + '.ocr'))
                        self.warn(u"%s使用父节点%s的ocr配置%s" % (optionName, cur_parent, ocr_dict))
                    else:
                        # 如果option父级没有配置,则获取顶层配置(first parent);
                        if self.has_option("First", first_parent + '.ocr'):
                            ocr_dict = self.get_dict(self.get_value("First", first_parent + '.ocr'))
                            self.warn(u"%s使用顶层节点%s的ocr配置%s" % (optionName, first_parent, ocr_dict))
                    #endif
                #endif
            # end-if
        # end-if

        if ocr_dict.__len__() == 0:
            ocr_dict = def_orc
            self.warn(u"无有效的ocr配置,将使用默认的ocr配置%s" % def_orc)

        self.info(u"%s使用的ocr配置=%s" % (optionName, ocr_dict))

        return ocr_dict

    '''
    函数:获取ICON源屏幕的分辨率配置值
    参数:
    返回:
    
    说明:
    该值用途:由于有些icon是在某些分辨率下截图的,但是同机芯项目可能使用同一套UI,只是分辨率不一样而已。
    所以,根据当初的icon分辨率,可以计算出在别的分辨率下的icon区域大小;
    '''
    def getICONResolutionConfig(self):
        return self.get_value_dict('Screen', 'shape') if self.has_option('Screen', 'shape') else [1920, 1080]


if __name__ == "__main__":
    exData = CExtraData()
    optionExcel = COptionExcel(exData)
    optionConfig = COptionConfig(exData, optionExcel)
    # print "getSuperPassword", optionConfig.getSuperPassword()
    # print "getOrdinaryPassword", optionConfig.getOrdinaryPassword()
    # print "getParentWaitTime", optionConfig.getParentWaitTime('setting')
    # print "getThresholdDict", optionConfig.getThresholdDict('setting')
    # print "getOptionICONConfig", optionConfig.getOptionICONConfig('picture')
    print "getOptionICONConfig", optionConfig.getOptionICONConfig('picture_preset')
    # print "getValueICONConfig", optionConfig.getValueICONConfig('picture')
    # print "getOptionOCRConfig", optionConfig.getOptionOCRConfig('picture')
    # print "getICONResolutionConfig", optionConfig.getICONResolutionConfig()