def open_settings_popup(self):

            sender = self.sender()

            "Get the index of this widget"
            index = self.model.get_settings_button_index(sender)

            self.settings_popup = BlockPopupView(self.model, index)

            self.settings_popup.show()
class MidiChainContainer(QtGui.QWidget):

    def __init__(self, model, main_view, main_ctrl):

        self.model = model

        self.main_view = main_view

        self.main_ctrl = main_ctrl

        self.settings_popup = None

        super(MidiChainContainer, self).__init__()

        self.build_ui()


    def build_ui(self):

        self.layout = QtGui.QHBoxLayout(self)

        self.layout.addStretch()

        """ Need to fix up

        for i in range(self.model.get_button_list_length()):

            button = self.model.get_button_at_index(i)

            self.layout.addWidget(button)

        """

        self.setLayout(self.layout)


    def add_block_to_chain(self):

        #Get the  new index
        index = self.model.get_block_widget_list_length()
        #Create a new block widget.
        block_widget = BlockWidget(self.model, self.main_view, self, index)

        """ Added connections in the Block Widget
        #Connect the block_type_combo_box with the change_block_type_at_index method
        block_widget.block_type_combo_box.currentIndexChanged.connect(self.change_block_type_at_index)

        #Connect the delete button clicked event with the remove_button_signal
        block_widget.delete_button.clicked.connect(self.remove_block_at_index)

        #Connect the settings button clicked even with the change_block_settings_at_index method
        block_widget.settings_button.clicked.connect(self.change_block_settings_at_index)

        #Connect the left_button clicked even with the move_block_at_index_left method
        block_widget.left_button.clicked.connect(self.move_block_at_index_left)

        #Connect the right_button clicked even with the move_block_at_index_right method
        block_widget.right_button.clicked.connect(self.move_block_at_index_right)

        """

        self.model.add_block(block_widget)

        self.layout.addWidget(block_widget)

        "Add action to the undo list"

        self.model.add_to_undo_actions(('Add Block', 0))

        "Add the controller aspect of the block"

        self.main_ctrl.midi_chain_ctrl.add_block_to_chain()

    def add_block_at_index(self, index, block, processing_block):

        """ May not need
        "Added connections in the Block Widget"
        #Connect the block_type_combo_box with the change_block_type_at_index method
        block.block_type_combo_box.currentIndexChanged.connect(self.change_block_type_at_index)

        #Connect the delete button clicked event with the remove_button_signal
        block.delete_button.clicked.connect(self.remove_block_at_index)

        #Connect the settings button clicked even with the change_block_settings_at_index method
        block.settings_button.clicked.connect(self.change_block_settings_at_index)

        #Connect the left_button clicked even with the move_block_at_index_left method
        block.left_button.clicked.connect(self.move_block_at_index_left)

        #Connect the right_button clicked even with the move_block_at_index_right method
        block.right_button.clicked.connect(self.move_block_at_index_right)
        """

        if index == 0 and self.model.get_block_widget_list_length() == 0:
            self.layout.addWidget(block)
        else:
            self.layout.insertWidget(index + 1, block)
        
        self.model.add_block_at_index(index, block)
        

        "Add the controller aspect of the block"

        self.main_ctrl.midi_chain_ctrl.add_block_to_chain_at_index(index, processing_block)

    def clear_chain(self):
        
        
        if self.model.get_block_widget_list_length() > 0:

            "Action Tuple = ('Clear Chain', model.block_widget_list,  model._midi_block_chain)"
            "Add action to the undo list"

            block_widget_list = self.model.get_block_widget_list()
            midi_block_chain = self.model.get_midi_chain()
            self.model.add_to_undo_actions(('Clear Chain', block_widget_list, midi_block_chain))

            while self.model.get_block_widget_list_length() > 0:

                block_widget = self.model.get_last_block_widget()

                #Remove from the model list
                self.model.remove_block(block_widget)

                #Remove from the layout
                self.layout.removeWidget(block_widget)
                block_widget.setParent(None)

            "Clear the midi_chain processing block list"
            self.main_ctrl.midi_chain_ctrl.clear_chain()
        
        return

                               

    def remove_block_at_index(self):

        sender = self.sender()

        #Get the index of the sender

        index = self.model.get_delete_button_index(sender)


        # Remove all the block buttons / combo boxs / (classes) from the model lists 

        block_widget = self.model.get_block_widget_at_index(index)

        #Remove from the layout

        self.layout.removeWidget(block_widget)
        

        #Remove from the model list

        self.model.remove_block_at_index(index)

        "Add action to the undo list"
        processing_block = self.model.get_block_at_midi_chain_index(index)
        action = ("Remove Block", index, block_widget, processing_block)
        self.model.add_to_undo_actions(action)

        block_widget.setParent(None)

        " Remove the processing block from the midi_chain"
        self.main_ctrl.midi_chain_ctrl.remove_block_from_chain(index)





    def delete_block_at_index(self, index):


        # Remove all the block buttons / combo boxs / (classes) from the model lists 

        block_widget = self.model.get_block_widget_at_index(index)

        #Remove from the layout

        self.layout.removeWidget(block_widget)
        block_widget.deleteLater()
        block_widget = None

        #Remove from the model list

        self.model.remove_block_at_index(index)

        " Remove the processing block from the midi_chain"
        self.main_ctrl.midi_chain_ctrl.remove_block_from_chain(index)

    


    def open_settings_popup(self):

            sender = self.sender()

            "Get the index of this widget"
            index = self.model.get_settings_button_index(sender)

            self.settings_popup = BlockPopupView(self.model, index)

            self.settings_popup.show()


    def move_block_at_index_left(self):

        sender = self.sender()

        #Get the index of the sender

        index = self.model.get_left_button_index(sender)

        if index > 0:

            "Able to move left"

            "Add action to the undo actions list"
            "Action Tuple = ('Move Block Left', index)"
            self.model.add_to_undo_actions(("Move Block Left", index))

            "Get the current index block"

            block_widget = self.model.get_block_widget_at_index(index)

            "Remove from GUI Layout"
            self.layout.removeWidget(block_widget)

            "Move block to left in model"
            self.model.move_block_to_left(index)

            "Move the processing block in the midi chain"
            self.main_ctrl.midi_chain_ctrl.move_block_left(index)

            "Update View"
            self.layout.insertWidget(index, block_widget)

    def undo_move_block_at_index_left(self, index):

        if index > 0:

            "Able to move left"

            "Get the current index block"

            block_widget = self.model.get_block_widget_at_index(index)

            "Remove from GUI Layout"
            self.layout.removeWidget(block_widget)

            "Move block to left in model"
            self.model.move_block_to_left(index)

            "Move the processing block in the midi chain"
            self.main_ctrl.midi_chain_ctrl.move_block_left(index)

            "Update View"
            self.layout.insertWidget(index, block_widget)

            

    def move_block_at_index_right(self):

        sender = self.sender()

        #Get the index of the sender

        index = self.model.get_right_button_index(sender)

        if index < (self.model.get_block_widget_list_length() - 1):

            "Able to move right"

            "Add action to the undo actions list"
            "Action Tuple = ('Move Block Left', index)"
            self.model.add_to_undo_actions(("Move Block Right", index))

            "Get the current index block"

            block_widget = self.model.get_block_widget_at_index(index)

            "Remove from GUI Layout"
            self.layout.removeWidget(block_widget)

            "Move block to left in model"
            self.model.move_block_to_right(index)

            "Move the processing block in the midi chain"
            self.main_ctrl.midi_chain_ctrl.move_block_right(index)

            "Update View"
            self.layout.insertWidget(index + 2, block_widget)

    def undo_move_block_at_index_right(self, index):

        if index < (self.model.get_block_widget_list_length() - 1):

            "Able to move right"

            "Get the current index block"

            block_widget = self.model.get_block_widget_at_index(index)

            "Remove from GUI Layout"
            self.layout.removeWidget(block_widget)

            "Move block to left in model"
            self.model.move_block_to_right(index)

            "Move the processing block in the midi chain"
            self.main_ctrl.midi_chain_ctrl.move_block_right(index)

            "Update View"
            self.layout.insertWidget(index + 2, block_widget)


    def change_block_type_at_index(self):

        sender = self.sender()

        #Get the index of the sender

        index = self.model.get_type_combo_box_index(sender)

        #Get the block widget at that index

        block_widget = self.model.get_block_widget_at_index(index)

        "Check to see if the las action was the same, if so do not add this"
        last_action = self.model.get_most_recent_action()

        if last_action[0] == 'Change Block Type' and last_action[1] == index:

            "Do not add to  undo_actions"
        else:

            "Add to undo actions list"
            "Action Tuple = ('Change Block Type', index, block, proc_block)"
            self.model.add_to_undo_actions(("Change Block Type", index, block_widget, 
                self.model.get_block_at_midi_chain_index(index)))


        #Remove the being displayed

        self.layout.removeWidget(block_widget)

        if sender.currentText() == 'Pitch Shift':

            "Change the backgorund pallete to red"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.red)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.change_block_type_at_index(index, 'Pitch Shift')

        elif sender.currentText() == 'Arpeggiator':

            "Change the backgorund pallete to yellow"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.yellow)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.change_block_type_at_index(index, 'Arpeggiator')

        elif sender.currentText() == 'Monophonic':

            "Change the background pallete to green"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.green)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.change_block_type_at_index(index, 'Monophonic')

        elif sender.currentText() == 'Chordify':

            "Change the background pallete to blue"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.blue)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.change_block_type_at_index(index, 'Chordify')

        #The insert index for the gui is (len of list - 1) - index


        self.layout.insertWidget(index+1, block_widget)






    def undo_change_block_type_at_index(self, index, block_widget, processing_block):

        #Remove the being displayed

        self.layout.removeWidget(block_widget)

        if processing_block.get_type() == 'Pitch Shift':

            "Change the backgorund pallete to red"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.red)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.remove_block_from_chain(index)
            self.main_ctrl.midi_chain_ctrl.add_block_to_chain_at_index(index, processing_block)


        elif processing_block.get_type() == 'Arpeggiator':

            "Change the backgorund pallete to yellow"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.yellow)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.remove_block_from_chain(index)
            self.main_ctrl.midi_chain_ctrl.add_block_to_chain_at_index(index, processing_block)

        elif processing_block.get_type() == 'Monophonic':

            "Change the background pallete to green"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.green)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.remove_block_from_chain(index)
            self.main_ctrl.midi_chain_ctrl.add_block_to_chain_at_index(index, processing_block)

        elif processing_block.get_type() == 'Chordify':

            "Change the background pallete to blue"

            p = block_widget.palette()
            p.setColor(block_widget.backgroundRole(), QtCore.Qt.blue)
            block_widget.setPalette(p)

            "Change the processing block controller at that index"

            self.main_ctrl.midi_chain_ctrl.remove_block_from_chain(index)
            self.main_ctrl.midi_chain_ctrl.add_block_to_chain_at_index(index, processing_block)


        "Put the "
        block_type_combo_box_index = self.model.get_block_type_index_of_block_type(processing_block.get_type())

        block_widget.block_type_combo_box.setCurrentIndex(block_type_combo_box_index)

        #The insert index for the gui is (len of list - 1) - index

        self.layout.insertWidget(index + 1, block_widget)



    "LOAD CONFIGURATION FUNCTIONS"
    def add_config_block_to_chain(self, type_index):

        #Get the  new index
        index = self.model.get_block_widget_list_length()
        #Create a new block widget.
        block_widget = BlockWidget(self.model, self.main_view, self, index)

        """ Added connections in the Block Widget
        #Connect the block_type_combo_box with the change_block_type_at_index method
        block_widget.block_type_combo_box.currentIndexChanged.connect(self.change_block_type_at_index)

        #Connect the delete button clicked event with the remove_button_signal
        block_widget.delete_button.clicked.connect(self.remove_block_at_index)

        #Connect the settings button clicked even with the change_block_settings_at_index method
        block_widget.settings_button.clicked.connect(self.change_block_settings_at_index)

        #Connect the left_button clicked even with the move_block_at_index_left method
        block_widget.left_button.clicked.connect(self.move_block_at_index_left)

        #Connect the right_button clicked even with the move_block_at_index_right method
        block_widget.right_button.clicked.connect(self.move_block_at_index_right)

        """

        self.model.add_block(block_widget)

        self.layout.addWidget(block_widget)


        "Add the controller aspect of the block"

        self.main_ctrl.midi_chain_ctrl.add_block_to_chain()


        block_widget.block_type_combo_box.setCurrentIndex(type_index)