use godot::prelude::*;
use godot::global::Key;
use godot::classes::{AudioStreamOggVorbis, Engine, InputEvent, InputEventKey};

#[derive(GodotClass)]
#[class(base=Node)]
struct Manager {
    #[export(file = "*.ogg")]
    bgm: GString,
    #[var]
    beat_count: i32,
    #[var]
    scenes: Array<Gd<PackedScene>>,
    current_scene: Option<i32>,
    instanced_scenes: Vec<Gd<Node>>,
    base: Base<Node>
}

#[godot_api]
impl INode for Manager {
    fn init(base: Base<Node>) -> Self {
        Self {
            bgm: GString::from(""),
            beat_count: 0,
            scenes: Array::new(),
            current_scene: None,
            instanced_scenes: Vec::new(),
            base,
        }
    }

    fn unhandled_input(&mut self, event: Gd<InputEvent>) {
        if event.is_released() {
            if let Ok(key) = event.clone().try_cast::<InputEventKey>() {
                if key.get_keycode() == Key::ESCAPE {
                    godot_print!("Goodbye!");
                    self.base_mut().get_tree().unwrap().quit();
                }
            }
        }
    }
}

#[godot_api]
impl Manager {
    #[func]
    fn set_scene(&mut self, number: i32) {
        let current_scene = self.current_scene;

        let scene = self.instanced_scenes[number as usize].clone(); // Memory leak??? Idk
        self.current_scene = Some(self.instanced_scenes[number as usize].get_index());
        let node: Option<Gd<Node>>;
        match current_scene {
            Some(_) => {
                node = self.base_mut().get_child(current_scene.unwrap());
                match node {
                    Some(value) => {
                        value.upcast::<Node>().queue_free();
                    }
                    None => {}
                };
            }
            None => {}
        }
        self.base_mut().add_child(scene);
    }

    #[func]
    fn register_scene(&mut self, scene: Gd<PackedScene>) {
        self.instanced_scenes.push(scene.instantiate_as())
    }

    #[func]
    fn start_audio(&mut self) {
        let editor_hint = Engine::singleton().is_editor_hint();
        if !editor_hint {
            let bgm = self.bgm.clone();
            let mut stream: Gd<AudioStreamOggVorbis> = load(bgm);
            stream.set_loop(false);
            let mut player = AudioStreamPlayer::new_alloc();
            player.set_stream(stream);
            player.set_autoplay(true);
            self.base_mut().add_child(player);
        }
    }
}