#!/usr/bin/env python3
import sys
import os

from PyQt5.QtWidgets import (
    QApplication,
    QWidget,
    QVBoxLayout,
    QLabel,
    QTextEdit,
    QPushButton,
    QMessageBox,
)
from PyQt5.QtCore import Qt


class BspChecker(QWidget):
    def __init__(self):
        super().__init__()
        self.results = []
        self.initUI()

    def initUI(self):
        self.setWindowTitle("BSP Checker")
        self.setAcceptDrops(True)
        layout = QVBoxLayout()

        instructions = QLabel(
            "Drag and drop .bsp files into this window.\n"
            "Files whose 5th byte (offset 0x00000004) is not 0x26 will be listed.\n"
            "Additional annotations will be added for specific hex values."
        )
        instructions.setWordWrap(True)
        layout.addWidget(instructions)

        self.textEdit = QTextEdit()
        self.textEdit.setReadOnly(True)
        layout.addWidget(self.textEdit)

        self.copyButton = QPushButton("Copy List to Clipboard")
        self.copyButton.clicked.connect(self.copyToClipboard)
        layout.addWidget(self.copyButton)

        self.setLayout(layout)
        self.resize(500, 400)

    def dragEnterEvent(self, event):
        # Accept the drag event if it contains URLs (file paths)
        if event.mimeData().hasUrls():
            event.acceptProposedAction()

    def dropEvent(self, event):
        # Retrieve the list of file paths dropped into the window.
        files = [url.toLocalFile() for url in event.mimeData().urls()]
        self.processFiles(files)

    def processFiles(self, files):
        self.results = []  # Reset list for new drops
        for file in files:
            if not file.lower().endswith(".bsp"):
                # Skip files that don't have a .bsp extension.
                continue

            # Ensure the file exists.
            if not os.path.exists(file):
                self.results.append(f"{file} - File not found")
                continue

            try:
                with open(file, "rb") as f:
                    data = f.read(5)
            except Exception as e:
                self.results.append(f"{file} - Error reading file: {str(e)}")
                continue

            if len(data) < 5:
                self.results.append(f"{file} - File too short")
                continue

            # The 5th byte is at index 4.
            fifth_byte = data[4]

            # If the byte is exactly 0x26, we skip this file.
            if fifth_byte == 0x26:
                continue

            # Determine annotation based on the 5th byte.
            annotation = ""
            if fifth_byte == 0x2E:
                annotation = " (Quake3, STVEF, or NExuiz)"
            elif fifth_byte == 0x29:
                annotation = " (Daikatana)"
            elif fifth_byte == 0x2F:
                annotation = " (RTCW)"

            # Add the file (with annotation if applicable) to the results.
            self.results.append(f"{file}{annotation}")

        # Update the text area with the list of results.
        if self.results:
            self.textEdit.setPlainText("\n".join(self.results))
        else:
            self.textEdit.setPlainText("All files have the expected hex value (0x26).")

    def copyToClipboard(self):
        clipboard = QApplication.clipboard()
        clipboard.setText(self.textEdit.toPlainText())
        QMessageBox.information(self, "Copied", "The list has been copied to the clipboard.")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = BspChecker()
    window.show()
    sys.exit(app.exec_())
