#include Once "window9.bi"

Type TSTACKNODE
	
	As Any Ptr xValue
	
	As TSTACKNODE Ptr pNext =0
	
End Type

Type TSTACK
	
	Declare Sub push(As Any Ptr)
	
	Declare Function pop(bFlagFreeMemoryStrings As Long = 0) As Any Ptr
	
	Declare Function front() As Any Ptr
	
	Declare Function size() As Long
	
	As Long iSize =0
	
	As TSTACKNODE Ptr pFirst =0
	
End Type

Sub TSTACK.push(xParam As Any Ptr)
	
	Dim As TSTACKNODE Ptr pTemp =New TSTACKNODE
	
	if pTemp then
		
		pTemp->xValue =xParam
		
		If pFirst =0 Then
			
			pFirst =pTemp
			
			iSize =1
			
		Else
			
			pTemp->pNext =pFirst
			
			pFirst =pTemp
			
			iSize +=1
			
		Endif
		
	else
		
		print "Allocated memory error in TSTACK.push!"
		
	endif
	
End Sub

Function TSTACK.pop(bFlagFreeMemoryStrings As Long = 0) As Any Ptr
	
	If iSize Andalso pFirst Then
		
		Dim As TSTACKNODE Ptr p =pFirst->pNext
		
		If bFlagFreeMemoryStrings Then
			
			If pFirst->xValue Then
				
				Deallocate(pFirst->xValue)
				
				Function = 0
				
			Endif
			
		Else
			
			Function =pFirst->xValue
			
		Endif
		
		Delete(pFirst)
		
		pFirst =p
		
		iSize -=1
		
	Endif
	
End Function

Function TSTACK.front() As Any Ptr
	
	If pFirst Then
		
		Return pFirst->xValue
		
	Endif
	
End Function

Function TSTACK.size() As Long
	
	Return iSize
	
End Function

Function CreateStack() As Any Ptr
	
	Return New TSTACK
	
End Function

Function GetSizeStack(p As Any Ptr) As Long
	
	If p Then
		
		Return Cast(TStack Ptr , p)->iSize
		
	Endif
	
End Function

Function PopStack(p As Any Ptr , bFlagFreeMemoryStrings As Long = 0) As Any Ptr
	
	If p Then
		
		Return Cast(TStack Ptr , p)->pop(bFlagFreeMemoryStrings)
		
	Endif
	
End Function

Sub PushStack(p As Any Ptr  , anyValue As Any Ptr)
	
	If p Then
		
		Cast(TStack Ptr , p)->push(anyValue)
		
	Endif
	
End Sub

Sub PushStrStack(p As Any Ptr  , anyValue As USTRING)
	
	If p Then
		
		#ifdef UNICODE
			Dim As Long iLen = Len(anyValue)
		#else
			Dim As Long iLen = Len(anyValue)
		#endif
		
		If iLen Then
			
			#ifdef UNICODE
				
				Dim As Wstring Ptr pws = Allocate(Sizeof(Wstring)*(iLen+1))
				
			#else
				
				Dim As Zstring Ptr pws = Allocate(iLen+1)
				
			#endif
			
			if pws then
				
				*pws = anyValue
				
				(*pws)[iLen] = 0
				
			else
				
				print "Allocated memory error in PushStrStack!"
				
			endif
			
			Cast(TStack Ptr , p)->push(pws)
			
		Else
			
			Cast(TStack Ptr , p)->push(0)
			
		Endif
		
	Endif
	
End Sub

Function FrontStack(p As Any Ptr) As Any Ptr
	
	If p Then
		
		Return Cast(TStack Ptr , p)->front()
		
	Endif
	
End Function

Function FrontStrStack(p As Any Ptr) As USTRING
	
	If p Then
		
		Dim As USTRING sRet
		
		#ifdef UNICODE
			Dim As Wstring Ptr pTemp = Cast(TStack Ptr , p)->front()
		#else
			Dim As Zstring Ptr pTemp = Cast(TStack Ptr , p)->front()
		#endif
		
		If pTemp Then
			
			sRet = *pTemp
			
		Endif
		
		Return sRet
		
	Endif
	
End Function

Sub FreeStack(p As Any Ptr , bFlagFreeMemoryStrings As Long = 0)
	
	If p Then
		
		For i As Long = 1 To Cast(TStack Ptr , p)->iSize
			
			Cast(TStack Ptr , p)->pop(bFlagFreeMemoryStrings)
			
		Next
		
	Endif
	
End Sub

Sub DeleteStack(p As Any Ptr , bFlagFreeMemoryStrings As Long = 0)
	
	If p Then
		
		For i As Long = 1 To Cast(TStack Ptr , p)->iSize
			
			Cast(TStack Ptr , p)->pop(bFlagFreeMemoryStrings)
			
		Next
		
		Delete Cast(TStack Ptr , p)
		
	Endif
	
End Sub
