import sys

from Map import Map
from CarController import CarController

from PySide6.QtWidgets import QFileDialog, QToolBox
from PySide6.QtCore import QElapsedTimer, QTimer, QElapsedTimer, QObject, Signal, Slot, QThread, QMutex, Qt

class mainLoop(QObject):
    updateFPS = Signal(int)
    mutex = QMutex()

    qlPresets = {
            Qt.Key_0 : ["comp_inter.net.xml", "comp_inter.rou.xml"],
            Qt.Key_1 : ["comp_inter.net.xml", "comp_inter_t2.rou.xml"],
            Qt.Key_2 : ["comp_rdp.net.xml", "comp_rdp.rou.xml"],
            Qt.Key_3 : ["comp_rdp.net.xml", "comp_rdp_t3.rou.xml"],
            Qt.Key_4 : ["rdpt_polytech_fixed.net.xml", "rdpt_polytech_burst.rou.xml"],
            Qt.Key_5 : ["rdpt_polytech_fixed.net.xml", "rdpt_polytech_burst_2.rou.xml"],
            Qt.Key_6 : ["rdpt_polytech_fixed.net.xml", "rdpt_polytech_burst_2_IA.rou.xml"]
            }
    
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.painter = parent.ui.mainSurf

        self.map = Map()

        self.controller = CarController(self.map)
        self.controller.addParent(parent)

        self.painter.addMap(self.map)
        self.painter.addCarController(self.controller)
        
        self.timer = None

        self.fpsTimer = QElapsedTimer()
        self.updateFPS.connect(self.parent.updatePhysicsFps)

        self.fpsAverage = 0
    
    def threadSafe(func):
        def inner(*args, **kwargs):
            args[0].mutex.lock()
            func(*args, **kwargs)
            args[0].mutex.unlock()
        return inner

    def start(self):
        self.fpsTimer.start()
        
        self.timer = QTimer()
        self.timer.timeout.connect(self.updateFps)
        self.timer.timeout.connect(self.update)
        self.timer.setInterval(1000/60)
        #self.stopSignal.connect(self.timer.stop)

    def startTimer(self):
        self.timer.start()

    def stopTimer(self):
        self.timer.stop()

    def setTimerInterval(self,t):
        self.timer.setInterval(t)

    def quit(self):
        super().quit()
        self.timer.stop()

    @threadSafe
    def update(self):
        try:
            self.controller.update()
            if self.controller.t > 3600:
                self.stopTimer()
        except:
            (type, value, traceback) = sys.exc_info()
            print(type, value, traceback.print_tb())
    
    @threadSafe
    def openNetwork(self, filename):
        if filename == '':
            return
        self.map.fromPath(filename)
        self.painter.generateTransform()

        self.controller.prepareRoute()

    @threadSafe
    def openVehicles(self, filename):
        if filename == '':
            return
        self.controller.fromPath(filename)
        if self.map.isLoaded():
            self.controller.prepareRoute()
    
    @threadSafe
    def quickLoad(self, key):
        paths = self.qlPresets.get(key)
        if paths == None:
            return
        self.map.fromPath(paths[0])
        self.painter.generateTransform()
        self.controller.fromPath(paths[1])
        self.controller.prepareRoute()

    def updateFps(self):
        self.fpsAverage += 1
        if(self.fpsAverage == 32):
            newFps = self.fpsTimer.restart()
            self.updateFPS.emit(newFps/32)
            self.fpsAverage = 0

