

Class CollectionSEClass
    Private m_Storage

    Private Sub Class_Initialize()
	    Set m_Storage = CreateObject("Scripting.Dictionary")
	    Clear
    End Sub

'///////////////////////////////////////////////////////
	Function ExcapeParam(s, r)
	    rr = Array("+", ",")
		ExcapeParam = s
		If IsNull(ExcapeParam) then 
		    ExcapeParam = ""
		    Exit Function
		End if
		ExcapeParam = HideChars(ExcapeParam,r)
		ExcapeParam = HideChars(ExcapeParam,rr)
		ExcapeParam = Escape(ExcapeParam)
	End Function	

	Function UnExcapeParam(s, r)
	    rr = Array("+", ",")
		If IsNull(s) then 
		    UnExcapeParam = ""
		    Exit Function
		End if
		UnExcapeParam = Unescape(s)
		UnExcapeParam = UnhideChars(UnExcapeParam, r)
		UnExcapeParam = UnhideChars(UnExcapeParam, rr)
	End Function		
	
	Public Function AppendFromArray(a)
	    For i=LBound(a) To UBound(a)
	        if Trim(a(i)) <> "" then
	            Add "a" & a(i), a(i)
	        end if
	    Next    
	End Function

	Public Sub SplitEx([String], Delimiter1, Delimiter2)
		Set rex = New RegExp
		rex.IgnoreCase = True
		rex.Global = True
		d1 = Delimiter1
		d2 = Delimiter2
		If d1 = "\" Then d1 = "\\"
		If d2 = "\" Then d2 = "\\"
		rex.Pattern = "([^" & d1 & "^" & d2 & "]*)" & d1 & "([^" & d2 & "]*)" & d2 & "?"
		Set Matches = rex.Execute([String])
		For each match in Matches
		    If match.value <> "" and match.SubMatches.Count = 2 Then
		        Add Trim(match.SubMatches(0)), UnExcapeParam(match.SubMatches(1), Array(Delimiter2, Delimiter1))
		    End if
		Next
	End Sub

	Public Sub SplitCookie([String])
	    SplitEx [String],"=",";"
	End Sub
	
	Public Sub SplitData([String])
		SplitEx [String],":",";"
	End Sub

	Public Sub SplitString([String], Delimiter)
		SplitEx [String],"=",Delimiter		
	End Sub

	Public Function JoinForQuery(sOperation)' As String
	    If Count = 0 Then
	        JoinForQuery = ""
	    Else
		    If Count > 1 Then
		        For i=1 to Count - 1
			        JoinForQuery = JoinForQuery & " ( " & Me.Item(Me.Key(i)) & " ) " & " " & sOperation & " "
		        Next
		    End if
		    JoinForQuery = JoinForQuery & " ( " & Me.Item(Me.Key(Me.Count)) & " ) "
		End if
	End Function
	
	Public Function JoinEx(Delimiter1, Delimiter2)' As String
		For i=1 to Count
			JoinEx = JoinEx & Me.Key(i) & Delimiter1 & ExcapeParam(Me.Item(Me.Key(i)), Array(Delimiter2, Delimiter1)) & Delimiter2
		Next
	End Function

	Public Function JoinCookie()' As String
		JoinCookie = JoinEx ("=", ";")
	End Function

	Public Function JoinData()' As String
		JoinData = JoinEx (":", ";")
	End Function

	Public Function Join(Delimiter)' As String
		Join = JoinEx ("=", ";")
	End Function
	
	' //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	Public Function Dublicate()
	    Dim i
	    Dim tmp
	    Set tmp = New CollectionSEClass
	    For i=1 to Me.Count
	        tmp.Add Me.Key(i), Me.Item(i)
	    Next
	    Set Dublicate = tmp
	End Function

    Public Property Get Count()
	    Count = m_Storage.Count
    End Property

    Public Function GetKey(ByVal k)
		If IsNumeric(k) Then
			GetKey = Me.Key(CLng(k))
		Else
			GetKey = LCase(k)
		End If
    End Function
    
    Public Property Get Index(K)
        Dim i
        keys = m_Storage.Keys()
        For i=lbound(keys) to ubound(keys)
            if K = keys(i) then 
                Index = i+1
                Exit Property
            End if
        next
        Index = -1
    End Property
    
    Public Property Get Key(Index)
		Key = m_Storage.Keys()(Index - 1)
    End Property

    Public Property Get Name(Index)
		Name = Key(Index)
    End Property
    
    Public Property Get Value(k)
        Value = Item(k)
    End Property
    
    Public Property Let Value(k, V)
        [Set] k, Value
    End Property

    Public Property Set Value(k, V)
        [Set] k, Value
    End Property

    Public Default Property Get Item(k)
        If Not Exists(GetKey(k)) then
            Item = ""
        Else
		    If IsObject(m_Storage.Item(GetKey(k))) Then
			    Set Item = m_Storage.Item(GetKey(k))
		    Else
			    Item = m_Storage.Item(GetKey(k))
		    End If
		End if
    End Property

    Private Function GenerateKey()
		GenerateKey = "key" & CStr(Int(random(10000, 9999999.999999)))
	End Function

	Public Sub [Set](byVal k, Value)
		If IsObject(Value) Then
			Set m_Storage.Item(GetKey(k)) = Value
		Else
			m_Storage.Item(GetKey(k)) = Value
		End If
	End Sub
	
    Public Sub Add(ByVal k, Item)
        If k = "" Then k = GenerateKey()

        if Exists(k) then
            [Set] k, Item
        else
            m_Storage.Add LCase(k), Item
	    End if
    End Sub
    
    Public Function Exists(k)
	    Exists = m_Storage.Exists(GetKey(k))
    End Function

    Public Sub Remove(k)
        If Exists(k) then
            m_Storage.Remove GetKey(k)
	    end if
    End Sub

    Function Find(val)
        Dim i
        Find = -1
        For i=1 to m_Storage.Count
            if m_Storage.Item(i) = val then
                Find = i
                Exit For
            end if
        Next
        
    End Function

    Public Sub Clear()
		m_Storage.RemoveAll()
    End Sub

    Private Sub Class_Terminate()
	    Clear
	    Set m_Storage = Nothing
    End Sub
    
    Private Function CompareIfStrings(b, s1, s2)
        CompareIfStrings = False
        If b then
            If s1 < s2 Then
                CompareIfStrings = True
            Else
                CompareIfStrings = False
            End if
        Else
            If s1 > s2 Then
                CompareIfStrings = True
            Else
                CompareIfStrings = False
            End if
        End if
                
    End Function
    
    Private Function FindMaxMin(bMax, CallBack_Compare)
        Dim ret, i, b
        
        If m_Storage.Count > 0 Then
            
            ret = 0
            
            For i=1 to m_Storage.Count - 1

                If IsObject(CallBack_Compare) Then
                    b = CallBack_Compare(bMax, m_Storage(m_Storage.Keys()(i)), m_Storage(m_Storage.Keys()(ret)))
                Else
                    b = CompareIfStrings(bMax, m_Storage(m_Storage.Keys()(i)), m_Storage(m_Storage.Keys()(ret)))
                End if
                
                If b Then
                    ret = i
                End if

            Next
            
        End if        
        
        FindMaxMin = ret
    End Function
    
    Public Function Sort(bAsc, CallBack_Compare)
        Dim iIndex, tmpStorage
        
        Set tmpStorage = CreateObject("Scripting.Dictionary")
        
        While m_Storage.Count > 0

            iIndex = FindMaxMin(Not bAsc, CallBack_Compare)
            
            tmpStorage.Add m_Storage.Keys()(iIndex), m_Storage(m_Storage.Keys()(iIndex))
            m_Storage.Remove m_Storage.Keys()(iIndex)
            
        Wend
        
        Set m_Storage = Nothing
        Set m_Storage = tmpStorage
        
    End Function    


    '// serverside functions
    
    Function ToSession(name)
        Set Session(name) = m_Storage
    End Function

    Function FromSession(name)
        Set m_Storage = Session(name)
    End Function

End Class
