import os,sys, math, winreg
import RLPy
from PySide2 import QtWidgets
from PySide2.QtCore import Qt
from PySide2.QtCore import QTimer
from shiboken2 import wrapInstance

#Programmed by Tesira

try:
    # 1. Wir öffnen den exakten, offiziellen iClone 8 Registry-Schlüssel
    hKey = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Reallusion\iClone\8.0")
    
    # 2. iClone 8 speichert den Standard-Pfad unter dem Wert "Template Data"
    raw_path = winreg.QueryValueEx(hKey, "Template Data")[0]
    ic_template_path = os.path.abspath(raw_path)
    
    print("--------------------------------------------------")
    print(f"Dein iClone 8 Template-Pfad lautet:")
    print(ic_template_path)
    print("--------------------------------------------------")

except Exception as e:
    print("--------------------------------------------------")
    print(f"Registry-Abfrage fehlgeschlagen: {e}")
    # Sicherheits-Fallback, falls die Registry blockiert ist:
    ic_template_path = r"C:\Users\Public\Documents\Reallusion\Reallusion Templates"
    print(f"Nutze Standard-Fallback: {ic_template_path}")
    print("--------------------------------------------------")

rl_plugin_info = None
ap_version=RLPy.RApplication.GetProductVersion()[0]

if ap_version == 8:
    rl_plugin_info = {"ap": "iClone", "ap_version": "8.0"}

my_template_path = "your template path" 

scalewa=1.0
scalewo=1.0
scalebe=1.0


# update of the high and scale of the selected prop  __________________________________________________________________________________________________________
def update_scale_high(parameter, value):
    print("scale and high")

def cloudini1(j): 
    print("cloudini")

def waterini(j): 
    print("waterini")

def waterini2(j): 
    print("waterini2")

def skyini(j): 
    print("skyini")

def clear_script_props():
    print("Script Log: Starte radikale Szene-Reinigung...")
    
    # Eine Liste mit den exakten Namen all deiner Props
    props_to_remove = ["Water1", "Water1_0", "Wolke1", "Wolke2", "Beach1"]
    
    # Erst die Timeline stoppen, falls sie noch läuft (Stresstest-Sicherung!)
    if RLPy.RGlobal.IsPlaying():
        RLPy.RGlobal.Stop()
    
    # Auf Frame 0 zurücksetzen für die saubere Leere
    RLPy.RGlobal.SetTime(RLPy.RTime.FromValue(0))
    
    # Schleife rennt durch die Namen und löscht die Objekte nacheinander aus der Szene
    for prop_name in props_to_remove:
        prop = RLPy.RScene.FindObject(RLPy.EObjectType_Prop, prop_name)
        if prop:
            RLPy.RScene.RemoveObject(prop) # Das offizielle iClone-Löschkommando [INDEX]
            print(f"Script Log: '{prop_name}' erfolgreich entfernt.")
            
    # iClone zwingen, den Viewport und den Scene-Manager sofort komplett neu zu zeichnen
    RLPy.RGlobal.ObjectModified(None, RLPy.EObjectModifiedType_Global)
    print("Script Log: Szene ist wieder blitzblank!")
   
def finde_projekt_im_inventory(projekt_name):
    print(f"Script Log: Suche im Inventory nach: {projekt_name}")
    
    global ic_template_path 
    
    print(f"Script Log: Nutze globalen Basis-Pfad für die Suche...")
    
    try:
        # 1. Wir gehen vom Template-Pfad einen Ordner höher (zurück zu ".../Reallusion")
        reallusion_haupt_ordner = os.path.dirname(ic_template_path)
        
        # 2. Wir steuern direkt deinen Custom-Projektordner an
        # (Standard-Struktur: Reallusion \ Custom \ iClone 8 Custom \ Project)
        projekt_basis_ordner = os.path.join(
            reallusion_haupt_ordner, 
            "Reallusion Custom", 
            "Project","IC Project"
        )
        
        # 3. Den vollen Pfad zur gewünschten .iProject-Datei zusammenbauen
        voller_datei_pfad = os.path.join(projekt_basis_ordner, f"{projekt_name}.iProject")
        
        # 4. Prüfen, ob die Datei dort wirklich existiert
        if os.path.exists(voller_datei_pfad):
            print(f"Script Log: Projekt erfolgreich gefunden: {voller_datei_pfad}")
            return voller_datei_pfad
        else:
            print(f"Script Log: Datei nicht gefunden unter: {voller_datei_pfad}")
            return None
            
    except Exception as e:
        print(f"Script Log: Fehler bei der Pfad-Berechnung: {e}")
        return None
       
def alles_neu():
   
    finde_projekt_im_inventory("waves")
    projekt_pfad = finde_projekt_im_inventory("waves")

    # 2. Nur wenn der Pfad gültig ist, laden wir die Szene scharf
    if projekt_pfad:
        print(f"Script Log: LADE PROJEKT JETZT SCHARF: {projekt_pfad}")
    
    # Stresstest-Sicherung: Timeline stoppen und auf 0 setzen
    if RLPy.RGlobal.IsPlaying():
        RLPy.RGlobal.Stop()
    RLPy.RGlobal.SetTime(RLPy.RTime.FromValue(0))
    
    # DER ECHTE LADEBEFEHL FÜR ICLONE 8:
    RLPy.RFileIO.LoadFile(projekt_pfad)
    

alles_neu()
#Video Rendern
RLPy.RGlobal.RenderVideo()

class HauptSteuerungWindow(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        
        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)
        
        layout.addWidget(QtWidgets.QLabel("<b>upper Water</b>"))
        
        # Das Dropdown für deine Wasser-Presets
        self.dropdown_wasser = QtWidgets.QComboBox()
        self.dropdown_wasser.addItem("Water 0: Stormy Ocean")
        self.dropdown_wasser.addItem("Water 1: Stormy Ocean 2")
        self.dropdown_wasser.addItem("Water 2: Calm Sea")
        self.dropdown_wasser.addItem("Water 3: Foamy Waves")
        self.dropdown_wasser.addItem("Water 4: High Waves")    
        self.dropdown_wasser.addItem("Water 5: Light Waves")   
        self.dropdown_wasser.addItem("Water 6: Wave Crests")   
        self.dropdown_wasser.addItem("Water 7: Choppy Sea")    
 # Connects the click directly to your function (using the lambda trick for VS)
        self.dropdown_wasser.currentIndexChanged.connect(lambda index: waterini(index))
        layout.addWidget(self.dropdown_wasser)
        # Verbindet den Klick direkt mit deiner Funktion (Verwendet den Lambda-Trick für VS)
        self.dropdown_wasser.currentIndexChanged.connect(lambda index: waterini(index))
        layout.addWidget(self.dropdown_wasser)

        layout.addWidget(QtWidgets.QLabel("<b>under Water</b>"))
        self.dropdown_wasser2 = QtWidgets.QComboBox()
        self.dropdown_wasser2.addItem("Water 0: Stormy Ocean")
        self.dropdown_wasser2.addItem("Water 1: Stormy Ocean 2")
        self.dropdown_wasser2.addItem("Water 2: Calm Sea")
        self.dropdown_wasser2.addItem("Water 3: Foamy Waves")
        self.dropdown_wasser2.addItem("Water 4: High Waves")    
        self.dropdown_wasser2.addItem("Water 5: Light Waves")   
        self.dropdown_wasser2.addItem("Water 6: Wave Crests")   
        self.dropdown_wasser2.addItem("Water 7: Choppy Sea")     

        # Verbindet den Klick direkt mit deiner Funktion (Verwendet den Lambda-Trick für VS)
        self.dropdown_wasser2.currentIndexChanged.connect(lambda index: waterini2(index))
        layout.addWidget(self.dropdown_wasser2)

        layout.addWidget(QtWidgets.QLabel("<b>Sky</b>"))
        self.dropdown_sky = QtWidgets.QComboBox()
        self.dropdown_sky.addItem("Sky 0: Sky_01")
        self.dropdown_sky.addItem("Sky 1: Night")
        self.dropdown_sky.addItem("Sky 1: Sky_03")
        self.dropdown_sky.addItem("Sky 3: Cloudy")
        self.dropdown_sky.addItem("Sky 4: Red Sky")
        self.dropdown_sky.addItem("Sky 5: Sunset")  

        # Verbindet den Klick direkt mit deiner Funktion 
        self.dropdown_sky.currentIndexChanged.connect(lambda index: skyini(index))
        layout.addWidget(self.dropdown_sky)

        layout.addWidget(QtWidgets.QLabel("Scale"))

        # Scale Slider und SpinBox erstellen __________________________________________________________________________
        self.slider_scale = QtWidgets.QSlider(orientation=Qt.Horizontal, singleStep=1, maximum=1000, minimum=1)
        self.double_spinBox_scale = QtWidgets.QDoubleSpinBox(singleStep=1, decimals=2, maximum=1000, minimum=1)

        # Startwert setzen (scalewa * 100)
        self.slider_scale.setValue(int(scalewa * 100))
        self.double_spinBox_scale.setValue(scalewa * 100)

        # Die beiden Elemente synchronisieren
        self.double_spinBox_scale.valueChanged.connect(lambda val: self.slider_scale.setValue(int(val)))
        self.slider_scale.valueChanged.connect(lambda val: self.double_spinBox_scale.setValue(val))
        self.slider_scale.valueChanged.connect(lambda val: update_scale_high("Scale", val))

        layout.addWidget(self.slider_scale)
        layout.addWidget(self.double_spinBox_scale)

  

        # alles wird gelöscht__________________________________________________________________________________________
        self.btn_clear = QtWidgets.QPushButton("Clear All Script Props")

        # Verbindet den Klick direkt mit der Lösch-Funktion da oben (Lambda-Trick für VS)
        self.btn_clear.clicked.connect(lambda: clear_script_props())
        layout.addWidget(self.btn_clear)

        #alles neu__________________________________________________________________________________________________
        self.btn_neu = QtWidgets.QPushButton("Load All Script Props")
        # Verbindet den Klick direkt mit der Lösch-Funktion da oben (Lambda-Trick für VS)
        self.btn_neu.clicked.connect(lambda: alles_neu())
        layout.addWidget(self.btn_neu)


        






    def closeEvent(self, event):
        # Wir erzwingen die Ausgabe ganz am Anfang, bevor Qt aufräumt
        print("--------------------------------------------------")
        print("Speicher wird befreit!")
        print("--------------------------------------------------")
        # Wir kappen beim manuellen Schließen nur kurz die Verbindung
        try:
            self.dropdown_wasser.currentIndexChanged.disconnect()
        except:
            pass
        try:
            self.dropdown_wasser2.currentIndexChanged.disconnect()
        except:
            pass
        try:
            self.dropdown_sky.currentIndexChanged.disconnect()
        except:
            pass
        self.setParent(None)
        self.deleteLater()
        event.accept()

# ------------------------------------------------------------------
# Startblock: Alte Qt-Boxen vor dem Neustart entfernen
# ------------------------------------------------------------------
for widget in QtWidgets.QApplication.topLevelWidgets():
    if isinstance(widget, QtWidgets.QDockWidget) and widget.windowTitle() == "Wave Control Main":
        widget.close()
        widget.deleteLater()

# Neue Box erstellen
dockable_window = RLPy.RUi.CreateRDockWidget()
dockable_window.SetWindowTitle("Wave Control Main")

dock = wrapInstance(int(dockable_window.GetWindow()), QtWidgets.QDockWidget)
mein_steuer_pult = HauptSteuerungWindow()
dock.setWidget(mein_steuer_pult)
dock.setFixedWidth(280)

dockable_window.Show()
