import sys
from PySide6.QtOpenGLWidgets import QOpenGLWidget
from PySide6.QtWidgets import (QApplication, QMainWindow, QHBoxLayout, QVBoxLayout, QWidget, QPushButton, QGroupBox,
                               QTextEdit, QSizePolicy)
from PySide6.QtCore import QSize, Qt, QPoint
from OpenGL.GL import *
from OpenGL.GLU import *
from stl import mesh


class OpenGLWidget(QOpenGLWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.stl_file = "out.stl"  # Replace with your STL file path
        self.lastPos = QPoint()
        self.xRot = 0
        self.yRot = 0
        self.zoom = -10.0

    def load_stl(self, filename):
        try:
            stl_mesh = mesh.Mesh.from_file(filename)
            return stl_mesh.vectors
        except FileNotFoundError:
            print(f"Error: File {filename} not found.")
        except Exception as e:
            print(f"Error loading {filename}: {e}")
        return []

    def initializeGL(self):
        glClearColor(0, 0, 0, 1)
        glEnable(GL_DEPTH_TEST)

    def resizeGL(self, w, h):
        glViewport(0, 0, w, h)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluPerspective(45, w/h, 0.1, 100.0)
        glMatrixMode(GL_MODELVIEW)

    def paintGL(self):
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()
        glTranslatef(0.0, 0.0, self.zoom)
        glRotatef(self.xRot, 1.0, 0.0, 0.0)
        glRotatef(self.yRot, 0.0, 1.0, 0.0)
        glColor3f(1.0, 1.0, 1.0)

        mesh_data = self.load_stl(self.stl_file)
        if mesh_data.any():
            self.draw_stl(mesh_data)

    def draw_stl(self, vertices):
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_COLOR_MATERIAL)
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)

        glLightfv(GL_LIGHT0, GL_POSITION, (0, 1, 1, 0))
        glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.6, 0.6, 0.6, 0.6))

        glBegin(GL_TRIANGLES)
        for triangle in vertices:
            for vertex in triangle:
                glVertex3fv(vertex)
        glEnd()

        # Draw outer vertices as points
        glDisable(GL_LIGHTING)
        glColor3f(1.0, 0.0, 0.0)  # Set color to red
        glPointSize(5.0)  # Set point size
        glBegin(GL_POINTS)
        for triangle in vertices:
            for vertex in triangle:
                glVertex3fv(vertex)
        glEnd()

    def mousePressEvent(self, event):
        self.lastPos = event.pos()

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.xRot += 0.5 * dy
            self.yRot += 0.5 * dx
            self.update()

        self.lastPos = event.pos()

    def wheelEvent(self, event):
        delta = event.angleDelta().y()
        self.zoom += delta / 120
        self.update()


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("fluencyCAD")
        self.height = 1080
        self.width = 1920
        self.setFixedSize(QSize(self.width, self.height))

        # Main central widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        layout = QHBoxLayout(central_widget)

        # Left tools area
        left_tools_layout = QVBoxLayout()

        self.left_tools = QGroupBox("Left Tools")
        self.left_tools.setFixedSize(100, self.height)

        self.draw_rectangle = QPushButton("Draw Rectangle")
        self.draw_rectangle.setFixedSize(80, 30)
        left_tools_layout.addWidget(self.draw_rectangle)

        self.draw_rectangle = QPushButton("Draw Rectangle2")
        self.draw_rectangle.setFixedSize(80, 30)
        left_tools_layout.addWidget(self.draw_rectangle)  # Align the button to the top

        self.draw_rectangle = QPushButton("Draw Rectangle3")
        self.draw_rectangle.setFixedSize(80, 30)
        left_tools_layout.addWidget(self.draw_rectangle)

        self.left_tools.setLayout(left_tools_layout)
        self.left_tools.setAlignment(Qt.AlignTop)
        layout.addWidget(self.left_tools)

        # Center OpenGL widget and QTextEdit
        center_layout = QVBoxLayout()

        self.openGLWidget = OpenGLWidget()
        center_layout.addWidget(self.openGLWidget)
        self.openGLWidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.enter_code = QTextEdit()
        self.enter_code.setFixedSize(QSize(self.width, self.height // 4))
        center_layout.addWidget(self.enter_code)

        self.code_tools = QGroupBox("Code Tools")
        self.code_tools.setFixedSize(QSize(self.width, self.height // 18))

        code_tools_layout = QHBoxLayout()  # Layout for code tools

        self.apply_code = QPushButton("Apply Code")  # Creating QPushButton
        self.apply_code.setFixedSize(80,30)

        code_tools_layout.addWidget(self.apply_code)  # Adding QPushButton to QHBoxLayout

        self.code_tools.setLayout(code_tools_layout)  # Setting QHBoxLayout to QGroupBox
        self.code_tools.setAlignment(Qt.AlignLeft)

        center_layout.addWidget(self.code_tools)  # Adding QGroupBox to the center layout

        layout.addLayout(center_layout)  # Adding center layout to the main layout


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())