import maya.cmds as cmds
from PySide2 import QtWidgets, QtCore

class CameraRiggingToolUI(QtWidgets.QDialog):
    def __init__(self):
        super(CameraRiggingToolUI, self).__init__()

        self.setWindowTitle("Camera Rigging Tool")
        self.setMinimumWidth(300)

        self.create_widgets()
        self.create_layout()

    def create_widgets(self):
        # UI elements for camera name input
        self.camera_name_label = QtWidgets.QLabel("Camera Name:")
        self.camera_name_lineedit = QtWidgets.QLineEdit()

        # UI elements for film back size
        self.film_back_label = QtWidgets.QLabel("Film Back:")
        self.film_back_width_spinbox = QtWidgets.QDoubleSpinBox()
        self.film_back_width_spinbox.setRange(1, 500)
        self.film_back_width_spinbox.setValue(36)

        self.film_back_height_spinbox = QtWidgets.QDoubleSpinBox()
        self.film_back_height_spinbox.setRange(1, 500)
        self.film_back_height_spinbox.setValue(24)

        # UI elements for gate mask settings
        self.gate_mask_label = QtWidgets.QLabel("Gate Mask:")
        self.gate_mask_top_spinbox = QtWidgets.QDoubleSpinBox()
        self.gate_mask_top_spinbox.setRange(0, 100)
        self.gate_mask_bottom_spinbox = QtWidgets.QDoubleSpinBox()
        self.gate_mask_bottom_spinbox.setRange(0, 100)
        self.gate_mask_left_spinbox = QtWidgets.QDoubleSpinBox()
        self.gate_mask_left_spinbox.setRange(0, 100)
        self.gate_mask_right_spinbox = QtWidgets.QDoubleSpinBox()
        self.gate_mask_right_spinbox.setRange(0, 100)

        # UI elements for camera shake control
        self.camera_shake_label = QtWidgets.QLabel("Camera Shake:")
        self.camera_shake_button = QtWidgets.QPushButton("Enable Shake")
        self.camera_shake_slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.camera_shake_slider.setRange(0, 100)
        self.camera_shake_slider.setValue(0)

        # Button to create the camera rig
        self.create_rig_button = QtWidgets.QPushButton("Create Rig")
        self.create_rig_button.clicked.connect(self.create_camera_rig)

    def create_layout(self):
        layout = QtWidgets.QVBoxLayout()

        # Camera name layout
        camera_name_layout = QtWidgets.QHBoxLayout()
        camera_name_layout.addWidget(self.camera_name_label)
        camera_name_layout.addWidget(self.camera_name_lineedit)
        layout.addLayout(camera_name_layout)

        # Film back layout
        film_back_layout = QtWidgets.QHBoxLayout()
        film_back_layout.addWidget(self.film_back_label)
        film_back_layout.addWidget(self.film_back_width_spinbox)
        film_back_layout.addWidget(self.film_back_height_spinbox)
        layout.addLayout(film_back_layout)

        # Gate mask layout
        gate_mask_layout = QtWidgets.QHBoxLayout()
        gate_mask_layout.addWidget(self.gate_mask_label)
        gate_mask_layout.addWidget(self.gate_mask_top_spinbox)
        gate_mask_layout.addWidget(self.gate_mask_bottom_spinbox)
        gate_mask_layout.addWidget(self.gate_mask_left_spinbox)
        gate_mask_layout.addWidget(self.gate_mask_right_spinbox)
        layout.addLayout(gate_mask_layout)

        # Camera shake layout
        camera_shake_layout = QtWidgets.QHBoxLayout()
        camera_shake_layout.addWidget(self.camera_shake_label)
        camera_shake_layout.addWidget(self.camera_shake_button)
        camera_shake_layout.addWidget(self.camera_shake_slider)
        layout.addLayout(camera_shake_layout)

        layout.addWidget(self.create_rig_button)

        self.setLayout(layout)

    def create_camera_rig(self):
        # Get the camera name from the user input
        camera_name = self.camera_name_lineedit.text()

        # Check if the camera with the provided name exists in the scene
        if not cmds.objExists(camera_name):
            cmds.warning("Camera '{}' does not exist!".format(camera_name))
            return

        # Create a new camera rig group to hold the camera and its controller
        rig_group = cmds.group(empty=True, name="{}_rig".format(camera_name))

        # Parent the camera under the rig group
        cmds.parent(camera_name, rig_group)

        # Create a controller (a circle shape) for the camera
        controller = cmds.circle(normal=[0, 1, 0], radius=5, name="{}_ctrl".format(camera_name))[0]

        # Position the controller above the camera
        camera_position = cmds.xform(camera_name, query=True, worldSpace=True, translation=True)
        cmds.xform(controller, worldSpace=True, translation=[camera_position[0], camera_position[1] + 10, camera_position[2]])

        # Parent the camera under the controller
        cmds.parent(camera_name, controller)

        # Create an attribute on the controller to control the camera's focal length
        cmds.addAttr(controller, longName="focalLength", attributeType="double", defaultValue=35, keyable=True)

        # Connect the controller's focalLength attribute to the camera's focal length attribute
        cmds.connectAttr("{}.focalLength".format(controller), "{}.focalLength".format(camera_name))

        # Get film back width and height values from the UI
        film_back_width = self.film_back_width_spinbox.value()
        film_back_height = self.film_back_height_spinbox.value()

        # Add attributes for film back width and height on the controller
        cmds.addAttr(controller, longName="filmBackWidth", attributeType="double", defaultValue=film_back_width, keyable=True)
        cmds.addAttr(controller, longName="filmBackHeight", attributeType="double", defaultValue=film_back_height, keyable=True)

        # Set up the camera's film back size based on the controller's attributes
        cmds.setAttr("{}.horizontalFilmAperture".format(camera_name), lock=False)
        cmds.setAttr("{}.verticalFilmAperture".format(camera_name), lock=False)
        cmds.connectAttr("{}.filmBackWidth".format(controller), "{}.horizontalFilmAperture".format(camera_name))
        cmds.connectAttr("{}.filmBackHeight".format(controller), "{}.verticalFilmAperture".format(camera_name))
        cmds.setAttr("{}.horizontalFilmAperture".format(camera_name), lock=True)
        cmds.setAttr("{}.verticalFilmAperture".format(camera_name), lock=True)

        # Get gate mask values from the UI
        gate_mask_top = self.gate_mask_top_spinbox.value()
        gate_mask_bottom = self.gate_mask_bottom_spinbox.value()
        
# Show the UI
ui = CameraRiggingToolUI()
ui.show()