

import os

from wizart import maya_qtutils

from wizart import cef
from Qt import QtWidgets, QtCore, QtGui
import pymel.core as pm
from functools import partial
from . import assets_utils
import wizart.anim_utils.menu

class BrowserTab(QtWidgets.QWidget):
    def __init__(self, parent=None, asset_info=None):
        super(BrowserTab, self).__init__(parent)
        self.parent = parent
        self.setLayout(QtWidgets.QVBoxLayout())
        self.frame = MainFrame(self)
        self.asset_info = asset_info
        self.toolbar = QtWidgets.QToolBar()
        self.toolbar.setStyleSheet("padding-left:5px;spacing:0px;margin:0px");
        self.layout().addWidget(self.toolbar)
        self.layout().addWidget(self.frame)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.rename_namespace_callback = None

        def _reload_browser():
            if self.frame.browser:
                self.frame.reload()

        reload_action = QtWidgets.QAction("Reload", self)
        reload_action.triggered.connect(_reload_browser)
        reload_action.setIcon(QtGui.QIcon(":refresh.png"))
        # reload_action.setIcon(QtGui.QIcon.fromTheme("view-refresh") )
        self.toolbar.addAction(reload_action)

        def _show_dev_tools():
            if self.frame.browser:
                self.frame.browser.ShowDevTools(int(self.frame.winId()))

        show_dev_tools_action = QtWidgets.QAction("Show Dev Tools", self)
        show_dev_tools_action.triggered.connect(_show_dev_tools)
        self.toolbar.addAction(show_dev_tools_action)
        if self.parent.dev_show_toolbar_act.isChecked() == False:
            self.toolbar.hide()

    def embed_browser(self, url=None):
        self.frame.embed_browser(url)

    def destroy_browser(self):
        self.frame.destroy_browser()


class MainFrame(QtWidgets.QWidget):
    key_event_signal = QtCore.Signal(int, bool, bool, bool)
    open_face_cam_signal = QtCore.Signal(tuple)
    time_changed_signal = QtCore.Signal()

    def __init__(self, parent=None):
        super(MainFrame, self).__init__(parent)
        self.parent = parent
        self.browser = None
        self._selection_callback = None
        self._attribute_change_cids = []
        self._attribute_change_attrs = []
        self.cef_attribute_change_cid = None
        self.cef_popup_menu_cid = None
        self.off_select = self.parent.parent.page_connect_to_maya[0]
        self.visibility = self.parent.parent.page_connect_to_maya[1]

        options_focus_on_resize = pm.optionVar.get("wizart_picker_options_focus_on_resize", 0)
        options_focus_on_resize = True if options_focus_on_resize == 1 else False
        self._option_focus_on_resize = options_focus_on_resize

        options_hide_avatar = pm.optionVar.get("wizart_picker_options_hide_avatar", 0)
        options_hide_avatar = True if options_hide_avatar == 1 else False
        self._option_hide_avatar = options_hide_avatar

        self._option_start_focus = pm.optionVar.get("wizart_picker_options_start_focus", "all")

        self.key_event_signal.connect(self.key_event_slot)
        self.open_face_cam_signal.connect(self.open_face_cam_slot)
        self.time_changed_signal.connect(self.time_update_attr_callbacks)
        
    def embed_browser(self, url=None):
        self._time_callback_cid = pm.api.MDGMessage.addDelayedTimeChangeCallback(lambda *args: self.time_changed_signal.emit())
        self._playback_change_cid = pm.api.MConditionMessage.addConditionCallback('playingBack', self.playback_change_attr_callbacks)
        self._selection_callback = pm.api.MEventMessage.addEventCallback("SelectionChanged", lambda *args: self._update_selection())
        self._attribute_change_cids = []
        self._attribute_change_attrs = []
        self.cef_attribute_change_cid = cef.RegisterPyCallback(self.install_attribute_change_callbacks)
        self.cef_mel_eval_cid = cef.RegisterPyCallback(self.mel_eval_callback)
        self.cef_python_eval_cid = cef.RegisterPyCallback(self.python_eval_callback)
        self.cef_popup_menu_cid = cef.RegisterPyCallback(self.popup_menu_callback)
        self.cef_popup_rig_menu_cid = cef.RegisterPyCallback(self.popup_rig_menu_callback)
        self.cef_key_event_cid = cef.RegisterPyCallback(self.key_event_callback)
        self.cef_sync_selection_cid = cef.RegisterPyCallback(self._update_selection)
        self.cef_open_face_cam_cid = cef.RegisterPyCallback(self.open_face_cam_callback)
        if self.parent.asset_info.get("picker_path") and url is None:
            asset_url = 'client://picker/%s/index.html' % (self.parent.asset_info["picker_path"])
            self.parent.asset_info["url"] = asset_url
            if os.path.exists(self.parent.asset_info.get("picker_path")):
                url = asset_url
            else:
                url = 'client://internal/404_picker.html'
        self.browser = cef.CreateBrowserSync(int(self.winId()), url)
        self.javascript_startup()

    def mel_eval_callback(self, code):
        pm.api.MGlobal.executeCommand(code, True)
    def python_eval_callback(self, code):
        exec(code, globals())
    def javascript_startup(self):
        import json
        # print 'browser_init_data'
        cmd = "window.mel_eval_cid = %d;\n" % self.cef_mel_eval_cid
        cmd += "window.python_eval_cid = %d;\n" % self.cef_python_eval_cid
        cmd += "window.track_attributes_cid = %d;\n" % self.cef_attribute_change_cid
        cmd += "window.popup_menu_cid = %d;\n" % self.cef_popup_menu_cid
        cmd += "window.popup_rig_menu_cid = %d;\n" % self.cef_popup_rig_menu_cid
        cmd += "window.key_event_cid = %d;\n" % self.cef_key_event_cid
        cmd += "window.sync_selection_cid = %d;\n" % self.cef_sync_selection_cid
        cmd += "window.open_face_cam_cid = %d;\n" % self.cef_open_face_cam_cid
        cmd += "window.asset_namespace ='%s';" % self.parent.asset_info['namespace']
        cmd += "window.options_focus_on_resize= %s;" % ('true' if self._option_focus_on_resize == True else 'false')
        cmd += "window.options_hide_avatar = %s;" % ('true' if self._option_hide_avatar == True else 'false')
        cmd += "window.options_start_focus = '%s';" % str(self._option_start_focus)
        cmd += "window.asset_info = %s;" % json.dumps(self.parent.asset_info)
        if self.parent.asset_info.get("picker_path"):
            control_list = [str(ctrl.stripNamespace()) for ctrl in pm.ls("%s:*_control" % self.parent.asset_info.get("namespace"))]
            cmd += "window.asset_controls_list = %s;" % json.dumps(control_list)
            cmd += "window.picker_face_camera = %s;" % ('true' if pm.objExists("%s:picker_face_cam" % self.parent.asset_info.get("namespace")) else 'false')

        cmd += """if (window.document.getElementById('error_picker') != null){
        window.document.getElementById('error_picker').style.visibility = '%s'};""" % self.visibility
        cmd += "var off_select = {};".format(self.off_select)
        cmd = str(cmd)
        # call now and register for reloads
        self.browser.RegisterStartupCode(cmd)
        self.browser.ExecuteJavascript(cmd)

    def set_option_focus_on_resize(self, state):
        self._option_focus_on_resize = state
        cmd = "window.options_focus_on_resize= %s" % ('true' if self._option_focus_on_resize == True else 'false')
        self.browser.ExecuteJavascript(cmd)

    def set_option_hide_avatar(self, state):
        self._option_hide_avatar = state
        cmd = "window.options_hide_avatar= %s;\n" % ('true' if self._option_hide_avatar == True else 'false')
        cmd += "picker_util.update_avatar_vis();"
        self.browser.ExecuteJavascript(cmd)

    def attribute_change_callback(self, msg, plug, otherPlug, clientData):
        if msg & pm.api.MNodeMessage.kAttributeEval or msg & pm.api.MNodeMessage.kAttributeSet:

            attr = pm.PyNode(plug)
            widget, tested_attribute = clientData
            if attr == tested_attribute:
                value = attr.get()
                attr_name = attr.name()
                cmd = 'maya.attribute_change("%s", %d) ' % (attr_name, value)
                cmd = str(cmd)
                #print '[wizart_cef_javascript]', cmd
                widget.browser.ExecuteJavascript(cmd)


    def playback_change_attr_callbacks(self, state, client_data):
        for attr in self._attribute_change_attrs:
            if attr.exists():
                self.attribute_change_callback(pm.api.MNodeMessage.kAttributeEval, attr.__apimplug__(), None, (self, attr))

    def time_update_attr_callbacks(self):
        if pm.api.MAnimControl.isPlaying():
            return
        for attr in self._attribute_change_attrs:
            if attr.exists():
                self.attribute_change_callback(pm.api.MNodeMessage.kAttributeEval, attr.__apimplug__(), None, (self, attr))


    def key_event_callback(self, key_code, shift, control, alt):
        self.key_event_signal.emit(key_code, shift, control, alt)

    def key_event_slot(self, key_code, shift, control, alt):
        modifiers = QtCore.Qt.NoModifier
        if shift == True:
            modifiers = modifiers | QtCore.Qt.ShiftModifier
        if control == True:
            modifiers = modifiers | QtCore.Qt.ControlModifier
        if alt == True:
            modifiers = modifiers | QtCore.Qt.AltModifier

        event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key_code, modifiers, "", False, 1)
        window = maya_qtutils.getMayaWindow(QtWidgets.QWidget)
        QtWidgets.QApplication.instance().sendEvent(window, event)
        event = QtGui.QKeyEvent(QtCore.QEvent.KeyRelease, key_code, modifiers, "", False, 1)
        QtWidgets.QApplication.instance().sendEvent(window, event)

    def popup_rig_menu_callback(self, pos_x, pos_y, node_name):
        menu = QtWidgets.QMenu(self)
        wizart.anim_utils.menu.createContextMenu(menu, node_name,  wizart.anim_utils.menu.AppType.Qt, inPicker=True)  # inPicker allow to skip "show in picker" in generate menu
        global_point = self.mapToGlobal(QtCore.QPoint(pos_x, pos_y))
        menu.exec_(global_point)

    def popup_menu_callback(self, pos_x, pos_y, menu_items):
        menu = QtWidgets.QMenu(self)
        for menu_item in menu_items:
            menu.addAction(menu_item[0], partial(self.browser.ExecuteJavascript, menu_item[1]))
        global_point = self.mapToGlobal(QtCore.QPoint(pos_x, pos_y))
        menu.exec_(global_point)

    def install_attribute_change_callbacks(self, *args):
        for arg in args:
            if pm.objExists(arg):
                attribute = pm.PyNode(arg)
                cid = pm.api.MNodeMessage.addAttributeChangedCallback(attribute.node().__apimobject__(), self.attribute_change_callback, (self, attribute))
                self._attribute_change_cids.append(cid)
                self._attribute_change_attrs.append(attribute)
                cmd = 'maya.attribute_change("%s", %d) ' % (attribute.name(), attribute.get())
                cmd = str(cmd)
                # print '[wizart_cef_javascript]', cmd
                self.browser.ExecuteJavascript(cmd)

    def reload(self):
        self.uninstall_attribute_change_callbacks()
        self.browser.UnregisterStartupCode()
        self.javascript_startup()
        self.browser.Reload()

    def uninstall_attribute_change_callbacks(self):
        for cid in self._attribute_change_cids:
            pm.api.MMessage.removeCallback(cid)
        self._attribute_change_cids = []
        self._attribute_change_attrs = []

    def resizeEvent(self, event):
        size = event.size()
        width = size.width()
        height = size.height()
        if self.browser:
            self.browser.Resize(0, 0, width, height)

    def _update_selection(self):
        import json
        if self.browser:
            selection = pm.ls(sl=True)
            sel_list = json.dumps([obj.name() for obj in selection])
            cmd = str('maya.update_selection(%s)' % sel_list)
            self.browser.ExecuteJavascript(cmd)

    def open_face_cam_callback(self, face_controls):
        self.open_face_cam_signal.emit(face_controls)

    def open_face_cam_slot(self, face_controls):
        from face_cam_tool import FaceCamWindow
        if PickerWindow.face_cam_window == None:
            PickerWindow.face_cam_window = FaceCamWindow(maya_qtutils.getMayaWindow(QtWidgets.QWidget))
            PickerWindow.face_cam_window.resize(300, 300)
            PickerWindow.face_cam_window.show()
        else:
            PickerWindow.face_cam_window.show()
        PickerWindow.face_cam_window.change_asset(self.parent.asset_info["namespace"], face_controls)

    def update_face_cam(self):
        if self.browser:
            if PickerWindow.face_cam_window != None:
                cmd = "picker_util.open_face_cam();"
                self.browser.ExecuteJavascript(cmd)

    def destroy_browser(self):
        pm.api.MConditionMessage.removeCallback(self._selection_callback)
        pm.api.MConditionMessage.removeCallback(self._playback_change_cid)
        pm.api.MDGMessage.removeCallback(self._time_callback_cid)
        cef.UnregisterPyCallback(self.cef_attribute_change_cid)
        cef.UnregisterPyCallback(self.cef_popup_menu_cid)
        cef.UnregisterPyCallback(self.cef_popup_rig_menu_cid)
        cef.UnregisterPyCallback(self.cef_open_face_cam_cid)
        self.uninstall_attribute_change_callbacks()
        if self.browser:
            self.browser.UnregisterStartupCode()
            self.browser.Close()
            self.browser = None


class DockableTabBar(QtWidgets.QTabBar):
    def __init__(self, parent_window):
        super(DockableTabBar, self).__init__()
        self.parent_window = parent_window
        self.drag_tab_index = -1
        self.tear_off_window = None
        self.move_click = False

    def mousePressEvent(self, event):
        self.drag_tab_index = self.tabAt(event.pos())
        if event.modifiers() == QtCore.Qt.ShiftModifier:
            self.parent_window.tab_widget.setMovable(False)
            self.move_click = True
        else:
            super(DockableTabBar, self).mousePressEvent(event)

    @property
    def header_height(self):
        return (self.parent_window.geometry().y() - self.parent_window.pos().y()) + self.parent_window.layout().menuBar().geometry().height()

    def pos_without_header(self, pos):
        new_pos = QtCore.QPoint(pos.x(), pos.y())
        new_pos.setY(new_pos.y() - self.header_height)
        return new_pos

    def under_another_picker_window(self, pos, ignore_other=None):
        for window in PickerWindow.get_instances():
            if window != self.parent_window and window != ignore_other and window.frameGeometry().contains(pos):
                return window

    def mouseMoveEvent(self, event):
        if self.move_click is True:
            if self.tear_off_window != None:
                self.tear_off_window.move(
                    self.pos_without_header(event.globalPos()) - self.tear_off_window.tab_widget.tabBar().tabRect(self.drag_tab_index).center())
                other_picker_window = self.under_another_picker_window(event.globalPos(), self.tear_off_window)
                if other_picker_window is not None:
                    widget = self.tear_off_window.tab_widget.widget(self.drag_tab_index)
                    tab_title = self.tear_off_window.tab_widget.tabText(self.drag_tab_index)
                    self.tear_off_window.tab_widget.removeTab(self.drag_tab_index)
                    tab_index = other_picker_window.tab_widget.addTab(widget, tab_title)
                    other_picker_window.tab_widget.setCurrentIndex(tab_index)
                    self.tear_off_window.close()
                    self.drag_tab_index = -1
                    self.tear_off_window = None
            elif self.drag_tab_index != -1 and self.count() == 1:
                pos = self.pos_without_header(event.globalPos())
                pos = pos - self.tabRect(self.drag_tab_index).center()
                self.parent_window.move(pos)
                other_picker_window = self.under_another_picker_window(event.globalPos())
                if other_picker_window is not None:
                    widget = self.parent_window.tab_widget.widget(self.drag_tab_index)
                    tab_title = self.parent_window.tab_widget.tabText(self.drag_tab_index)
                    self.parent_window.tab_widget.removeTab(self.drag_tab_index)
                    tab_index = other_picker_window.tab_widget.addTab(widget, tab_title)
                    other_picker_window.tab_widget.setCurrentIndex(tab_index)
                    self.drag_tab_index = -1
                    self.parent_window.close()
                self.parent_window.tab_widget.setMovable(True)



            elif not self.parent_window.frameGeometry().contains(
                    event.globalPos()) and self.drag_tab_index != -1 and self.count() > 1:

                widget = self.parent_window.tab_widget.widget(self.drag_tab_index)
                tab_title = self.parent_window.tab_widget.tabText(self.drag_tab_index)
                self.parent_window.tab_widget.removeTab(self.drag_tab_index)
                self.tear_off_window = PickerWindow(maya_qtutils.getMayaWindow(QtWidgets.QWidget))
                self.drag_tab_index = self.tear_off_window.tab_widget.addTab(widget, tab_title)
                self.tear_off_window.show()
                self.tear_off_window.move(self.pos_without_header(event.globalPos()) - self.tear_off_window.tab_widget.tabBar().tabRect(self.drag_tab_index).center())

        else:
            super(DockableTabBar, self).mouseMoveEvent(event)

    def mouseReleaseEvent(self, event):
        self.move_click = False
        self.drag_tab_index = -1
        self.tear_off_window = None
        self.parent_window.tab_widget.setMovable(True)
        super(DockableTabBar, self).mouseReleaseEvent(event)


def asset_info_tab_title(asset_info):
    return '%s:%s' % (asset_info["namespace"], asset_info["name"])


class PickerWindow(QtWidgets.QWidget):
    refs = []
    face_cam_window = None
    page_disconnect_from_maya = ('true', 'visible')
    page_connect_to_maya = ('false', 'hidden')
    def __init__(self, parent=None):
        super(PickerWindow, self).__init__(parent)
        self.refs.append(self)

        self.window_title = 'Wizart Character Picker'
        self.setWindowTitle(self.window_title)
        # self.setStyleSheet("border: 1px black")
        self.setWindowFlags(QtCore.Qt.Window)
        self.setLayout(QtWidgets.QVBoxLayout())
        self.tab_widget = QtWidgets.QTabWidget()
        self.tab_widget.setTabBar(DockableTabBar(self))
        self.picker_widget = QtWidgets.QWidget()
        self.layout().addWidget(self.tab_widget)
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.setMovable(True)
        self.menubar = QtWidgets.QMenuBar(self)
        self.options_menu = QtWidgets.QMenu("Options")
        self.focus_resize_act = self.options_menu.addAction("Focus On Resize")
        self.focus_resize_act.setCheckable(True)
        self.callback_dict = {}

        options_focus_on_resize = pm.optionVar.get("wizart_picker_options_focus_on_resize", 0)
        options_focus_on_resize = True if options_focus_on_resize == 1 else False

        self.focus_resize_act.setChecked(options_focus_on_resize)
        self.focus_resize_act.toggled.connect(self.change_focus_on_resize)

        self.hide_avatar_act = self.options_menu.addAction("Hide Avatar")
        self.hide_avatar_act.setCheckable(True)

        options_hide_avatar = pm.optionVar.get("wizart_picker_options_hide_avatar", 0)
        options_hide_avatar = True if options_hide_avatar == 1 else False
        self.hide_avatar_act.setChecked(options_hide_avatar)
        self.hide_avatar_act.toggled.connect(self.hide_avatar)

        self.options_start_focus_menu = self.options_menu.addMenu("Start Focus")
        action_group = QtWidgets.QActionGroup(self)
        self.act_focus_start_face = self.options_start_focus_menu.addAction("Face")
        self.act_focus_start_face.setCheckable(True)
        self.act_focus_start_face.triggered.connect(partial(self.set_start_focus))

        self.act_focus_start_body = self.options_start_focus_menu.addAction("Body")
        self.act_focus_start_body.setCheckable(True)
        self.act_focus_start_body.triggered.connect(partial(self.set_start_focus))

        self.act_focus_start_all = self.options_start_focus_menu.addAction("All")
        self.act_focus_start_all.setCheckable(True)
        self.act_focus_start_all.triggered.connect(partial(self.set_start_focus))

        options_start_focus = pm.optionVar.get("wizart_picker_options_start_focus", "all")
        dict(all=self.act_focus_start_all, body=self.act_focus_start_body, face=self.act_focus_start_face)[options_start_focus].setChecked(True)

        action_group.addAction(self.act_focus_start_face)
        action_group.addAction(self.act_focus_start_body)
        action_group.addAction(self.act_focus_start_all)
        self.options_menu.addAction("Save Windows Startup Size And Position", self.save_windows_start_size_and_position)

        self.dev_menu = QtWidgets.QMenu("Dev", self)
        act = self.dev_menu.addAction("Add Empty Tab")
        act.triggered.connect(partial(self.add_tab, assets_utils.make_asset_info()))

        self.menubar.addMenu(self.options_menu)
        self.menubar.addMenu(self.dev_menu)
        self.layout().setMenuBar(self.menubar)
        self.dev_show_toolbar_act = QtWidgets.QAction("Show Toolbar", self)
        self.dev_show_toolbar_act.setCheckable(True)
        self.dev_show_toolbar_act.setChecked(False)
        self.dev_show_toolbar_act.toggled.connect(self.show_toolbar)
        self.dev_menu.addAction(self.dev_show_toolbar_act)

        self.add_tab_btn = QtWidgets.QPushButton("+")
        self.add_tab_menu = QtWidgets.QMenu()

        def _add_tab_btn_click_event(event):
            self.add_tab_menu.clear()
            for asset_info in assets_utils.get_scene_asset_list():
                act = self.add_tab_menu.addAction(asset_info["namespace"] + ":" + asset_info["name"])
                act.triggered.connect(partial(self.add_tab, asset_info))
            return QtWidgets.QPushButton.mousePressEvent(self.add_tab_btn, event)

        self.add_tab_btn.setMenu(self.add_tab_menu)
        self.add_tab_btn.mousePressEvent = _add_tab_btn_click_event
        self.add_tab_btn.setFlat(True)
        self.add_tab_btn.setMinimumHeight(18)

        self.tab_widget.setCornerWidget(self.add_tab_btn, QtCore.Qt.TopRightCorner)
        self.tab_widget.tabCloseRequested.connect(self.close_tab)

        self._selection_callback = pm.api.MEventMessage.addEventCallback("SelectionChanged", lambda *args: self.update_selection())
        # open scene callback
        self._open_sc_callback = pm.api.MSceneMessage.addCallback(pm.api.MSceneMessage.kAfterOpen, self.reload_tabs)
        self._new_sc_callback = pm.api.MSceneMessage.addCallback(pm.api.MSceneMessage.kAfterNew, self.reload_tabs)
        self._before_open_sc_callback = pm.api.MSceneMessage.addCallback(pm.api.MSceneMessage.kBeforeOpen, self.delete_rename_callbacks)
        self._before_new_sc_callback = pm.api.MSceneMessage.addCallback(pm.api.MSceneMessage.kBeforeNew, self.delete_rename_callbacks)
        # Callbacks for load and unload reference
        self._unload_ref_callback = pm.api.MSceneMessage.addReferenceCallback(pm.api.MSceneMessage.kAfterUnloadReference, self.reload_tab, self.page_disconnect_from_maya)
        self._load_ref_callback = pm.api.MSceneMessage.addReferenceCallback(pm.api.MSceneMessage.kAfterLoadReference, self.reload_tab, self.page_connect_to_maya)
        self._create_ref_callback = pm.api.MSceneMessage.addReferenceCallback(pm.api.MSceneMessage.kAfterCreateReferenceAndRecordEdits, self.reload_tab, self.page_connect_to_maya)
        self._remove_ref_callback = pm.api.MSceneMessage.addReferenceCallback(pm.api.MSceneMessage.kBeforeRemoveReference, self.reload_tab, self.page_disconnect_from_maya)

    def delete_rename_callbacks(self):
        browser_tab = self.tab_widget
        for idx in range(browser_tab.count()):
            self.delete_rename_callback_single(browser_tab.widget(idx))


    def delete_rename_callback_single(self, browser_widget):
        if browser_widget.rename_namespace_callback:
            pm.api.MNodeMessage.removeCallback(browser_widget.rename_namespace_callback)
            browser_widget.rename_namespace_callback = None

    def reload_namespace(self, obj, txt, my_tuple):
        refNode = my_tuple[0]
        browser_widget = my_tuple[1]
        ref = pm.FileReference(refNode).nodes()[0].namespace()[:-1]
        old_namespace = pm.FileReference(refNode).namespace
        path = pm.FileReference(refNode).path
        browser_tab = self.tab_widget  # QTabWidget
        asset_info = browser_widget.asset_info
        tab_idx = browser_tab.indexOf(browser_widget)
        if asset_info['path'] == path and asset_info['namespace'] == old_namespace:
            asset_info['namespace'] = ref
            cmd = "window.asset_namespace ='%s';" % asset_info['namespace']
            browser_widget.frame.browser.ExecuteJavascript(cmd)
            browser_tab.setTabText(tab_idx, asset_info["namespace"] + ':' + asset_info["name"])

    def add_rename_namespace_callback(self, browser_widget):
        self.delete_rename_callback_single(browser_widget)
        asset_info = browser_widget.asset_info
        reference = pm.FileReference(namespace=asset_info['namespace'])
        rename_namespace_callback = pm.api.MNodeMessage.addNameChangedCallback(reference.nodes()[0].__apimobject__(), self.reload_namespace, (reference.refNode, browser_widget))
        browser_widget.rename_namespace_callback = rename_namespace_callback

    def reload_tab(self, referenceNode, file, clientData):
        ref_name = pm.api.MFnDependencyNode(referenceNode).name()
        path = file.resolvedFullName()
        ref_namespace = pm.FileReference(ref_name).namespace
        browser_tab = self.tab_widget
        for idx in range(browser_tab.count()):
            asset_info = browser_tab.widget(idx).asset_info
            if asset_info.get('path') == path and asset_info.get('namespace') == ref_namespace:
                browser_tab.widget(idx).frame.off_select = clientData[0]
                browser_tab.widget(idx).frame.visibility = clientData[1]
                if clientData == self.page_connect_to_maya:
                    self.add_rename_namespace_callback(browser_tab.widget(idx))
                else:
                    self.delete_rename_callback_single(browser_tab.widget(idx))
                browser_tab.widget(idx).frame.reload()

    def reload_tabs(self, *args):
        reference_list = [ref for ref in pm.listReferences() if ref.isLoaded()]

        browser_tab = self.tab_widget
        for idx in range(browser_tab.count()):
            asset_info = browser_tab.widget(idx).asset_info
            reference_is_found = False
            for ref in reference_list:
                if asset_info.get('namespace') == ref.namespace and asset_info.get('path') == ref.path:
                    reference_is_found = True
                    break
            if reference_is_found:
                browser_tab.widget(idx).frame.off_select = self.page_connect_to_maya[0]
                browser_tab.widget(idx).frame.visibility = self.page_connect_to_maya[1]
                self.add_rename_namespace_callback(browser_tab.widget(idx))
            else:
                browser_tab.widget(idx).frame.off_select = self.page_disconnect_from_maya[0]
                browser_tab.widget(idx).frame.visibility = self.page_disconnect_from_maya[1]
            browser_tab.widget(idx).frame.reload()
        reference_list = None


    @classmethod
    def get_instances(cls):
        for inst in cls.refs:
            yield inst

    def update_selection(self):
        selection = pm.ls(sl=True)
        if selection:
            last_obj = selection[-1]
            asset_namespace = last_obj.namespace()[:-1]
            if asset_namespace == self.tab_widget.widget(self.tab_widget.currentIndex()).asset_info.get("namespace"): 
                return
            for idx in range(self.tab_widget.count()):
                widget = self.tab_widget.widget(idx)
                if asset_namespace == widget.asset_info.get("namespace"):
                    self.tab_widget.setCurrentIndex(idx)
                    self.tab_widget.widget(idx).frame.update_face_cam()
                    break

    def show_toolbar(self, state):
        for idx in range(self.tab_widget.count()):
            widget = self.tab_widget.widget(idx)
            if state == True:
                widget.toolbar.show()
            else:
                widget.toolbar.hide()

    def change_focus_on_resize(self, state):
        for idx in range(self.tab_widget.count()):
            widget = self.tab_widget.widget(idx)
            widget.frame.set_option_focus_on_resize(state)
        pm.optionVar["wizart_picker_options_focus_on_resize"] = 1 if state == True else 0

    def hide_avatar(self, state):
        for idx in range(self.tab_widget.count()):
            widget = self.tab_widget.widget(idx)
            widget.frame.set_option_hide_avatar(state)
        pm.optionVar["wizart_picker_options_hide_avatar"] = 1 if state == True else 0

    def save_windows_start_size_and_position(self):
        pm.optionVar["wizart_picker_options_start_win_width"] = self.width()
        pm.optionVar["wizart_picker_options_start_win_height"] = self.height()
        pm.optionVar["wizart_picker_options_start_pos_x"] = self.pos().x()
        pm.optionVar["wizart_picker_options_start_pos_y"] = self.pos().y()

    def set_start_focus(self):
        if self.act_focus_start_all.isChecked():
            pm.optionVar["wizart_picker_options_start_focus"] = "all"
        if self.act_focus_start_body.isChecked():
            pm.optionVar["wizart_picker_options_start_focus"] = "body"
        if self.act_focus_start_face.isChecked():
            pm.optionVar["wizart_picker_options_start_focus"] = "face"

    def close_tab(self, index):
        widget = self.tab_widget.widget(index)
        self.delete_rename_callback_single(widget)
        self.tab_widget.removeTab(index)
        if widget:
            widget.destroy_browser()

    def add_tab(self, asset_info=None, url=None):
        browser_tab = BrowserTab(self, asset_info)
        index = self.tab_widget.addTab(browser_tab, asset_info_tab_title(asset_info))
        browser_tab.embed_browser(url)
        self.add_rename_namespace_callback(browser_tab)
        return index

    def closeEvent(self, event):
        for index in range(self.tab_widget.count()):
            self.close_tab(index)
        PickerWindow.refs.remove(self)
        if self._selection_callback:
            pm.api.MConditionMessage.removeCallback(self._selection_callback)
            self._selection_callback = None
        if self._unload_ref_callback:
            pm.api.MMessage.removeCallback(self._unload_ref_callback)
            self._unload_ref_callback = None
        if self._load_ref_callback:
            pm.api.MMessage.removeCallback(self._load_ref_callback)
            self._load_ref_callback = None
        if self._create_ref_callback:
            pm.api.MMessage.removeCallback(self._create_ref_callback)
            self._create_ref_callback = None
        if self._remove_ref_callback:
            pm.api.MMessage.removeCallback(self._remove_ref_callback)
            self._remove_ref_callback = None
        if self._open_sc_callback:
            pm.api.MMessage.removeCallback(self._open_sc_callback)
            self._open_sc_callback = None
        if self._new_sc_callback:
            pm.api.MMessage.removeCallback(self._new_sc_callback)
            self._new_sc_callback = None
        if self._before_open_sc_callback:
            pm.api.MMessage.removeCallback(self._before_open_sc_callback)
            self._before_open_sc_callback = None
        if self._before_new_sc_callback:
            pm.api.MMessage.removeCallback(self._before_new_sc_callback)
            self._before_new_sc_callback = None
        event.accept()





