// Generated from WebIDL - DO NOT EDIT
// Source: @webref/idl/notifications

///|
/// NotificationPermission enum
pub(all) enum NotificationPermission {
  Default
  Denied
  Granted
} derive(Eq, Show)

///|
/// Convert to string value
pub fn NotificationPermission::to_string(
  self : NotificationPermission,
) -> String {
  match self {
    NotificationPermission::Default => "default"
    NotificationPermission::Denied => "denied"
    NotificationPermission::Granted => "granted"
  }
}

///|
/// Parse from string value
pub fn NotificationPermission::from_string(
  s : String,
) -> NotificationPermission? {
  match s {
    "default" => Some(NotificationPermission::Default)
    "denied" => Some(NotificationPermission::Denied)
    "granted" => Some(NotificationPermission::Granted)
    _ => None
  }
}

///|
/// NotificationDirection enum
pub(all) enum NotificationDirection {
  Auto
  Ltr
  Rtl
} derive(Eq, Show)

///|
/// Convert to string value
pub fn NotificationDirection::to_string(self : NotificationDirection) -> String {
  match self {
    NotificationDirection::Auto => "auto"
    NotificationDirection::Ltr => "ltr"
    NotificationDirection::Rtl => "rtl"
  }
}

///|
/// Parse from string value
pub fn NotificationDirection::from_string(s : String) -> NotificationDirection? {
  match s {
    "auto" => Some(NotificationDirection::Auto)
    "ltr" => Some(NotificationDirection::Ltr)
    "rtl" => Some(NotificationDirection::Rtl)
    _ => None
  }
}

///|
/// NotificationPermissionCallback callback interface
pub type NotificationPermissionCallback

///|
/// Create NotificationPermissionCallback from a MoonBit function
pub extern "js" fn NotificationPermissionCallback::from_fn(
  handler : (NotificationPermission) -> Unit,
) -> NotificationPermissionCallback =
  #| (handler) => (a0) => handler(a0)

///|
/// NotificationOptions dictionary
pub(all) struct NotificationOptions {
  dir : NotificationDirection?
  lang : String?
  body : String?
  navigate : String?
  tag : String?
  image : String?
  icon : String?
  badge : String?
  vibrate : VibratePattern?
  timestamp : EpochTimeStamp?
  renotify : Bool?
  silent : Nullable[Bool]
  requireInteraction : Bool?
  data : JsValue?
  actions : Array[NotificationAction]?
}

///|
/// Create a new NotificationOptions with default values
pub fn NotificationOptions::default() -> NotificationOptions {
  NotificationOptions::{
    dir: None,
    lang: None,
    body: None,
    navigate: None,
    tag: None,
    image: None,
    icon: None,
    badge: None,
    vibrate: None,
    timestamp: None,
    renotify: None,
    silent: Nullable::Undefined,
    requireInteraction: None,
    data: None,
    actions: None,
  }
}

///|
extern "js" fn NotificationOptions::to_js_ffi(
  self : NotificationOptions,
) -> JsValue =
  #| (self) => ({
  #|   dir: ((() => { const v = self.dir; if (v === undefined) return undefined; return ['auto', 'ltr', 'rtl'][v]; })()),
  #|   lang: self.lang,
  #|   body: self.body,
  #|   navigate: self.navigate,
  #|   tag: self.tag,
  #|   image: self.image,
  #|   icon: self.icon,
  #|   badge: self.badge,
  #|   vibrate: ((() => { const v = self.vibrate; if (v === undefined || v.$tag !== 1) return undefined; return v._0.to_js_value(); })()),
  #|   timestamp: ((() => { const v = self.timestamp; if (v === undefined || v.$tag !== 1) return undefined; return v._0; })()),
  #|   renotify: (self.renotify === -1 ? undefined : self.renotify),
  #|   silent: ((() => { const v = self.silent; if (v.$tag === 0) return undefined; if (v.$tag === 1) return null; return v._0; })()),
  #|   requireInteraction: (self.requireInteraction === -1 ? undefined : self.requireInteraction),
  #|   data: ((() => { const v = self.data; if (v === undefined || v.$tag !== 1) return undefined; return v._0; })()),
  #|   actions: ((() => { const v = self.actions; if (v === undefined || v.$tag !== 1) return undefined; return v._0; })())
  #| })

///|
/// Convert to JsValue
pub fn NotificationOptions::to_js(self : NotificationOptions) -> JsValue {
  NotificationOptions::to_js_ffi(self)
}

///|
extern "js" fn NotificationOptions::from_js_ffi(
  value : JsValue,
) -> NotificationOptions =
  #| (v) => ({
  #|   dir: (v.dir === undefined ? undefined : ['auto', 'ltr', 'rtl'].indexOf(v.dir)),
  #|   lang: v.lang,
  #|   body: v.body,
  #|   navigate: v.navigate,
  #|   tag: v.tag,
  #|   image: v.image,
  #|   icon: v.icon,
  #|   badge: v.badge,
  #|   vibrate: (v.vibrate === undefined ? { $tag: 0 } : { $tag: 1, _0: v.vibrate }),
  #|   timestamp: (v.timestamp === undefined ? { $tag: 0 } : { $tag: 1, _0: v.timestamp }),
  #|   renotify: (v.renotify === undefined ? -1 : v.renotify),
  #|   silent: (v.silent === undefined ? { $tag: 0 } : v.silent === null ? { $tag: 1 } : { $tag: 2, _0: v.silent }),
  #|   requireInteraction: (v.requireInteraction === undefined ? -1 : v.requireInteraction),
  #|   data: (v.data === undefined ? { $tag: 0 } : { $tag: 1, _0: v.data }),
  #|   actions: (v.actions === undefined ? { $tag: 0 } : { $tag: 1, _0: v.actions })
  #| })

///|
/// Convert from JsValue
pub fn NotificationOptions::from_js(value : JsValue) -> NotificationOptions {
  NotificationOptions::from_js_ffi(value)
}

///|
/// NotificationAction dictionary
pub(all) struct NotificationAction {
  action : String
  title : String
  navigate : String?
  icon : String?
}

///|
/// Create a new NotificationAction with default values
pub fn NotificationAction::default() -> NotificationAction {
  NotificationAction::{ action: "", title: "", navigate: None, icon: None }
}

///|
extern "js" fn NotificationAction::to_js_ffi(
  self : NotificationAction,
) -> JsValue =
  #| (self) => ({
  #|   action: self.action,
  #|   title: self.title,
  #|   navigate: self.navigate,
  #|   icon: self.icon
  #| })

///|
/// Convert to JsValue
pub fn NotificationAction::to_js(self : NotificationAction) -> JsValue {
  NotificationAction::to_js_ffi(self)
}

///|
extern "js" fn NotificationAction::from_js_ffi(
  value : JsValue,
) -> NotificationAction =
  #| (v) => ({
  #|   action: v.action,
  #|   title: v.title,
  #|   navigate: v.navigate,
  #|   icon: v.icon
  #| })

///|
/// Convert from JsValue
pub fn NotificationAction::from_js(value : JsValue) -> NotificationAction {
  NotificationAction::from_js_ffi(value)
}

///|
/// GetNotificationOptions dictionary
pub(all) struct GetNotificationOptions {
  tag : String?
}

///|
/// Create a new GetNotificationOptions with default values
pub fn GetNotificationOptions::default() -> GetNotificationOptions {
  GetNotificationOptions::{ tag: None }
}

///|
extern "js" fn GetNotificationOptions::to_js_ffi(
  self : GetNotificationOptions,
) -> JsValue =
  #| (self) => ({
  #|   tag: self.tag
  #| })

///|
/// Convert to JsValue
pub fn GetNotificationOptions::to_js(self : GetNotificationOptions) -> JsValue {
  GetNotificationOptions::to_js_ffi(self)
}

///|
extern "js" fn GetNotificationOptions::from_js_ffi(
  value : JsValue,
) -> GetNotificationOptions =
  #| (v) => ({
  #|   tag: v.tag
  #| })

///|
/// Convert from JsValue
pub fn GetNotificationOptions::from_js(
  value : JsValue,
) -> GetNotificationOptions {
  GetNotificationOptions::from_js_ffi(value)
}

///|
/// NotificationEventInit dictionary
pub(all) struct NotificationEventInit {
  notification : Notification
  action : String?
}

///|
/// Create a new NotificationEventInit
pub fn NotificationEventInit::new(
  notification~ : Notification,
) -> NotificationEventInit {
  NotificationEventInit::{ notification, action: None }
}

///|
extern "js" fn NotificationEventInit::to_js_ffi(
  self : NotificationEventInit,
) -> JsValue =
  #| (self) => ({
  #|   notification: self.notification,
  #|   action: self.action
  #| })

///|
/// Convert to JsValue
pub fn NotificationEventInit::to_js(self : NotificationEventInit) -> JsValue {
  NotificationEventInit::to_js_ffi(self)
}

///|
extern "js" fn NotificationEventInit::from_js_ffi(
  value : JsValue,
) -> NotificationEventInit =
  #| (v) => ({
  #|   notification: v.notification,
  #|   action: v.action
  #| })

///|
/// Convert from JsValue
pub fn NotificationEventInit::from_js(value : JsValue) -> NotificationEventInit {
  NotificationEventInit::from_js_ffi(value)
}

///|
/// Notification interface
pub type Notification

///|
pub extern "js" fn Notification::to_js_value(self : Notification) -> JsValue =
  #| (self) => self

///|
/// Cast JsValue to Notification (unchecked)
pub extern "js" fn Notification::from_js_value(v : JsValue) -> Notification =
  #| (v) => v

///|
/// Safely cast JsValue to Notification (checked with instanceof)
pub extern "js" fn Notification::from_js_value_opt(
  v : JsValue,
) -> Notification? =
  #| (v) => (v instanceof Notification) ? { $tag: 1, _0: v } : { $tag: 0 }

///|
/// Safely cast JsValue to Notification (checked with instanceof)
pub extern "js" fn JsValue::as_notification(self : JsValue) -> Notification? =
  #| (self) => (self instanceof Notification) ? { $tag: 1, _0: self } : { $tag: 0 }

///|
/// Cast JsValue to Notification (unchecked)
pub extern "js" fn JsValue::to_notification(self : JsValue) -> Notification =
  #| (self) => self

///|
pub extern "js" fn Notification::to_event_target(
  self : Notification,
) -> EventTarget =
  #| (self) => self

///|
/// Error type for throwing methods
pub(all) enum NotificationConstructorError {
  TypeError(JsError)
  DataCloneError(JsError)
  OtherError(JsError)
} derive(Show)

///|
pub extern "js" fn Notification::new(
  title : String,
) -> Result[Notification, NotificationConstructorError] =
  #| (title) => (() => { try { return { $tag: 1, _0: new Notification(title) }; } catch(e) { return { $tag: 0, _0: (() => { const n = (e && e.name) || ''; if (n === 'TypeError') return { $tag: 0, _0: e }; if (n === 'DataCloneError') return { $tag: 1, _0: e }; return { $tag: 2, _0: e }; })() }; } })()

///|
extern "js" fn Notification::new_with_options_ffi(
  title : String,
  options : JsValue,
) -> Result[Notification, NotificationConstructorError] =
  #| (title, options) => (() => { try { return { $tag: 1, _0: new Notification(title, options) }; } catch(e) { return { $tag: 0, _0: (() => { const n = (e && e.name) || ''; if (n === 'TypeError') return { $tag: 0, _0: e }; if (n === 'DataCloneError') return { $tag: 1, _0: e }; return { $tag: 2, _0: e }; })() }; } })()

///|
pub fn Notification::new_with_options(
  title : String,
  options : NotificationOptions,
) -> Result[Notification, NotificationConstructorError] {
  Notification::new_with_options_ffi(title, options.to_js())
}

///|
pub extern "js" fn Notification::get_permission(
  self : Notification,
) -> NotificationPermission =
  #| (self) => ['default', 'denied', 'granted'].indexOf(self.permission)

///|
pub extern "js" fn Notification::request_permission() -> Promise[
  NotificationPermission,
] =
  #| () => Notification.requestPermission()

///|
pub extern "js" fn Notification::request_permission_with_deprecated_callback(
  deprecated_callback : NotificationPermissionCallback,
) -> Promise[NotificationPermission] =
  #| (deprecated_callback) => Notification.requestPermission(deprecated_callback)

///|
pub extern "js" fn Notification::get_max_actions(self : Notification) -> Int =
  #| (self) => self.maxActions

///|
pub extern "js" fn Notification::set_onclick(
  self : Notification,
  handler : (Event) -> Unit,
) -> Unit =
  #| (self, handler) => { self.onclick = (e) => handler(e) }

///|
pub extern "js" fn Notification::clear_onclick(self : Notification) -> Unit =
  #| (self) => { self.onclick = null }

///|
pub extern "js" fn Notification::set_onshow(
  self : Notification,
  handler : (Event) -> Unit,
) -> Unit =
  #| (self, handler) => { self.onshow = (e) => handler(e) }

///|
pub extern "js" fn Notification::clear_onshow(self : Notification) -> Unit =
  #| (self) => { self.onshow = null }

///|
pub extern "js" fn Notification::set_onerror(
  self : Notification,
  handler : (Event) -> Unit,
) -> Unit =
  #| (self, handler) => { self.onerror = (e) => handler(e) }

///|
pub extern "js" fn Notification::clear_onerror(self : Notification) -> Unit =
  #| (self) => { self.onerror = null }

///|
pub extern "js" fn Notification::set_onclose(
  self : Notification,
  handler : (Event) -> Unit,
) -> Unit =
  #| (self, handler) => { self.onclose = (e) => handler(e) }

///|
pub extern "js" fn Notification::clear_onclose(self : Notification) -> Unit =
  #| (self) => { self.onclose = null }

///|
pub extern "js" fn Notification::get_title(self : Notification) -> String =
  #| (self) => self.title

///|
pub extern "js" fn Notification::get_dir(
  self : Notification,
) -> NotificationDirection =
  #| (self) => ['auto', 'ltr', 'rtl'].indexOf(self.dir)

///|
pub extern "js" fn Notification::get_lang(self : Notification) -> String =
  #| (self) => self.lang

///|
pub extern "js" fn Notification::get_body(self : Notification) -> String =
  #| (self) => self.body

///|
pub extern "js" fn Notification::get_navigate(self : Notification) -> String =
  #| (self) => self.navigate

///|
pub extern "js" fn Notification::get_tag(self : Notification) -> String =
  #| (self) => self.tag

///|
pub extern "js" fn Notification::get_image(self : Notification) -> String =
  #| (self) => self.image

///|
pub extern "js" fn Notification::get_icon(self : Notification) -> String =
  #| (self) => self.icon

///|
pub extern "js" fn Notification::get_badge(self : Notification) -> String =
  #| (self) => self.badge

///|
pub extern "js" fn Notification::get_vibrate(self : Notification) -> Array[Int] =
  #| (self) => self.vibrate

///|
pub extern "js" fn Notification::get_timestamp(
  self : Notification,
) -> EpochTimeStamp =
  #| (self) => self.timestamp

///|
pub extern "js" fn Notification::get_renotify(self : Notification) -> Bool =
  #| (self) => self.renotify

///|
pub extern "js" fn Notification::get_silent(self : Notification) -> Bool? =
  #| (self) => (self.silent) ?? undefined

///|
pub extern "js" fn Notification::get_require_interaction(
  self : Notification,
) -> Bool =
  #| (self) => self.requireInteraction

///|
pub extern "js" fn Notification::get_data(self : Notification) -> JsValue =
  #| (self) => self.data

///|
pub extern "js" fn Notification::get_actions(
  self : Notification,
) -> Array[NotificationAction] =
  #| (self) => self.actions

///|
pub extern "js" fn Notification::close(self : Notification) -> Unit =
  #| (self) => self.close()

///|
/// NotificationEvent interface
pub type NotificationEvent

///|
pub extern "js" fn NotificationEvent::to_js_value(
  self : NotificationEvent,
) -> JsValue =
  #| (self) => self

///|
/// Cast JsValue to NotificationEvent (unchecked)
pub extern "js" fn NotificationEvent::from_js_value(
  v : JsValue,
) -> NotificationEvent =
  #| (v) => v

///|
/// Safely cast JsValue to NotificationEvent (checked with instanceof)
pub extern "js" fn NotificationEvent::from_js_value_opt(
  v : JsValue,
) -> NotificationEvent? =
  #| (v) => (v instanceof NotificationEvent) ? { $tag: 1, _0: v } : { $tag: 0 }

///|
/// Safely cast JsValue to NotificationEvent (checked with instanceof)
pub extern "js" fn JsValue::as_notification_event(
  self : JsValue,
) -> NotificationEvent? =
  #| (self) => (self instanceof NotificationEvent) ? { $tag: 1, _0: self } : { $tag: 0 }

///|
/// Cast JsValue to NotificationEvent (unchecked)
pub extern "js" fn JsValue::to_notification_event(
  self : JsValue,
) -> NotificationEvent =
  #| (self) => self

///|
pub extern "js" fn NotificationEvent::to_extendable_event(
  self : NotificationEvent,
) -> ExtendableEvent =
  #| (self) => self

///|
pub extern "js" fn NotificationEvent::to_event(
  self : NotificationEvent,
) -> Event =
  #| (self) => self

///|
extern "js" fn NotificationEvent::new_ffi(
  type_ : String,
  event_init_dict : JsValue,
) -> NotificationEvent =
  #| (type_, event_init_dict) => new NotificationEvent(type_, event_init_dict)

///|
pub fn NotificationEvent::new(
  type_ : String,
  event_init_dict : NotificationEventInit,
) -> NotificationEvent {
  NotificationEvent::new_ffi(type_, event_init_dict.to_js())
}

///|
pub extern "js" fn NotificationEvent::get_notification(
  self : NotificationEvent,
) -> Notification =
  #| (self) => self.notification

///|
pub extern "js" fn NotificationEvent::get_action(
  self : NotificationEvent,
) -> String =
  #| (self) => self.action