use godot::prelude::*;
use godot::engine::{Node, NodeVirtual, Texture};
use crate::metadata::VideoMetadata;

mod metadata;
mod playback;

struct Main;

#[gdextension]
unsafe impl ExtensionLibrary for Main {}


// A Video Player Node.
#[derive(GodotClass)]
#[class(base=Node)]
struct VideoPlayer {
    metadata : Option<VideoMetadata>,

    #[export(get = get_has_video)]
    has_video: bool,
    #[export(get = get_has_audio)]
    has_audio: bool,
    #[export(get = get_duration)]
    duration: i64,

    #[base]
    base: Base<Node>
}

#[godot_api]
impl NodeVirtual for VideoPlayer {
    //fn init(base: Base<Node>) -> Self {
    fn init(base: Base<Node>) -> Self {
        Self {
            metadata: None,
            has_video: false,
            has_audio: false,
            duration: -1,
            base
        }
    }
}

#[godot_api]
impl VideoPlayer {

    /// Load a video file from `path`.
    /// Return true if successfully loaded else false.
    #[func]
    fn load_file(&mut self, path : GodotString) -> bool {
        if let Ok(m) = VideoMetadata::get_metadata(path.to_string().as_str()) {
            self.metadata = Some(m);
            return true
        }
        false
    }

    /// Return the version string for ffmepg
    #[func]
    fn ffmpeg_version(&mut self) -> GodotString {
        VideoMetadata::get_version().into()
    }

    /// Return the license string for ffmepg
    #[func]
    fn ffmpeg_license(&mut self) -> GodotString {
        VideoMetadata::get_license().into()
    }

    /// Return true if audio stream is loaded
    #[func]
    fn get_has_audio(&self) -> bool {
        false
    }

    /// Return true if video stream is loaded
    #[func]
    fn get_has_video(&self) -> bool {
        if let Some(_) =  &self.metadata {
            return true
        }
        false
    }

    /// Return the duration en micro second of the video or -1 if no video is loaded
    #[func]
    fn get_duration(&self) -> i64 {
        if let  Some(m) = &self.metadata {
            return m.duration
        }
        -1
    }


    /// Return the duration en micro second of the video or -1 if no video is loaded
    #[func]
    fn get_texture(&self) -> Gd<Texture>{
        todo!()
    }
}
