class LayoutCloner:
    def __init__(self):
        self.project = Project()

    def clone(self):
        shot_list = self.project.list_shots()

        self.item_gui = sfl.SelectFromList(l=shot_list,
                                           parent=hou.ui.mainQtWindow(),
                                           title="Select a shot to clone from")
        self.item_gui.submitted.connect(self.results)

    def results(self, value):
        self.shot_name = value[0]
        self.shot = self.project.get_shot(self.shot_name)
        if not self.shot:
            self.shot = self.project.create_shot(self.shot_name)
        if not self.shot:
            qd.error("Something's wrong here. Talk to Stephanie")
        self.layout_element = self.shot.get_element(Asset.LAYOUT)
        path = os.path.join(self.layout_element._filepath,
                            self.shot_name + ".usda")
        if not os.path.exists(path):
            # no layout is associated with this shot yet
            layouts = self.project.list_existing_layouts()

            self.item_gui = sfl.SelectFromList(
                l=layouts,
                parent=hou.ui.mainQtWindow(),
                title="Select a layout for this shot")
            self.item_gui.submitted.connect(self.layout_results)
            return

        self.load(path)

    def layout_results(self, value):
        layout_name = value[0]

        # copy ref file into the shot
        layout_body = self.project.get_layout(layout_name)
        element = layout_body.get_element(Asset.LAYOUT)
        src = os.path.join(element._filepath, layout_name + "_ref.usda")
        dst = os.path.join(self.layout_element._filepath,
                           self.shot_name + ".usda")
        shutil.copy(src, dst)
        pio.set_permissions(dst)
        self.load(dst)

    def load(self, file):
        ref = hou.node("/stage").createNode("loadlayer")
        ref.setName("layout_ref", 1)
        ref.parm("filepath").set(file)

        ref.setDisplayFlag(True)

        rop = hou.node("/stage").createNode("usd_rop")
        rop.setInput(0, ref)
        rop.parm("enableoutputprocessor_simplerelativepaths").set(0)
        rop.parm("lopoutput").set(file)
        rop.setName("save_layout", 1)
class UsdReader:
    def __init__(self):
        pm.loadPlugin("mayaUsdPlugin")
        self.project = Project()

    def go(self, quick=True):
        self.quick = quick
        shot_list = self.project.list_shots()

        self.item_gui = sfl.SelectFromList(
            l=shot_list, parent=maya_main_window(), title="Which shot is this layout in?")
        self.item_gui.submitted.connect(self.shot_results)

    def shot_results(self, value):
        self.shot_name = value[0]
        self.shot = self.project.get_shot(self.shot_name)
        if not self.shot:
            self.shot = self.project.create_shot(self.shot_name)
        if not self.shot:
            qd.error("This is real :'( (but the shot you picked isn't. talk to stephanie)")

        self.element = self.shot.get_element(Asset.LAYOUT)

        if self.element is None:
            qd.warning("Nothing was cloned.")
            return

        if self.quick:
            path = os.path.join(self.element._filepath, self.shot_name+".usda")
            if os.path.exists(path):
                self.open_scene_file(path)
                return
            else:
                self.choose_layout()
                return

        self.publishes = self.element.list_publishes()

        if not self.publishes:
            self.choose_layout()
            return

        # make the list a list of strings, not tuples
        self.sanitized_publish_list = []
        for publish in self.publishes:
            label = publish[0] + " " + publish[1] + " " + publish[2]
            self.sanitized_publish_list.append(label)

        self.item_gui =sfl.SelectFromList(
            l=self.sanitized_publish_list, parent=maya_main_window(), title="Select publish to clone")
        self.item_gui.submitted.connect(self.publish_selection_results)

    def publish_selection_results(self, value):

        selected_publish = None
        for item in self.sanitized_publish_list:
            if value[0] == item:
                selected_publish = item

        selected_scene_file = None
        for publish in self.publishes:
            label = publish[0] + " " + publish[1] + " " + publish[2]
            if label == selected_publish:
                selected_scene_file = publish[3]

        # selected_scene_file is the one that contains the scene file for the selected commit
        self.open_scene_file(selected_scene_file)

    def open_scene_file(self, selected_scene_file):
        if selected_scene_file is not None:

            if not os.path.exists(selected_scene_file):
                qd.error(
                    "That publish is missing. It may have been deleted to clear up space.")
                return False

            else:
                # do the thing
                command = "mayaUsd_createStageFromFilePath(\"" + selected_scene_file + "\")"
                pm.Mel.eval(command)

            return True
        else:
            return False

    def choose_layout(self):
        layout_list = self.project.list_layouts()

        self.item_gui =sfl.SelectFromList(
            l=layout_list, parent=maya_main_window(), title="Select layout to clone")
        self.item_gui.submitted.connect(self.layout_results)

    def layout_results(self, value):
        layout_name = value[0]
        layout = self.project.get_layout(layout_name)
        layout_element = layout.get_element(Asset.LAYOUT)
        src = os.path.join(layout_element._filepath, layout_name + "_ref.usda")
        dst = os.path.join(self.element._filepath, self.shot_name + ".usda")

        shutil.copy(src, dst)
        pio.set_permissions(dst)

        # basically set up a fake publish since we're not doing version control on this file
        self.element._datadict[self.element.LATEST_VERSION] = 0
        timestamp = pio.timestamp()
        username = Environment().get_user().get_username()
        self.element._datadict[self.element.PUBLISHES].append((username, timestamp, "initial publish", dst))
        self.element._update_pipeline_file()

        self.open_scene_file(dst)
class LayoutPublisher:

    def __init__(self):
        self.project = Project()

    def publish(self):
        if len(hou.selectedNodes()) != 1:
            qd.error("Select only the last node in the network")
            return

        layout_list = Project().list_layouts()

        self.item_gui = sfl.SelectFromList(l=layout_list, parent=hou.qt.mainWindow(), title="Which layout are you publishing?")
        self.item_gui.submitted.connect(self.results)

    def results(self, value):
        self.layout_name = value[0]

        self.layout = self.project.get_layout(self.layout_name)
        if self.layout is None:
            self.layout = Project().create_layout(self.layout_name)
        if self.layout is None:
            qd.error("Stephanie done messed up")
            return

        self.element = self.layout.get_element(Asset.LAYOUT)

        rop = hou.node("/stage").createNode("usd_rop")

        out = hou.selectedNodes()[0]
        rop.setInput(0, out)

        self.savePath = os.path.join(self.element._filepath, self.layout_name + ".usda")
        rop.parm("lopoutput").set(self.savePath)
        rop.parm("enableoutputprocessor_simplerelativepaths").set(0)

        rop.parm("execute").pressButton()

        rop.destroy()

        publishes = self.element.list_publishes()
        publishes_string_list = ""
        for publish in publishes:
            label = publish[0] + " " + publish[1] + " " + publish[2] + "\n"
            publishes_string_list += label
        
        self.comment = qd.HoudiniInput(
            parent=hou.qt.mainWindow(), title="Comment for publish?", info=publishes_string_list)
        self.comment.submitted.connect(self.comment_results)

    def comment_results(self, value):
        comment = str(value)
        username = Environment().get_user().get_username()
        self.element.update_app_ext(".usda")
        self.element.publish(username, self.savePath, comment, self.layout_name)

        if self.element.get_last_version() == 0:
            # if it is the first publish, we have to make the referencing file as well
            # create a reference node
            ref = hou.node("/stage").createNode("reference")
            # set the values to reference the main publish file, etc.
            ref.parm("primpath").set("/layout")
            ref.parm("filepath1").set(self.element.get_last_publish()[3])          
            # create a USD ROP node and connect it to the ref node
            refrop = hou.node("/stage").createNode("usd_rop")
            refrop.setInput(0, ref)
            # set the values in the ROP and save to disk alongside the main publish
            refrop.parm("lopoutput").set(os.path.join(self.element._filepath, self.layout_name + "_ref.usda"))
            refrop.parm("enableoutputprocessor_simplerelativepaths").set(0)
            refrop.parm("execute").pressButton()

            pio.set_permissions(os.path.join(self.element._filepath, self.layout_name + "_ref.usda"))
            #   this only needs to be done once since with every new publish, the file being referenced gets updated
            ref.destroy()
            refrop.destroy()