' Gambas module file

Class DBus
Class DBusSignal
Class DBusFile

Property Read Enabled As Boolean

Private $bStarted As Boolean
Private $bCheckAvailable As Boolean
Private $iToken As Integer

Private $hScreenshotSignal As DBusSignal
Private $hScreenshot As Image
Private $cResult As Collection

Private Sub StartPortal()
  
  If $bStarted Then Return
  Component.Load("gb.dbus")
  DBus.Session.Start("org.freedesktop.portal.Desktop")
  $bStarted = True
  
End

Private Sub GetPortal(sInterface As String) As DBusProxy

  If Not $bCheckAvailable Then
    If Not DesktopPortal.Enabled Then Error.Raise("Desktop portal is not available")
    $bCheckAvailable = True
  Endif
  Return DBus["org.freedesktop.portal.Desktop"]["/org/freedesktop/portal/desktop", "org.freedesktop.portal." & sInterface]

End

Private Sub GetToken(ByRef sToken As String) As DBusSignal
  
  Dim hSignal As DBusSignal

  $cResult = Null
  Inc $iToken
  sToken = "gb_" & Application.Id & "_" & CStr($iToken)
  hSignal = New DBusSignal(DBus.Session, "org.freedesktop.portal.Request", "/org/freedesktop/portal/desktop/request/" & Replace(Mid$(DBus.Session._Name, 2), ".", "_") &/ sToken) As "Request"
  Return hSignal

End

Private Sub WaitForResult()
  
  While Not $cResult
    Wait Next
  Wend
  
End

Private Sub FromUri(sUri As String) As String
  
  If sUri Begins "file://" Then sUri = Mid$(sUri, 8)
  Return FromUrl(sUri)
  
End

Public Sub Request_Signal((Method) As String, Arguments As Variant[])
  
  $cResult = Arguments[1]
  Last.Enabled = False
  
End

Public Sub Screenshot_Signal((Method) As String, Arguments As Variant[])

  Dim cResult As Collection
  Dim sPath As String
  
  cResult = Arguments[1]
  sPath = FromUri(cResult["uri"])
  Try $hScreenshot = Image.Load(sPath)
  
  $hScreenshotSignal.Enabled = False
  $hScreenshotSignal = Null
  
End

Public Sub Screenshot() As Image

  Dim sToken As String

  StartPortal
  
  If Not $hScreenshotSignal Then
    
    $hScreenshotSignal = GetToken(ByRef sToken)
    Object.Attach($hScreenshotSignal, Me, "Screenshot")
    GetPortal("Screenshot").Screenshot("", ["handle_token": sToken, "interactive": False])
    
    Do
      If Not $hScreenshotSignal Or If $hScreenshot Then Break
      Wait Next
    Loop
    
  Endif
  
  Return $hScreenshot
  
End

Private Function Enabled_Read() As Boolean

  If Not Desktop.UsePortal Then Return False
  If Env["GB_DESKTOP_PORTAL_ENABLED"] = "0" Then Return False
  StartPortal
  Try Return DBus.Session.Exist("org.freedesktop.portal.Desktop")

End

Public Sub PickColor() As Integer

  Dim sToken As String
  Dim aColor As Float[]
  
  StartPortal
  
  GetToken(ByRef sToken)
  GetPortal("Screenshot").PickColor("", ["handle_token": sToken, "interactive": False])
  WaitForResult
  
  aColor = $cResult["color"]
  If aColor Then
    Return Color.RGB(aColor[0] * 255, aColor[1] * 255, aColor[2] * 255)
  Else 
    Return Color.Default 
  Endif
  
End

Public Sub OpenURI(sUrl As String)
  
  Dim cOption As New Collection
  Dim hFile As File
  
  StartPortal
  
  If sUrl Begins "file://" Then sUrl = FromUri(Mid$(sUrl, 8))
  
  cOption["ask"] = False
  
  If InStr(sUrl, "://") Then
    GetPortal("OpenURI").OpenURI("", sUrl, cOption)
  Else
    hFile = Open sUrl For Read
    GetPortal("OpenURI").OpenFile("", DBusFile(hFile), cOption)
  Endif
  
End

Public Sub SendMail(aTo As String[], aCc As String[], aBcc As String[], sSubject As String, sBody As String, aAttach As String[])

  Dim aFile As DBusFile[]
  Dim sAttach As String
  Dim hFile As File
  Dim cOption As New Collection
  
  StartPortal
  
  If aAttach And If aAttach.Count Then
    aFile = New DBusFile[]
    For Each sAttach In aAttach
      Try hFile = Open sAttach For Read
      If Error Then Continue
      aFile.Add(DBusFile(hFile))
    Next
  Endif
  
  cOption = New Collection
  
  If Not aTo Then aTo = New String[]
  cOption["addresses"] = aTo
  If Not aCc Then aCc = New String[]
  cOption["cc"] = aCc
  If Not aBcc Then aBcc = New String[]
  cOption["bcc"] = aBcc
  cOption["subject"] = sSubject
  cOption["body"] = sBody
  If aFile Then cOption["attachment_fds"] = aFile
  
  GetPortal("Email").ComposeEmail("", cOption)
  
End
