// This file is part of Poezio.
//
// Poezio is free software: you can redistribute it and/or modify
// it under the terms of the GPL-3.0-or-later license. See the COPYING file.

use gtk::gdk;
use gtk::glib;
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use std::cell::RefCell;
use std::path::Path;
use std::sync::LazyLock;

#[derive(Debug, Default)]
pub struct Sticker {
    filename: RefCell<Option<String>>,
    texture: RefCell<Option<gdk::Texture>>,
}

#[glib::object_subclass]
impl ObjectSubclass for Sticker {
    const NAME: &'static str = "Sticker";
    type Type = StickerType;
}

impl ObjectImpl for Sticker {
    fn properties() -> &'static [glib::ParamSpec] {
        static PROPERTIES: LazyLock<Vec<glib::ParamSpec>> = LazyLock::new(|| {
            vec![
                glib::ParamSpecString::builder("filename")
                    .nick("Filename")
                    .blurb("Filename")
                    .readwrite()
                    .construct_only()
                    .build(),
                glib::ParamSpecObject::builder::<gdk::Texture>("texture")
                    .nick("Texture")
                    .blurb("Texture")
                    .readwrite()
                    .construct_only()
                    .build(),
            ]
        });
        PROPERTIES.as_ref()
    }

    fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
        match pspec.name() {
            "filename" => {
                let filename = value.get().unwrap();
                self.filename.replace(filename);
            }
            "texture" => {
                let texture = value.get().unwrap();
                self.texture.replace(texture);
            }
            _ => unimplemented!(),
        }
    }

    fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
        match pspec.name() {
            "filename" => self.filename.borrow().to_value(),
            "texture" => self.texture.borrow().to_value(),
            _ => unimplemented!(),
        }
    }
}

glib::wrapper! {
    pub struct StickerType(ObjectSubclass<Sticker>);
}

impl StickerType {
    pub fn new(filename: String, path: &Path) -> StickerType {
        let texture = gdk::Texture::from_filename(path).unwrap();
        glib::Object::builder::<StickerType>()
            .property("filename", &filename)
            .property("texture", &texture)
            .build()
    }

    pub fn filename(&self) -> Option<String> {
        let imp = self.imp();
        let filename = imp.filename.borrow();
        if let Some(filename) = filename.as_ref() {
            Some(filename.clone())
        } else {
            None
        }
    }

    pub fn texture(&self) -> Option<gdk::Texture> {
        let imp = self.imp();
        let texture = imp.texture.borrow();
        if let Some(texture) = texture.as_ref() {
            Some(texture.clone())
        } else {
            None
        }
    }
}
