'DDV - Validation functions

function DDVM_String(Ctrl, sMsg)
	DDVM_String = False
	if (Ctrl.value = "") then
		DDVM_String = True
	end if
	
	if DDVM_String then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_StringMax(Ctrl, nMaxLen, sMsg)
	DDVM_StringMax = DDVM_String(Ctrl, sMsg)
	if DDVM_StringMax then exit function
	
	if Len(Ctrl.value) > nMaxLen then
		DDVM_StringMax = true
	end if
	
	if DDVM_StringMax then
		if sMsg <> "" then MsgBox Replace(sMsg, "%1", nMaxLen)
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_Numeric(Ctrl, sMsg)
	DDVM_Numeric = False
	if not IsNumeric(Ctrl.value) then
		DDVM_Numeric = True
	end if
	
	if DDVM_Numeric then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_NumericMin(Ctrl, nMin, sMsg)
	DDVM_NumericMin = False
	if not IsNumeric(Ctrl.value) then
		DDVM_NumericMin = True
	elseif CDbl(Ctrl.value) < CDbl(nMin) then
		DDVM_NumericMin = True
	end if
	
	if DDVM_NumericMin then
		if sMsg <> "" then MsgBox Replace(sMsg, "%1", nMin)
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_NumericMax(Ctrl, nMax, sMsg)
	DDVM_NumericMax = False
	if not IsNumeric(Ctrl.value) then
		DDVM_NumericMax = True
	elseif CDbl(Ctrl.value) > CDbl(nMax) then
		DDVM_NumericMax = True
	end if
		
	if DDVM_NumericMax then
		if sMsg <> "" then MsgBox Replace(sMsg, "%1", nMax)
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_NumericMinMax(Ctrl, nMin, nMax, sMsg)
	DDVM_NumericMinMax = False
	if not IsNumeric(Ctrl.value) then
		DDVM_NumericMinMax = True
	elseif CDbl(Ctrl.value) < CDbl(nMin) or CDbl(Ctrl.value) > CDbl(nMax) then
		DDVM_NumericMinMax = True
	end if
		
	if DDVM_NumericMinMax then
		if sMsg <> "" then MsgBox Replace(Replace(sMsg, "%1", nMin), "%2", nMax)
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_Long(Ctrl, sMsg)
	DDVM_Long = False
	if not IsNumeric(Ctrl.value) then
		DDVM_Long = True
	else
		if CDbl(Ctrl.value) > 2147483647 then
			DDVM_Long = True
		else
			if CDbl(Ctrl.value) <> CLng(Ctrl.value) then
				DDVM_Long = True
			end if
		end if
	end if

	if DDVM_Long then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_DateTime(Ctrl, sMsg)
	DDVM_DateTime = False
	if not IsDate(Ctrl.value) then
		DDVM_DateTime = True
	else
		Ctrl.value = CDate(Ctrl.value)
	end if
		
	if DDVM_DateTime then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

function DDVM_DateTimeMin(Ctrl, dtMinDate, sMsg)
	sMsg = Replace(sMsg, "%1", dtMinDate)
	DDVM_DateTimeMin = DDVM_DateTime(Ctrl, sMsg)
	if DDVM_DateTimeMin then exit function
	
	if CDate(Ctrl.value) < CDate(dtMinDate) then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
		DDVM_DateTimeMin = true
	end if
end function 

function DDVM_DateTimeMax(Ctrl, dtMaxDate, sMsg)
	sMsg = Replace(sMsg, "%1", dtMaxDate)
	DDVM_DateTimeMax = DDVM_DateTime(Ctrl, sMsg)
	if DDVM_DateTimeMax then exit function
	
	if CDate(Ctrl.value) > CDate(dtMaxDate) then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
		DDVM_DateTimeMax = true
	end if
end function 

function DDVM_DateTimeSpan(Ctrl1, Ctrl2, nMaxSpan, sMsgInvalid, sMsgTooLong)
	DDVM_DateTimeSpan = False

	Dim curSpan, txt
	curSpan = CDate(Ctrl2.value) - CDate(Ctrl1.value)

	if curSpan <= 0 then
		if sMsgInvalid <> "" then MsgBox sMsgInvalid
		DDVM_DateTimeSpan = True
		on error resume next
	    Ctrl1.focus()
	elseif curSpan >= nMaxSpan then
		txt = Replace(sMsgTooLong, "%1", nMaxSpan)
		if sMsgTooLong <> "" then
			if MsgBox(txt, vbYesNo + vbQuestion + vbDefaultButton2) <> vbYes then
				DDVM_DateTimeSpan = True
        		on error resume next
	            Ctrl1.focus()
			end if
		end if
	end if
end function 

function DDVM_Select(ctrl, sMsg)
	DDVM_Select = false
	if ctrl.value = "" then
		DDVM_Select = true
		if sMsg <> "" then MsgBox sMsg
		on error resume next
	    ctrl.focus
	end if
end function

function DDVM_RGB(Ctrl, sMsg)
	Set re = new regexp
	re.Pattern = "^[0-9a-fA-F]{6}$"
	re.IgnoreCase = true
	
	DDVM_RGB = False
	if not re.Test(Ctrl.value) then
		DDVM_RGB = True
	end if
		
	if DDVM_RGB then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 

'!!! String versions

function DDV_String(Ctrl)
	DDV_String = DDVM_String(Ctrl, "Value cannot be empty!")
end function 

function DDV_StringMax(Ctrl, nMaxLen)
	DDV_StringMax = DDVM_StringMax(Ctrl, nMaxLen, "Insert string with the maximum of %1 characters!")
end function 

function DDV_Numeric(Ctrl)
	DDV_Numeric = DDVM_Numeric(Ctrl, "Insert number!")
end function 

function DDV_NumericMin(Ctrl, nMin)
	DDV_NumericMin = DDVM_NumericMin(Ctrl, nMin, "Insert number greater than or equal to %1!")
end function 

function DDV_NumericMax(Ctrl, nMax)
	DDV_NumericMax = DDVM_NumericMax(Ctrl, nMax, "Insert number less than or equal to %1!")
end function 

function DDV_NumericMinMax(Ctrl, nMin, nMax)
	DDV_NumericMinMax = DDVM_NumericMinMax(Ctrl, nMin, nMax, "Insert number between %1 and %2!")
end function 

function DDV_Long(Ctrl)
	DDV_Long = DDVM_Long(Ctrl, "Insert integer less than 2147483647!")
end function 

function DDV_DateTime(Ctrl)
	DDV_DateTime = DDVM_DateTime(Ctrl, "Insert date!")
end function 

function DDV_DateTimeMin(Ctrl, dtMinDate)
	DDV_DateTimeMin = DDVM_DateTimeMin(Ctrl, dtMinDate, "Insert date greater than or equal to %1!")
end function 

function DDV_DateTimeMax(Ctrl, dtMaxDate)
	DDV_DateTimeMax = DDVM_DateTimeMax(Ctrl, dtMaxDate, "Insert date less than or equal to %1!")
end function 

function DDV_DateTimeSpan(Ctrl1, Ctrl2, nMaxSpan)
	DDV_DateTimeSpan = DDVM_DateTimeSpan(Ctrl1, Ctrl2, nMaxSpan, "Invalid date period!", _
		"Date period is longer than %1 days." & vbcrlf & "Are you sure to use it?")
end function 

function DDV_Select(ctrl)
	DDV_Select = DDVM_Select(ctrl, "Select an item!")
end function

function DDV_RGB(ctrl)
	DDV_RGB = DDVM_RGB(ctrl, "Wrong format of RGB!")
end function

function DDV_StringRegex(Ctrl, sPattern, sMsg)
	Set re = new regexp
	re.Pattern = sPattern
	re.IgnoreCase = true

	DDV_StringRegex = False
	if not re.Test(Ctrl.value) then
		DDV_StringRegex = True
	end if
		
	if DDV_StringRegex then
		if sMsg <> "" then MsgBox sMsg
		on error resume next
		Ctrl.select
	    Ctrl.focus()
	end if
end function 