' Gambas module file

Class DesktopMime

Public Ext As New Collection(gb.IgnoreCase)

Private $cArrow As New Collection
Private $bInitGTK As Boolean
Private $bUseGTK As Boolean
Private $cEmblem As New Collection

Public Sub GetArrow(iType As Integer, iSize As Integer) As Image
  
  Dim sKey As String
  Dim hPict As Picture
  Dim hImage As Image
  
  Select Case iType
    Case Align.Top
      sKey = "top"
    Case Align.Bottom
      sKey = "bottom"
    Case Align.Left
      sKey = "left"
    Case Align.Right
      sKey = "right"
  End Select

  sKey = sKey & "-" & iSize

  hImage = $cArrow[sKey]
  If Not hImage Then 
    hPict = New Picture(16, 16)
    hPict.Fill(Color.White)
    Draw.Begin(hPict)
    Draw.Style.Arrow(0, 0, 16, 16, iType)
    Draw.End
    hImage = hPict.Image
    hImage.Erase()
    hImage = hImage.Stretch(iSize, iSize)
    'hPict = hImage.Picture
    $cArrow[sKey] = hImage
  Endif
  Return hImage
  
End

' Public Sub GetFileSize(iSize As Long) As String
' 
'   Dim fSize As Float
'   
'   If iSize < 1024 Then
'     Return Subst(("&1 B"), CStr(iSize))
'   Else If iSize < 1048576 Then
'     fSize = iSize / 1024
'     If fSize < 20 Then
'       Return Subst(("&1 KiB"), Format(iSize / 1024, "0.#"))
'     Else
'       Return Subst(("&1 KiB"), Format(iSize / 1024, "0"))
'     Endif
'   Else If iSize < 1073741824 Then
'     fSize = iSize / 1048576
'     If fSize < 20 Then
'       Return Subst(("&1 MiB"), Format(iSize / 1048576, "0.#"))
'     Else
'       Return Subst(("&1 MiB"), Format(iSize / 1048576, "0"))
'     Endif
'   Else
'     fSize = iSize / 1073741824
'     If fSize < 20 Then
'       Return Subst(("&1 GiB"), Format(iSize / 1073741824, "0.#"))
'     Else
'       Return Subst(("&1 GiB"), Format(iSize / 1073741824, "0"))
'     Endif
'   Endif
'   
' End

Private Sub FindMenuChild(hMenu As Menu, sMenu As String) As Menu
  
  For Each hMenu In hMenu.Children
    If hMenu.Name == sMenu Then Return hMenu
    hMenu = FindMenuChild(hMenu, sMenu)
    If hMenu Then Return hMenu
  Next
  
End

Private Sub FindMenuWindow(hWindow As Window, sMenu As String) As Menu
  
  Dim hMenu As Menu
  
  For Each hMenu In hWindow.Menus
    If hMenu.Name == sMenu Then Return hMenu
    hMenu = FindMenuChild(hMenu, sMenu)
    If hMenu Then Return hMenu
  Next
  
End

Public Sub FindMenu(hCtrl As Control, sMenu As String) As Menu
  
  Dim hWindow As Window
  Dim hMenu As Menu
  
  hWindow = hCtrl.Window
  Do
    hMenu = FindMenuWindow(hWindow, sMenu)
    If hMenu Then Break
    Try hWindow = hWindow.Parent.Window
    If Error Then Return
  Loop
  
  Return hMenu
  
End

Public Sub PaintColor(X As Integer, Y As Integer, W As Integer, H As Integer, fBorderRadius As Float, iColor As Integer)
  
  Dim I, J, C As Integer
  
  If iColor And &HFF000000 Then 
  
    Paint.Save
    Paint.Rectangle(X, Y, W, H, fBorderRadius)
    Paint.Clip
    
    For J = 0 To W + 7 Step 8
      For I = 0 To H + 7 Step 8
      
        If ((I + J) \ 8) And 1 Then 
          C = Color.Blend(iColor, &H808080)
        Else 
          C = Color.Blend(iColor, &HC0C0C0)
        Endif
      
        Paint.FillRect(X + I, Y + J, 8, 8, C)
        
      Next 
    Next
    
    Paint.Restore
  
  Else 
    
    Paint.Rectangle(X, Y, W, H, fBorderRadius)
    Paint.Background = iColor
    Paint.Fill
    
  Endif
  
End

Public Sub NormalizePath(sPath As String) As String
  
  Dim iLen As Integer
  
  Do
    iLen = Len(sPath)
    sPath = Replace(sPath, "//", "/")
    If Len(sPath) = iLen Then Break
  Loop
  
  If Len(sPath) > 1 And If Right(sPath) = "/" Then sPath = Left(sPath, -1)
  
  If Not sPath Then Error.Raise("Void path")
  
  Return sPath
  
End

#If False
Private Sub AddUnique(aStr As String[], sVal As String)
  
  If Not aStr.Exist(sVal) Then aStr.Add(sVal)
  
End

Private Sub MakeMap()
  
  Dim aKey As New String[]
  Dim sPath As String
  Dim sLine As String
  Dim hFile As File
  Dim aLine As String[]
  Dim sKey As String
  Dim sIcon As String
  Dim aIcon As String[]
  Dim cIcon As New Collection
  
  For Each sPath In ["map/gnome.map", "map/kde4.map"]
    
    hFile = Open sPath
    For Each sLine In hFile.Lines
      
      If Left(sLine) = ";" Then Continue
      
      aLine = Split(sLine, " ", "", True)
      sKey = Trim(aLine[0])
      AddUnique(aKey, sKey)
      
      If Not cIcon.Exist(sKey) Then cIcon[sKey] = New String[]
      If aLine.Count >= 2 Then
        aIcon = cIcon[sKey]
        For Each sIcon In Split(Trim(aLine[1]), ";")
          AddUnique(aIcon, sIcon)
        Next
      Endif
      
    Next
    
  Next
  
  hFile = Open Application.Path &/ "icon.map" For Create
  aKey.Sort
  For Each sKey In aKey
    Print #hFile, sKey; Space$(Max(1, 24 - Len(sKey))); cIcon[sKey].Join(";")
  Next
  Close #hFile
  
End
#Endif

Public Sub MkDir(Path As String)

  Dim sElt As String
  Dim sMake As String = "/"

  For Each sElt In Split(Path, "/")
    sMake &/= sElt
    If IsDir(sMake) Then Continue
    Try Mkdir sMake
  Next

End

Public Sub Test()

  'MakeColorMap
  'InputBox("<b></b>Please enter your age.<br><b>Do not lie!</b><br>", "Important request")
  Application.Theme = "gambas-thin"
  Message.Title = "An optional message box"
  Message.Optional("\"Life is like a chocolate box.\"<br><br>This is an optional message.", "OK", "test", "tip")

End

Public Sub Task_Read(sData As String)

  Debug sData
  
End

Public Sub Task_Error(Data As String)
  
  Debug Data
  
End


Public Sub Task_Kill()

  Dim sStr As String
  Try sStr = Last.Value
  If Error Then 
    Debug Error.Text
  Else
    Debug "->";; sStr
  Endif
End

Public Sub GetCacheDir() As String
  
  Dim sPath As String = Env["XDG_CACHE_HOME"]
  If sPath Then 
    Return sPath 
  Else 
    Return User.Home &/ ".cache"
  Endif
  
End

Public Sub UseGTK() As Boolean
  
  If Not $bInitGTK Then 
    $bInitGTK = True
    If Component.IsLoaded("gb.gtk3") Or If Component.IsLoaded("gb.gtk") Then
      $bUseGTK = True
    Endif
  Endif
  
  Return $bUseGTK
  
End

Public Sub MakeColorMap()

  Dim hImage As Image
  Dim X As Integer
  Dim Y As Integer
  Dim H, S As Integer
  Dim V As Integer
  Dim hImage2 As Image

  Return

  hImage = New Image(360, 256)
  hImage2 = New Image(360, 256)
  
  For X = 0 To hImage.W - 1
    For Y = 0 To hImage.H - 1
          
      H = 359 - X * 360 / hImage.W
      S = Min(255, 255 - Y * 256 / hImage.H)
      
      hImage2[X, Y] = Color.HSV(H, S, 255)
      
      H = ((H + 7) \ 15) * 15
      If H = 360 Then H = 0
      S = Min(255, ((S + 15) \ 32) * 32)
      
      hImage[X, Y] = Color.HSV(H, S, 255)
      
    Next
  Next
  
  ' For Y = 0 To hImage.H - 2
  '   If hImage[0, Y] <> hImage[0, Y + 1] Then
  '     hImage.PaintRect(0, Y, hImage.W, 1, Color.RGB(0, 0, 0, &HE0))
  '   Endif
  ' Next
  ' 
  ' For X = 0 To hImage.W - 2
  '   If hImage[X, 0] <> hImage[X + 1, 0] Then
  '     hImage.PaintRect(X, 0, 1, hImage.H, Color.RGB(0, 0, 0, &HE0))
  '   Endif
  ' Next
  
  
  hImage2.Save("~/gambas/git/master/comp/src/gb.form/img/colormap.png")
  hImage.Save("~/gambas/git/master/comp/src/gb.form/img/colormap-snap.png")
  
  hImage = New Image(8, 128)
  
  For Y = 0 To hImage.H - 1
          
    V = Y / hImage.H * 256
    V = ((V + 16) \ 32) * 32
    V = Min(255, Max(0, 256 - V))

    hImage.FillRect(0, Y, hImage.W, 1, Color.RGB(V, V, V))
      
  Next
  
  hImage.Save("~/gambas/git/master/comp/src/gb.form/img/valuemap-snap.png")
  

End


Private Sub FormatNumber(fNum As Float) As String

  Dim sStr As String
  
  sStr = Format(fNum, "0.#")
  If String.Len(sStr) > 3 Then
    sStr = String.Left(sStr, 3)
    If Not IsDigit(Right(sStr)) Then sStr = Left(sStr, -1)
  Endif
  Return sStr
  
End

Public Sub FormatSize(Size As Long, Optional {Binary} As Boolean) As String

  If {Binary} Then
    If Size < 1000 Then
      Return Subst(("&1 B"), CStr(Size))
    Else If Size < 1024000 Then
      Return Subst(("&1 KiB"), FormatNumber(Size / 1024))
    Else If Size < 1048576000 Then
      Return Subst(("&1 MiB"), FormatNumber(Size / 1048576))
    Else
      Return Subst(("&1 GiB"), FormatNumber(Size / 1073741824))
    Endif
  Else
    If Size < 1000 Then
      Return Subst(("&1 B"), CStr(Size))
    Else If Size < 1000000 Then
      Return Subst(("&1 KB"), FormatNumber(Size / 1000))
    Else If Size < 1000000000 Then
      Return Subst(("&1 MB"), FormatNumber(Size / 1000000))
    Else
      Return Subst(("&1 GB"), FormatNumber(Size / 1000000000))
    Endif
  Endif

End

Public Sub FormatPath(Path As String) As String
  
  If Path = User.Home Then Return "~"
  If Path Begins (User.Home & "/") Then Return "~/" & Mid$(Path, Len(User.Home) + 2)
  Return Path
  
End

Public Sub PaintEmblems(XI As Integer, YI As Integer, WI As Integer, HI As Integer, aEmblem As Variant[], (iBg) As Integer)
  
  Dim hEmblem As Variant
  Dim S As Integer
  Dim sIcon As String
  Dim X As Integer
  Dim DS As Integer
  Dim Y As Integer
  Dim vEmblem As Variant
  
  If Not aEmblem Or If aEmblem.Count = 0 Then Return
  
  S = Min(HI, WI) \ 6
  If S < 2 Then Return
  DS = S \ 4
  S = Max(S, 8)
  
  If System.RightToLeft Then
    X = XI + S + DS * 2
  Else 
    X = XI + WI - S - DS * 2
  Endif
  Y = YI + HI - S - DS * 2
  
  For Each vEmblem In aEmblem
  
    If System.RightToLeft Then
      If X > WI - S Then Break
    Else 
      If X < S Then Break
    Endif
    
    If TypeOf(vEmblem) = gb.String Then
    
      sIcon = vEmblem
      hEmblem = $cEmblem[sIcon]
      If Not hEmblem Then
        hEmblem = Picture["icon:/128" &/ sIcon]
        If Not hEmblem Then Try hEmblem = Image.Load("img/emblem" &/ sIcon & ".png")
        If Not hEmblem Then Continue
        $cEmblem[sIcon] = hEmblem
      Endif
      
    Else If vEmblem Is Picture Or If vEmblem Is Image Then
      
      hEmblem = vEmblem
      
    Else 
      
      Continue
      
    Endif
    
    GoSub DRAW_EMBLEM
  
  Next
  
  Return

DRAW_EMBLEM:
  
  ' Paint.Ellipse(X, Y, S, S)
  ' Paint.Background = Color.Opacity(iBg, 0.75)
  ' Paint.Fill()

  If System.RightToLeft Then
    X += DS
  Else 
    X -= DS
  Endif
  
  If hEmblem Is Image Then
    Paint.DrawImage(hEmblem, X, Y, S, S)
  Else
    Paint.DrawPicture(hEmblem, X, Y, S, S)
  Endif
  
  If System.RightToLeft Then
    X += S
  Else 
    X -= S
  Endif
  
  Return
  
End

Public Sub AddEmblems(hPict As Picture, aEmblem As Variant[], iBg As Integer) As Picture
  
  Dim hImage As Image
  
  If Not aEmblem Or If aEmblem.Count = 0 Then Return hPict
  
  hImage = hPict.Image
  
  Paint.Begin(hImage)
  PaintEmblems(0, 0, hImage.W, hImage.H, aEmblem, iBg)
  Paint.End()
  
  Return hImage.Picture

End

Public Sub InitExt()
  
  Ext["html"] = "html"
  Ext["htm"] = "html"
  Ext["css"] = "css"
  Ext["js"] = "js"
  Ext["xml"] = "xml"
  
  Ext["tar"] = "archive"
  Ext["gz"] = "archive"
  Ext["tgz"] = "archive"
  Ext["bz2"] = "archive"
  Ext["z"] = "archive"
  Ext["zip"] = "archive"
  Ext["xz"] = "archive"
  
  Ext["txt"] = "text"
  Ext["log"] = "text"
  Ext["json"] = "text"
  
  Ext["mp3"] = "audio"
  Ext["aac"] = "audio"
  Ext["ogg"] = "audio"
  Ext["oga"] = "audio"
  Ext["flac"] = "audio"
  Ext["wav"] = "audio"
  
  Ext["mpg"] = "video"
  Ext["mpeg"] = "video"
  Ext["avi"] = "video"
  Ext["wmv"] = "video"
  Ext["mov"] = "video"
  Ext["mp4"] = "video"
  Ext["mkv"] = "video"
  
  Ext["gambas"] = "gambas"
  Ext["gbs"] = "gambas"
  
  Ext["c"] = "c"
  Ext["cpp"] = "cpp"
  Ext["h"] = "h"
  
  Ext["deb"] = "package"
  Ext["rpm"] = "package"
  
  Ext["iso"] = "cdrom"
  
  Ext["jpg"] = "image"
  Ext["jpeg"] = "image"
  Ext["png"] = "image"
  Ext["gif"] = "image"
  Ext["xpm"] = "image"
  Ext["bmp"] = "image"
  Ext["ico"] = "image"
  Ext["xcf"] = "image"
  Ext["svg"] = "image"
  Ext["svgz"] = "image"
  Ext["webp"] = "image"
  
  Ext["pdf"] = "pdf"
  
  Ext["ttf"] = "font"
  Ext["otf"] = "font"
  Ext["bdf"] = "font"
  
  Ext["odt"] = "office"
  Ext["ods"] = "office-calc"
  Ext["odg"] = "office-draw"
  Ext["odp"] = "office-presentation"
  Ext["odf"] = "office-math"
  
  Ext["rtf"] = "office"
  Ext["doc"] = "office"
  Ext["docx"] = "office"
  Ext["xls"] = "office-calc"
  Ext["xlsx"] = "office-calc"
  Ext["ppt"] = "office-presentation"
  Ext["pptx"] = "office-presentation"
  
End

Public Sub UrlUnquote((Path) As String, Optional DoNotDecodePlus As Boolean) As String
  
  Dim iInd As Integer
  Dim sRes As String
  Dim sCar As String
  
  For iInd = 1 To Len(Path)
    sCar = Mid$(Path, iInd, 1)
    If sCar = "%" Then 
      sCar = Chr$(Val("&H" & Mid$(Path, iInd + 1, 2)))
      iInd += 2
    Else If sCar = "+" And If Not DoNotDecodePlus Then 
      sCar = " "
    Endif
    sRes &= sCar
  Next

  Return sRes  
  
End

Public Sub Main()

  ' Stock.Debug = True
  ' Stock["32/table"].Save("~/icon.png")

  ' InputBox("Début 2007, au moment d’élire le futur Président de la République en France, l’un des débats\nimportants est, une nouvelle fois, celui sur la sécurité. En 2002, alors que la gauche était au\npouvoir et qu’elle devait rendre compte de son action, cette question était même au coeur de la\ncampagne. Tel n’est pas le cas aujourd’hui. Les médias semblent moins friands de rapporter\nces affaires de violences individuelles ou collectives qui avaient pourtant fait la une de\nbeaucoup de journaux télévisés il y a cinq ans, non sans conséquence sur le résultat de\nl’élection d’ailleurs. La matière est aujourd’hui pourtant identique, plus dense même, puisque\nces violences n’ont cessé de s’aggraver. On ne peut que se réjouir de voir d’autres sujets\nanimer la campagne: l’emploi, le logement, le pouvoir d’achat, les impôts, la dette extérieur, la\nplace du citoyen dans la République, le sort des minorités, la place de la France dans le\nmonde... ", "Important request", "235")
  ' 
  ' InputBox("Test<br>Une ligne qui est quand même très longue.")

End

