# Path: robot_designer_plugin/core/gui.py
# class InfoBox(object):
#     """
#     This class collects messages (e.g., from :meth:`.operators.operators.RDOperator.poll`) and displays them
#     with an info, either in a separated box or the current layout.
# 
#     See :ref:`gui_development` for an example.
#     """
# 
#     global_messages = []
# 
#     def __init__(self, layout):
#         """
#         Constructor.
# 
#         :param layout: Blender gui element as passed to the
#             :meth:`robot_designer_plugin.interface.main.UserInterface.draw` method.
#         """
#         self.messages = []
#         self.layout = layout
# 
#     def add_message(self, message):
#         """
#         Adds a string message to the info box.
# 
#         :param message: message
#         :type message: str
#         """
#         self.messages.append(message)
# 
#     def draw_info(self, additional_messages=[], icon=StringConstants.info):
#         """
#         Draws the info box onto the layout.
# 
#         :param additional_messages: Additional messages can be appended.
#         """
#         messages = self.messages + additional_messages
#         if messages:
# 
#             column = self.layout.column(align=True)
#             for text in set(messages):
#                 column.label(text=text, icon=icon)
# 
#     @classmethod
#     def draw_global_info(cls, layout):
# 
#         if cls.global_messages:
#             ib = InfoBox(layout)
#             ib.draw_info(additional_messages=cls.global_messages, icon=StringConstants.error)
# 
# Path: robot_designer_plugin/core/config.py
# PLUGIN_PREFIX = "robotdesigner"
# OPERATOR_PREFIX = PLUGIN_PREFIX + '.'
# MENU_PREFIX = "ROBOTDESIGNER_MT_"
# BACKTRACE_FILTER_FUNC = ('func_wrapper', 'op_logger', '__call__')
# BACKTRACE_FILTER_HIDE_CODE = ('run', 'runNestedOperator')
# BACKTRACE_MESSAGE_STACK_CODE = "\t\t{0:25}\t\t({1}:{2})\n\t\t\t{3}\n"
# BACKTRACE_MESSAGE_STACK = "\t\t{0:25}\t\t({1}:{2})\n"
# BACKTRACE_MESSAGE_CALLSTACK = "\n\tNesting Level %d:\n\n\tCallstack:\n"
# BACKTRACE_MESSAGE = "\n\tBacktrace:\n"
# EXCEPTION_MESSAGE = "\tException:\t%s\n\tMessages:\n\t\t%s\n%s\n%s"


import logging
import sys
import traceback
import os
from .gui import InfoBox
from ..core.config import BACKTRACE_MESSAGE_CALLSTACK, BACKTRACE_MESSAGE, BACKTRACE_FILTER_FUNC, \
    BACKTRACE_FILTER_HIDE_CODE, BACKTRACE_MESSAGE_STACK, BACKTRACE_MESSAGE_STACK_CODE, EXCEPTION_MESSAGE, script_path
from importlib import reload

    return func_logger


def log_callstack(back_trace=False):
    """
    Helper function that formats either a (filtered) backtrace or call stack in a string. Blender internals
    are filtered such that errors in the own code can be detected more easily.

    :param back_trace: If true, the backtrace is returned. Otherwise, the call stack is returned.
    :return: the formatted call stack/backtrace in a string.
    """

    if not back_trace:
        message = BACKTRACE_MESSAGE_CALLSTACK % len([i for i in traceback.extract_stack() if i[2] == 'run'])
        stack = traceback.extract_stack()[:-1]
    else:
        message = BACKTRACE_MESSAGE
        stack = traceback.extract_tb(sys.exc_info()[2])

    last_call = ""
    for path, line, func, code in stack:
        if 'addons' in path:
            file = '...' + path[path.find('addons') + 6:]
        elif 'scripts' in path:
            file = '...' + path[path.find('scripts') + 7:]
        else:
            file = path
        if func not in BACKTRACE_FILTER_FUNC:
            if func in BACKTRACE_FILTER_HIDE_CODE:

# Path: robot_designer_plugin/core/gui.py
# class InfoBox(object):
#     """
#     This class collects messages (e.g., from :meth:`.operators.operators.RDOperator.poll`) and displays them
#     with an info, either in a separated box or the current layout.
# 
#     See :ref:`gui_development` for an example.
#     """
# 
#     global_messages = []
# 
#     def __init__(self, layout):
#         """
#         Constructor.
# 
#         :param layout: Blender gui element as passed to the
#             :meth:`robot_designer_plugin.interface.main.UserInterface.draw` method.
#         """
#         self.messages = []
#         self.layout = layout
# 
#     def add_message(self, message):
#         """
#         Adds a string message to the info box.
# 
#         :param message: message
#         :type message: str
#         """
#         self.messages.append(message)
# 
#     def draw_info(self, additional_messages=[], icon=StringConstants.info):
#         """
#         Draws the info box onto the layout.
# 
#         :param additional_messages: Additional messages can be appended.
#         """
#         messages = self.messages + additional_messages
#         if messages:
# 
#             column = self.layout.column(align=True)
#             for text in set(messages):
#                 column.label(text=text, icon=icon)
# 
#     @classmethod
#     def draw_global_info(cls, layout):
# 
#         if cls.global_messages:
#             ib = InfoBox(layout)
#             ib.draw_info(additional_messages=cls.global_messages, icon=StringConstants.error)
# 
# Path: robot_designer_plugin/core/config.py
# PLUGIN_PREFIX = "robotdesigner"
# OPERATOR_PREFIX = PLUGIN_PREFIX + '.'
# MENU_PREFIX = "ROBOTDESIGNER_MT_"
# BACKTRACE_FILTER_FUNC = ('func_wrapper', 'op_logger', '__call__')
# BACKTRACE_FILTER_HIDE_CODE = ('run', 'runNestedOperator')
# BACKTRACE_MESSAGE_STACK_CODE = "\t\t{0:25}\t\t({1}:{2})\n\t\t\t{3}\n"
# BACKTRACE_MESSAGE_STACK = "\t\t{0:25}\t\t({1}:{2})\n"
# BACKTRACE_MESSAGE_CALLSTACK = "\n\tNesting Level %d:\n\n\tCallstack:\n"
# BACKTRACE_MESSAGE = "\n\tBacktrace:\n"
# EXCEPTION_MESSAGE = "\tException:\t%s\n\tMessages:\n\t\t%s\n%s\n%s"


# Path: robot_designer_plugin/core/logfile.py
import logging
import sys
import traceback
import os
from .gui import InfoBox
from ..core.config import BACKTRACE_MESSAGE_CALLSTACK, BACKTRACE_MESSAGE, BACKTRACE_FILTER_FUNC, \
    BACKTRACE_FILTER_HIDE_CODE, BACKTRACE_MESSAGE_STACK, BACKTRACE_MESSAGE_STACK_CODE, EXCEPTION_MESSAGE, script_path
from importlib import reload


    return func_logger


def log_callstack(back_trace=False):
    """
    Helper function that formats either a (filtered) backtrace or call stack in a string. Blender internals
    are filtered such that errors in the own code can be detected more easily.

    :param back_trace: If true, the backtrace is returned. Otherwise, the call stack is returned.
    :return: the formatted call stack/backtrace in a string.
    """

    if not back_trace:
        message = BACKTRACE_MESSAGE_CALLSTACK % len([i for i in traceback.extract_stack() if i[2] == 'run'])
        stack = traceback.extract_stack()[:-1]
    else:
        message = BACKTRACE_MESSAGE
        stack = traceback.extract_tb(sys.exc_info()[2])

    last_call = ""
    for path, line, func, code in stack:
        if 'addons' in path:
            file = '...' + path[path.find('addons') + 6:]
        elif 'scripts' in path:
            file = '...' + path[path.find('scripts') + 7:]
        else:
            file = path
        if func not in BACKTRACE_FILTER_FUNC:
            if func in BACKTRACE_FILTER_HIDE_CODE:

                message += BACKTRACE_MESSAGE_STACK.format(func, file, line)