'Classes/System/Collections/Generic/Dictionary.ab

'#require <Classes/System/Collections/Generic/EqualityComparer.ab>

Namespace System
Namespace Collections
Namespace Generic

Namespace Detail
	Class Pair
	Public
		Sub Pair(key As Object, value As Object)
			Key = key
			Value = value
		End Sub

		Key As Object
		Value As Object
	End Class
End Namespace 'Detail

Class Dictionary<Key, T>
Public
	'Constructor
	Sub Dictionary()
		initialize(23)
	End Sub
'	Sub Dictionary(d As IDictionary<Key, T>)
'	Sub Dictionary(comparer As IEqualityComparer<Key>)
	Sub Dictionary(capacity As Long)
		initialize(capacity)
	End Sub
'	Sub Dictionary(d As IDictionary<Key, T>, comparer As IEqualityComparer<Key>)
'	Sub Dictionary(capacity As Long, comparer As IEqualityComparer<Key>)

	'Properties
'	Function Comparer() As IEqualityComparer<Key>
'	Virtual Function Count() As Long
'	End Function

	Virtual Function Item(key As Key) As T
		If ActiveBasic.IsNothing(key) Then
			Throw New ArgumentNullException("key")
		End If

		Dim hash = getHash(key)
		Dim a = al[hash] As ArrayList

		If Not ActiveBasic.IsNothing(a) Then
			Dim i As Long
			For i = 0 To ELM(a.Count)
				Dim pair = a[i] As Detail.Pair
				If pair.Key.Equals(key) Then
					Return pair.Value
				End If
			Next
		End If

		Throw New KeyNotFoundException
	End Function

	Virtual Sub Item(key As Key, value As T)
		If ActiveBasic.IsNothing(key) Then
			Throw New ArgumentNullException("key")
		End If

		Dim hash = getHash(key)
		Dim a = al[hash] As ArrayList

		If Object.ReferenceEquals(a, Nothing) Then
			a = New ArrayList
			al[hash] = a
		Else
			Dim i As Long
			For i = 0 To ELM(a.Count)
				Dim pair = a[i] As Detail.Pair
				If pair.Key.Equals(key) Then
					pair.Value = value
					Exit Sub
				End If
			Next
		End If

		a.Add(New Detail.Pair(key, value))
	End Sub

'	Function Keys() As KeyCollection
'	Function Values() As ValuesCollection
/*
	'Operators
'	Function Operator [](key As Key) As T
	Function Operator [](key As Key) As Object
		Return Item[key]
	End Function

	Sub Operator []=(key As Key, value As T)
'		Item[key] = vaule
	End Sub
*/
	'Methods
	Sub Add(key As Key, value As T)
		If ActiveBasic.IsNothing(key) Then
			Throw New ArgumentNullException("key")
		End If

		Dim hash = getHash(key)
		Dim a = al[hash] As ArrayList

		If ActiveBasic.IsNothing(a) Then
			a = New ArrayList
			al[hash] = a
		Else
			Dim i As Long
			For i = 0 To ELM(a.Count)
				Dim pair = a[i] As Detail.Pair
				If pair.Key.Equals(key) Then
					'Throw ArgumentError
				End If
			Next
		End If

		a.Add(New Detail.Pair(key, value))

		count++
	End Sub

	Sub Clear()
		Dim i As Long
		For i = 0 To ELM(al.Count)
			al[i] = Nothing
		Next
	End Sub

	Function Count() As Long
		Return count
	End Function

	/*!
	@biref	指定されたキーが格納されているか調べる。
	@date	2008/07/11
	@param[in] key	検索対象のキー
	@retval True	格納されていたとき
	@retval False	格納されていなかったとき
	@throw ArgumentNullException	keyがNothingだったとき
	@author Egtra
	*/
	Function ContainsKey(key As Key) As Boolean
		If ActiveBasic.IsNothing(key) Then
			Throw New ArgumentNullException("key")
		End If
		ContainsKey = False

		Dim hash = getHash(key)
		Dim a = al[hash] As ArrayList

		If Not ActiveBasic.IsNothing(a) Then
			Dim i As Long
			For i = 0 To ELM(a.Count)
				Dim pair = a[i] As Detail.Pair
				If pair.Key.Equals(key) Then
					ContainsKey = True
					Exit Function
				End If
			Next
		End If
	End Function

'	Function ContainsValue(value As T) As Boolean
'	End Function
'	Function GetEnumerator() As Enumerator

	/*!
	@biref	指定されたキーの要素を削除する。
	@date	2008/07/11
	@param[in] key	削除対象のキー
	@retval True	対象要素が見つかって削除されたとき
	@retval False	見つからず削除されなかったとき
	@author Egtra
	*/
	Function Remove(key As Key) As Boolean
		Remove = False
		If Not ActiveBasic.IsNothing(key) Then
			Dim hash = getHash(key)
			Dim a = al[hash] As ArrayList
			If Not ActiveBasic.IsNothing(a) Then
				Dim i As Long
				For i = 0 To ELM(a.Count)
					Dim pair = a[i] As Detail.Pair
					If pair.Key.Equals(key) Then
						a.RemoveAt(i)
						Remove = True
						count--
						Exit Function
					End If
				Next
			End If
		End If
	End Function

	Function TryGetValue(key As Key, ByRef value As T) As Boolean
		If ActiveBasic.IsNothing(key) Then
			Throw New ArgumentNullException("key")
		End If
		TryGetValue = False
		value = Nothing

		Dim hash = getHash(key)
		Dim a = al[hash] As ArrayList

		If Not ActiveBasic.IsNothing(a) Then
			Dim i As Long
			For i = 0 To ELM(a.Count)
				Dim pair = a[i] As Detail.Pair
				If pair.Key.Equals(key) Then
					TryGetValue = True
					value = pair.Value
					Exit Function
				End If
			Next
		End If
	End Function

	'Classses
'	Class KeyCollection
'	Class ValuesCollection
'	Class Enumerator

Private

'	comp As System.Collections.Generic.Detail.DefaultEqualityComparer<Key> 'IEqualityComparer<Key>

	Sub initialize(c As Long)
		al = ArrayList.Repeat(Nothing, c)
		count = 0
	End Sub

	Function getHash(key As Object) As Long
		Return (key.GetHashCode As DWord) Mod al.Count
	End Function

	al As ArrayList
	count As Long

End Class

End Namespace 'Generic
End Namespace 'Collections
End Namespace 'System
