
Function Property_Get ( Property_DB ( Any ) As Property_DB_Type, Label As String = EMPTY ) As Property_DB_Type

	Dim As Property_DB_Type Request
	
	With Request
		
		.Label = Label
		Request = Property_Database_Query ( Property_DB ( ), .Label )
		Exit Function

	End With
	
	Property_Get = Request
	Exit Function

End Function

Function Property_Set ( Property_DB ( Any ) As Property_DB_Type, Label As String = EMPTY, Value As String = EMPTY ) As Property_DB_Type

	Dim As Property_DB_Type Request
	
	With Request
		
		.Label = Label
		.Value = Value
		
		.Iterator = Property_Database_Set ( Property_DB ( ), .Label , .Value )
		
		.Value = Property_DB ( .Iterator ).Value
		.Image = Property_DB ( .Iterator ).Image
	
	End With
	
	Property_Set = Request
	Exit Function

End Function

Sub Property_Inc_Capacity ( Property_DB ( Any ) As Property_DB_Type, Counter As Long = POSONE )

	Select Case Counter
	Case Is GTR ZERO
	
		Do While Counter GTR ZERO
			
			If UBound ( Property_DB, POSONE ) EQU NEGONE Then
				ReDim Property_DB ( ZERO To ZERO )
			Else
				ReDim Preserve Property_DB ( ZERO To UBound( Property_DB, POSONE ) + POSONE )
			End If
			
			Counter -= POSONE
			
		Loop
		
	Case Is LSS ZERO
	
		Do While Counter LSS ZERO
			
			If UBound( Property_DB, POSONE ) EQU ZERO Then

				ReDim Property_DB ( NEGONE To NEGONE )
				
				Exit Do
				
			Else
				
				Redim Preserve Property_DB ( ZERO To UBound( Property_DB, POSONE ) - POSONE )
			
			End If
			
			Counter += POSONE
			
		Loop
		
	End Select
	
End Sub

Function Property_DB_CRLF_Buffer ( ByRef Buffer As String = EMPTY ) As String

	If Len ( Buffer ) GTR ZERO Then
		Buffer &= CRLF
	End If

	Property_DB_CRLF_Buffer = Buffer
	Exit Function

End Function

Sub Property_Erase ( Property_DB ( Any ) As Property_DB_Type )

	For Index As Long = UBound ( Property_DB, POSONE ) To ZERO Step NEGONE

		With Property_DB ( Index )
			
			.Label = EMPTY
			.Value = EMPTY
			.Image = ImageDestroy2 ( .Image )
			.Iterator = NEGONE
		
		End With
		
		If Index GTR ZERO Then
			ReDim Preserve Property_DB ( ZERO To Index - POSONE )
		Else
			ReDim Property_DB ( NEGONE To NEGONE )
		End If
	
	Next Index

End Sub

Sub Property_Digest_Word ( Property_DB ( Any ) As Property_DB_Type, ByRef Buffer As String = EMPTY )

	Property_Erase Property_DB ( )
	
	Do While Len( Buffer ) GTR ZERO
		
		If StRPos( CRLF, Buffer ) LSS StrPos( Chr(32), Buffer ) Then
			
			Property_Inc_Capacity( Property_DB ( ), POSONE )

			With Property_DB( UBound( Property_DB, POSONE ) )
				.Iterator = NEGONE
				.Label = Hex( UBound( Property_DB, POSONE ) + POSONE )
				.Value = Prefix( CRLF, Buffer )
			End With

			Buffer = Suffix( CRLF, Buffer )

			Property_Inc_Capacity( Property_DB ( ), POSONE )

			With Property_DB( UBound( Property_DB, POSONE ) )
				.Iterator = NEGONE
				.Label = Hex( UBound( Property_DB, POSONE ) + POSONE )
				.Value = "{% CRLF %}"
			End With
			
		Else
			
			Property_Inc_Capacity( Property_DB ( ), POSONE )

			With Property_DB( UBound( Property_DB, POSONE ) )
				.Iterator = NEGONE
				.Label = Hex( UBound( Property_DB, POSONE ) + POSONE )
				.Value = Prefix( Chr(32), Buffer )
			End With
		
			Buffer = Suffix( Chr(32), Buffer )
		
		End If
		

	Loop
	
	Property_Bubble_Sort( Property_DB ( ) )
	
	Property_Database_Save( Property_DB ( ), "./Assets (v0x22)/Words.Property" )
	
End Sub
	
Sub Property_Show_Array_Direct ( Property_DB ( Any ) As Property_DB_Type )
	
	Dim As String Buff = EMPTY
	Dim As FB.Image Ptr Image
	
	Property_Show_Array ( Property_DB ( ), Buff, Image )
	Buff = EMPTY : Image = ImageDestroy2 ( Image )

End Sub

Sub Property_Show_Array_Bounds ( Property_DB ( Any ) As Property_DB_Type )
	
	if DBDebugEnabled NEQ ZERO then
		Color RGBA ( 255, ZERO, ZERO, 255 )
		Print "LBound:" & SP & QUOT & LBound ( Property_DB, POSONE ) & QUOT & SP & "To" & SP & "UBound:" & SP & QUOT & UBound ( Property_DB, POSONE ) & QUOT
	end if
	
End Sub

Sub Property_Show_Array ( Property_DB ( Any ) As Property_DB_Type, ByRef Buff As String = EMPTY, ByRef Image As FB.Image Ptr = ZERO )
	
	Buff = EMPTY : Image = ImageDestroy2 ( Image )
	
	Dim As String Property_Text_Buffer : Property_Text_Buffer = EMPTY
	
	For Iterator As Long = LBound ( Property_DB, POSONE ) To UBound ( Property_DB, POSONE ) Step POSONE
		With Property_DB ( Iterator )
			Property_Text_Buffer &= .Label & EQ & .Value & CRLF
		End With
	Next
	
	Buff = Text_Box_String ( Property_Text_Buffer, 40, 30 )
	Image = Text_Box_Render ( Buff, 40, 30, ZERO )

	if DBDebugEnabled NEQ ZERO then
		Color RGBA ( 255, 64, 64, 255 )
		Print "Property Show Array (" & SP & Image -> Width & COMMA & SP & Image -> Height & SP & ")"
	
		Cls
		Put ( ZERO, ZERO ), Image, Alpha
		SimpleSleep ( VGA_Table ( ) )

	end if

End Sub

Sub Property_Bubble_Sort ( Property_DB ( Any ) As Property_DB_Type )

	'Bubble
	
	Dim As Long Sorted = ZERO
	
	Do
		Sorted = ZERO
		
		For Iterator As Long = LBound ( Property_DB, POSONE ) To UBound ( Property_DB, POSONE )-POSONE
			If Property_DB ( Iterator ).Label GTR Property_DB(Iterator+POSONE).Label Then
				Swap Property_DB ( Iterator ).Iterator,Property_DB(Iterator+POSONE).Iterator
				
				Swap Property_DB(Iterator),Property_DB(Iterator+POSONE)
				Sorted=POSONE
			End If
		Next
		
		If Sorted EQU ZERO Then
			Exit Do
		End If
	Loop

End Sub

Function Property_Binary_Find ( Property_DB ( Any ) As Property_DB_Type , sName As String = EMPTY, ByRef WhereToAdd As Long = ZERO ) As Long
	
	'Binary
	
	Dim As Long Result = ZERO
	
	Dim As Long Lo = LBound ( Property_DB, POSONE ), Hi = UBound ( Property_DB, POSONE ), Md = ZERO
	
	While Hi >= Lo		      
		
		Md = ( Lo + Hi + POSONE ) \ 2
		Result = strcmp ( sName , Property_DB ( Md ).Label )
		
		Select Case Result
		Case ZERO
			Property_Binary_Find = Md
		Case Is GTR ZERO			
			Lo = Md + POSONE
		Case Else
			Hi = Md - POSONE
		End Select
		
	Wend
	
	WhereToAdd = Lo
	
	Property_Binary_Find = NEGONE
	Exit Function

End Function

Function Property_Database_Query ( Property_DB ( Any ) As Property_DB_Type , sName As String = EMPTY ) As Property_DB_Type

	Var iIndex = Property_Binary_Find ( Property_DB ( ) , sName )
	
	If iIndex GEQ ZERO Then
		Property_Database_Query = Property_DB( iIndex )
		Exit Function

	Else
		Property_Database_Query = Bogus
		Exit Function
	End If
	
End Function

Function Property_Database_Set Overload ( Property_DB ( Any ) As Property_DB_Type , sName As String = EMPTY , sValue As String = EMPTY ) As Long

	Dim As Long uNewPos = Any
	
	Var iIndex = Property_Binary_Find( Property_DB ( ) , sName , uNewPos )    
	
	If iIndex GEQ ZERO Then 'replace if found
		Property_DB ( iIndex ).Value = sValue
		Property_Database_Set = iIndex
	End If
		
	Dim As Long lo = LBound ( Property_DB, POSONE ), hi = UBound ( Property_DB, POSONE )
	
	If uNewPos NEQ ( hi + POSONE ) Then

		Property_Inc_Capacity ( Property_DB ( ), POSONE )

		memmove( @Property_DB( uNewPos + POSONE ), @Property_DB( uNewPos ), ( ( hi - uNewPos ) - POSONE ) *SizeOf( Property_DB( ZERO ) ) )
		memset( @Property_DB( uNewPos ), ZERO, SizeOf( Property_DB( ZERO ) ) )
	
	End If
	
	With Property_DB ( uNewPos )
		.Iterator = NEGONE
		.Label = sName
		.Value = sValue
	End With
	
	Property_Database_Set = uNewPos    
	Exit Function

End Function

Function Property_Database_Set Overload ( Property_DB ( Any ) As Property_DB_Type , sName As String = EMPTY , sValue As LongInt = ZERO ) As Long

	Property_Database_Set = Property_Database_Set ( Property_DB ( ), sName, Str ( sValue ) )
	Exit Function

End Function

Function Property_Database_Set Overload ( Property_DB ( Any ) As Property_DB_Type , sName As String = EMPTY , sValue As FB.Image Ptr ) As Long

	Property_Database_Set = Property_Database_Set ( Property_DB ( ), sName, Str ( @sValue ) )
	Exit Function

End Function

Function Property_Database_Delete ( Property_DB ( Any ) As Property_DB_Type , sName As String = EMPTY ) As Long    
	
	Var iIndex = Property_Binary_Find( Property_DB ( ) , sName )    
	
	If iIndex LSS ZERO Then
		Property_Database_Delete = iIndex 'failed
	End If
	
	With Property_DB(iIndex)
		.Label = EMPTY : .Value = EMPTY 'clean strings before delete!!
	End With
	Var lo = LBound(Property_DB), hi = UBound(Property_DB)    
	memmove( @Property_DB(iIndex), @Property_DB(iIndex+POSONE) , ((hi-iIndex))*SizeOf(Property_DB(ZERO)) )
	memset( @Property_DB(hi) , ZERO , SizeOf(Property_DB(ZERO)) )
	
	lo = LBound ( Property_DB, POSONE )
	hi = UBound ( Property_DB, POSONE )

	Property_Inc_Capacity( Property_DB ( ), NEGONE )
	
	Property_Database_Delete = iIndex
	Exit Function

End Function

Sub Property_Database_Save ( Property_DB ( Any ) As Property_DB_Type, Filename As String = EMPTY )
	
	SimpleSleep ( VGA_Table ( ) )
	
	Dim As String Buffer
	Buffer = EMPTY
	
	Property_Database_Export( Property_DB ( ), Buffer )

	SimpleSleep ( VGA_Table ( ) )

	Property_Save_Raw_Buffer( Buffer, Filename )

	SimpleSleep ( VGA_Table ( ) )

End Sub

Sub Property_Database_Load ( Property_DB ( Any ) As Property_DB_Type, Filename As String = EMPTY )
	
	Filename = prefix(Property_DB_EXT,Filename) & Property_DB_EXT

	Dim As String Buffer
	Buffer = EMPTY
	
	Property_Load_Raw_Buffer( Buffer, Filename )
	
	Property_Database_Import( Property_DB ( ), Buffer )

End Sub

Function Property_Database_Export ( Property_DB ( Any ) As Property_DB_Type, ByRef Buffer As String = EMPTY ) As String
		
	'Buffer = EMPTY

	Property_Bubble_Sort( Property_DB ( ) )
		
	For Iterator As Long = LBound ( Property_DB, POSONE ) to UBound ( Property_DB, POSONE ) Step POSONE
		
		If Property_DB ( Iterator ).Label NEQ EMPTY And Property_DB ( Iterator ).Value NEQ EMPTY Then

			Buffer = Property_DB_CRLF_Buffer ( Buffer )
						
			Buffer &= Property_DB ( Iterator ).Label & EQ & Property_DB ( Iterator ).Value				
			
		End If
		
	Next Iterator
	
	Property_Database_Export = Buffer
	Exit Function
	
End Function

Sub Property_Database_Import ( Property_DB ( Any ) As Property_DB_Type, ByRef Buffer As String = EMPTY )
	
	Dim As String Property_Line
	Property_Line = EMPTY
	
	Property_Erase Property_DB ( )
	
	While Len( Buffer ) GTR ZERO
		
		Property_Line = Prefix( CRLF, Buffer )
		Buffer = Suffix( CRLF, Buffer )
			
		If StrPos( EQ, Property_Line ) GTR ZERO Then
			
			Property_Inc_Capacity( Property_DB ( ), POSONE )
		
			With Property_DB( UBound ( Property_DB, POSONE ) )
				
				.Iterator = NEGONE
				.Label = Prefix( EQ, Property_Line )
				.Value = Suffix( EQ, Property_Line )
				
				
				if DBDebugEnabled NEQ ZERO then
					Color RGBA ( 63, 255, 63, 255 )
					Print QUOT & .Label & QUOT & EQ & QUOT & .Value & QUOT
				
					SimpleSleep ( VGA_Table ( ) )
				end if
			
			End With
				
		End If
			
	Wend
		
	Property_Bubble_Sort( Property_DB ( ) )
	
End Sub

Sub Property_Save_Raw_Buffer ( ByRef Buffer As String = EMPTY, Filename As String = EMPTY )
		
	If Is_File( Filename ) Then
		Kill Filename
	End If

	Dim As Long Filemode = Freefile
				
	If Open(Filename For Binary As #Filemode) then
		Close #Filemode
		Exit Sub
	end if
		
	Put #Filemode, Lof ( Filemode ) + POSONE,Buffer
				
	Close #Filemode
			
End Sub

Sub Property_Load_Raw_Buffer ( ByRef Buffer As String = EMPTY, Filename As String = EMPTY )

	Dim As Long Filemode = Freefile
	
	Filename = prefix(Property_DB_EXT,Filename) & Property_DB_EXT
	
	If Is_File( Filename ) then
		
		If Open ( Filename For Binary As #Filemode ) then
			Close #Filemode
			Exit Sub
		End If
		
		Buffer = String ( Lof ( Filemode ), SP )
		
		If Lof ( Filemode ) GTR ZERO Then
		
			Get #Filemode, POSONE, Buffer
		
		End If
		
		Close #Filemode
				
	End If
	
End Sub

Declare Function Property_Request ( Property_DB ( Any ) As Property_DB_Type, Request As Property_DB_Type, Mode As Long ) As Property_DB_Type

Function Property_Request ( Property_DB ( Any ) As Property_DB_Type, Request As Property_DB_Type, Mode As Long ) As Property_DB_Type
	
	Dim As Long Iterator = NEGONE
	
	Select Case Mode
	Case Property_DB_CLR
		
		For Iterator = UBound ( Property_DB, POSONE ) To LBound ( Property_DB, POSONE ) Step NEGONE
			
			With Property_DB ( Iterator )
				.Label = EMPTY
				.Value = EMPTY
				.Iterator = NEGONE
				.Image = ImageDestroy2 ( .Image )
			End With
			
			ReDim Preserve Property_DB ( UBound ( Property_DB, POSONE ) - POSONE To LBound ( Property_DB, POSONE ) )
			
		Next Iterator
		
		Erase Property_DB
		
		Property_Request = Bogus
		Exit Function
		
	Case Property_DB_GET, Property_DB_PEEK

		With Request
			Request = Property_Database_Query ( Property_DB ( ), .Label )		
		End With

	Case Property_DB_POP
	
		With Request
			.Iterator = Property_Database_Delete ( Property_DB ( ), .Label )
		End With

		Property_Request = Bogus
		Exit Function

	Case Property_DB_SET, Property_DB_POKE
		
		With Request
			.Iterator = Property_Database_Set ( Property_DB ( ), .Label, .Value )
		End With
		
	End Select
	
	Property_Request = Request
	Exit Function
	
End Function
