class MovesetDatEditor(QWidget):
    def __init__(self, fname, save_directory='', owner=None):
        super().__init__()

        # reference to the main window because parent is overwritten by addTab
        self.owner = owner
        self.grid = QGridLayout(self)
        self.fname = fname

        self.editors_list = QListWidget(self)
        self.editors_list.setSizeAdjustPolicy(QListWidget.AdjustToContents)
        self.editors_list.setFixedWidth(150)
        self.frame = QStackedWidget(self)
        self.frame.setFrameStyle(QFrame.Panel | QFrame.Raised)
        self.frame.sizeHint = lambda: QSize(
            max(
                self.frame.widget(i).sizeHint().width()
                for i in range(self.frame.count())),
            max(
                self.frame.widget(i).sizeHint().height()
                for i in range(self.frame.count())))
        self.initialize()

        self.grid.addWidget(QLabel(self.f.title(), self), 0, 0)
        self.grid.addWidget(self.editors_list, 1, 0)
        self.grid.addWidget(self.frame, 1, 1)
        self.grid.setColumnStretch(1, 1)

    def save(self):
        """Save the opened file (over itself)"""
        self.f.save(self.fname)
        self.last_save_directory = os.path.dirname(self.fname)

    def saveas(self):
        """Spawn a save file dialog and save as the selected file name"""
        self.fname = QFileDialog.getSaveFileName(
            self, 'Save Moveset File As', self.last_save_directory,
            'Moveset dat files (*.dat)')[0]
        if self.fname:
            self.save()
            # Retitle the tab to reflect the new filename.
            # QTabWidget uses a QStackedWidget internally, and that is the
            # parent of each tab, so we need parent() twice.
            tabs = self.parent().parent()
            tabs.setTabText(tabs.indexOf(self), os.path.basename(self.fname))

    def close(self):
        self.f.close()
        self.deleteLater()

    def reload(self):
        """Reload same file from disk"""
        while self.editors_list.count() > 0:
            w = self.editors_list.takeItem(0)
            del w
        while self.frame.count() > 0:
            w = self.frame.currentWidget()
            self.frame.removeWidget(w)
            w.deleteLater()
        self.f.close()
        self.initialize()

    def initialize(self):
        self.f = moveset_datfile(self.fname)
        self.setup_stacked_frame()

    @property
    def last_save_directory(self):
        return self.owner.last_save_directory

    @last_save_directory.setter
    def last_save_directory(self, val):
        self.owner.last_save_directory = val

    def setup_stacked_frame(self):
        self.script_widget = ScriptEditor(self.f)
        self.frame.addWidget(self.script_widget)

        self.common_attributes_widget = AttributeEditor(
            'Common Attributes', self.f.common_attributes_table)
        self.frame.addWidget(self.common_attributes_widget)

        self.unique_attributes_widget = AttributeEditor(
            'Unique Attributes', self.f.unique_attributes_table)
        self.frame.addWidget(self.unique_attributes_widget)

        self.hurtboxes_widget = HurtboxEditor(self.f.hurtbox_header,
                                              self.f.hurtbox_table)
        self.frame.addWidget(self.hurtboxes_widget)

        self.ledgegrab_editor = AttributeEditor('Ledge Grab Box',
                                                self.f.ledge_grab_data)
        self.frame.addWidget(self.ledgegrab_editor)

        for i in range(self.frame.count()):
            new = QListWidgetItem(self.frame.widget(i).display_name)
            self.editors_list.addItem(new)
            self.editors_list.currentRowChanged.connect(
                self.frame.setCurrentIndex)
        self.frame.sizeHint = lambda: QSize(
            max(
                self.frame.widget(i).sizeHint().width()
                for i in range(self.frame.count())),
            max(
                self.frame.widget(i).sizeHint().height()
                for i in range(self.frame.count())))
        self.frame.resize(self.frame.sizeHint())
        self.editors_list.setCurrentRow(0)