﻿B4A=true
Group=Libraries
ModulesStructureVersion=1
Type=Class
Version=11
@EndOfDesignText@
Private Sub Class_Globals
	Private cache As Map
	Private cache_folder As String = "caches"
	Private w,h As Int
	Private force_resize As Boolean
	Private radius_,degree_ As Int
	Private center_crop As Boolean
	Private img As Object
	Private duration As Int
	Private holder As Bitmap
	Private xui As XUI
	Private timeout_ As Int
	Private dir As String
	#if b4a
	dir = File.DirInternal
	#Else
	dir = File.DirLibrary
	#End If
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize As Picture
	File.MakeDir(dir,cache_folder)
	cache.Initialize
	timeout_ = 2500
	Return Me
End Sub

Public Sub AnimationDuration(Val As Int) As Picture	
	duration = Val
	Return Me
End Sub

Public Sub Resize(Width As Int,Height As Int) As Picture
	w = Width
	h = Height
	force_resize = True
	Return Me
End Sub

Public Sub SetTimeout(Timeout As Int) As Picture
	timeout_ = Timeout
	Return Me
End Sub

'The radius filter is applied at the end 
Public Sub SetRadius(Radius As Int) As Picture
	radius_ = Radius
	Return Me
End Sub

Public Sub SetPlaceHolder(res As Bitmap) As Picture
	holder = res
	Return Me
End Sub

Public Sub Rotate(Degree As Int) As Picture
	degree_ = Degree
	Return Me
End Sub

Public Sub CenterCrop(iv As ImageView) As Picture
	center_crop = True
	img = iv
	Return Me
End Sub

Public Sub ShowFade(IV As B4XView,bt As Bitmap)
	
	IV.Visible = False
	Sleep(10)
	IV.SetBitmap(bt)
	IV.SetVisibleAnimated(duration,True)
		
End Sub

Public Sub Download(Url As String) As ResumableSub

	Dim filename As String = GetFilename(Url)
	
	If cache.ContainsKey(Url) Then
		Return ApplyFilter(cache.Get(filename))
	End If
	
	If File.Exists(dir & "/" & cache_folder,filename) Then

		Dim b As Bitmap = LoadBitmap(dir & "/" & cache_folder,filename)

		cache.Put(Url,b)
		
		Return ApplyFilter(b)
		
	Else
		
		Dim h1 As HttpJob
		h1.Initialize("",Me)
		h1.Download(Url)
		h1.GetRequest.Timeout = timeout_
		Wait For JobDone(Job As HttpJob)
			If Job.Success Then
				
				Dim res As Bitmap
				res = Job.GetBitmap
				SaveBitmap(res,dir & "/" & cache_folder,filename)
			
				res = ApplyFilter(res)
				
				cache.Put(Url,res)
				
				Return res
				
			Else
				
				If holder.IsInitialized Then
					Return ApplyFilter(holder)
				End If
	
				Return Null
			
		End If
			
	End If
	
End Sub

#region private subrootine
Private Sub ApplyFilter(res As Bitmap) As Bitmap
	
	If force_resize Then
		force_resize = False
		res = res.Resize(w,h,True)
	End If
				
	If center_crop Then
		center_crop = False
		res = FillImage(res,img)
	End If
				
	If radius_ > 0 Then
		res = RoundBitmap(res,radius_)
		radius_ = 0
	End If
				
	If degree_ > 0 Then
		res = RotateBitmap(res,degree_)
		degree_ = 0
	End If
	
	Return res
	
End Sub

Private Sub GetFilename(fullpath As String) As String
	
	Try
		Dim su As StringUtils
		fullpath		=	su.DecodeUrl(fullpath,"UTF8")
		
		Dim index As Int
		index = fullpath.LastIndexOf("/")
		Dim rs As String
		rs = fullpath.SubString(index + 1)
		Return rs
	Catch
		Return fullpath
	End Try
	
End Sub

Private Sub SaveBitmap(Bitmap As Bitmap,Dir_ As String,Filename As String)
	
	Dim format As String
	
	Try
		Dim ext As String = Filename.SubString(Filename.LastIndexOf("."))
		If ext.ToLowerCase = "jpg" Or ext.ToLowerCase = "jpeg" Then
			format = "JPEG"
		Else if ext.ToLowerCase = "png" Then
			format = "PNG"
		Else
			format = "JPEG"
		End If
	Catch
		format = "JPEG"
	End Try
	
	Dim b1 As Bitmap
	Dim out As OutputStream
	b1 = Bitmap
	out = File.OpenOutput(Dir_,Filename,False)
	b1.WriteToStream(out,100,format)
	out.Close
	
End Sub

Private Sub RoundBitmap(Input As Bitmap,Corner As Int) As Bitmap
	
	Dim xui As XUI
	Dim BorderColor As Int = xui.Color_Black
	Dim BorderWidth As Int = 0
	Dim c As B4XCanvas
	Dim xview As B4XView = xui.CreatePanel("")
	xview.SetLayoutAnimated(0, 0, 0, Input.Width, Input.Height)
	c.Initialize(xview)
	Dim path As B4XPath
	path.InitializeRoundedRect(c.TargetRect, Corner)
	c.ClipPath(path)
	c.DrawRect(c.TargetRect, BorderColor, True, BorderWidth) 'border
	c.RemoveClip
	Dim r As B4XRect
	r.Initialize(BorderWidth, BorderWidth, c.TargetRect.Width - BorderWidth, c.TargetRect.Height - BorderWidth)
	path.InitializeRoundedRect(r, Corner)
	c.ClipPath(path)
	c.DrawBitmap(Input, r)
	c.RemoveClip
	c.Invalidate
	Dim res As B4XBitmap = c.CreateBitmap
	c.Release
	Return res
	
End Sub

Private Sub FillImage(bmp As B4XBitmap, ImageView As B4XView) As Bitmap
	Dim bmpRatio As Float = bmp.Width / bmp.Height
	Dim viewRatio As Float = ImageView.Width / ImageView.Height
	If viewRatio > bmpRatio Then
		Dim NewHeight As Int = bmp.Width / viewRatio
		bmp = bmp.Crop(0, bmp.Height / 2 - NewHeight / 2, bmp.Width, NewHeight)
	Else if viewRatio < bmpRatio Then
		Dim NewWidth As Int = bmp.Height * viewRatio
		bmp = bmp.Crop(bmp.Width / 2 - NewWidth / 2, 0, NewWidth, bmp.Height)
	End If
	Dim scale As Float = 1
    #if B4i
	scale = GetDeviceLayoutValues.NonnormalizedScale
    #End If
	Return bmp.Resize(ImageView.Width * scale, ImageView.Height * scale, True)
End Sub

Private Sub RotateBitmap(original As Bitmap, degree As Float) As Bitmap
	Return original.Rotate(degree)
End Sub
#end region