use url::Url;

use crate::{
    NodeId, PixelCoordinate, PixelDimension,
    color::Color,
    node::{GenericNode, GenericNodeInfo},
};

/// A link node.
#[derive(
    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
)]
pub struct LinkNode {
    #[serde(flatten)]
    generic: GenericNode,
    url: Url,
}

impl LinkNode {
    /// Creates a new [`LinkNode`].
    #[must_use]
    pub const fn new(
        id: NodeId,
        x: PixelCoordinate,
        y: PixelCoordinate,
        width: PixelDimension,
        height: PixelDimension,
        color: Option<Color>,
        url: Url,
    ) -> Self {
        Self {
            generic: GenericNode::new(id, x, y, width, height, color),
            url,
        }
    }

    /// Returns a reference to the url of this [`LinkNode`].
    #[must_use]
    pub const fn url(&self) -> &Url {
        &self.url
    }
}

impl GenericNodeInfo for LinkNode {
    fn id(&self) -> &NodeId {
        self.generic.id()
    }

    fn x(&self) -> PixelCoordinate {
        self.generic.x()
    }

    fn y(&self) -> PixelCoordinate {
        self.generic.y()
    }

    fn width(&self) -> PixelDimension {
        self.generic.width()
    }

    fn height(&self) -> PixelDimension {
        self.generic.height()
    }

    fn color(&self) -> &Option<Color> {
        self.generic.color()
    }
}
