'Script Copyright  2012 Ryan Marshall (Skarn)
'All Rights Reserved

Dim dxs

'current date variables
Dim selected_year
Dim selected_month
Dim selected_date
Dim selected_day
Dim selected_month_day_count
Dim todays_date

'holds whether month selecting is on
Dim month_selector_active

'where the calendar settings are kept
Dim iniCalendar

'calendar object references
Dim objDateTemplate
Dim objDayTemplate
Dim objMonthText
Dim objYearText

Sub Object_OnScriptEnter()
	On Error Resume Next
	Call dxInit()
End Sub

Sub dxInit()
	Set dxs 				= DesktopX.ScriptObject("dxScriptor")
	Set objDateTemplate 	= DesktopX.Object("calander_date_template")
	Set objDayTemplate 		= DesktopX.Object("calander_day_template")
	Set objMonthText 		= DesktopX.Object("calander_month_text")
	Set objYearText 		= DesktopX.Object("calander_year")
	
	Call store_date(Date())
	todays_date = Date()
	Call loadSettings()
	Call set_monthyear_text
	
	Object.Visible = True
End Sub

Function Object_OnDragFinishEx(obj)
	Select Case obj.Name
		Case "calendar_pos","calander_day_template"
			Call loadSettings()
		
	End Select
End Function

Sub Object_OnSizeEx(obj,width, height)
	Select Case obj.Name
		Case "calendar_pos"
			Call loadSettings()
		
	End Select
End Sub

Sub Object_OnScriptExit()
	On Error Resume Next
	objDayTemplate.Visible = True
	objDateTemplate.Visible = True
	
	'dates text
	For a = 1 To 31
		If DesktopX.IsObject("calander_date"&a) = True Then
			DesktopX.Object("calander_date"&a).Delete
		End If
	Next
	
	'day text
	For a = 1 To 7
		If DesktopX.IsObject("calander_day"&a) = True Then
			DesktopX.Object("calander_day"&a).Delete
		End If
	Next
End Sub

Sub loadSettings()
	dayYOffset 		= DesktopX.Object("calander_day_template").Top
	dateGridYOffset = DesktopX.Object("calendar_pos").Top
	dateGridXOffset	= DesktopX.Object("calendar_pos").Left
	dateGridXGap 	= DesktopX.Object("calendar_pos").Width
	dateGridYGap 	= DesktopX.Object("calendar_pos").Height

	'redraw the calendar
		'day text
		For a = 1 To 7
			If DesktopX.IsObject("calander_day"&a) = True Then
				DesktopX.Object("calander_day"&a).Delete
			End If
		Next
		
		For column = 1 To 7
			DesktopX.Object("calander_day_template").Clone "calander_day"&column, dateGridXOffset+dateGridXGap*(column-1), dayYOffset
			DesktopX.Object("calander_day"&column).Text = Left(WeekDayName(column,True,1),2)
			DesktopX.Object("calander_day"&column).Visible = True
		Next
		
		'dates text
		For a = 1 To 31
			If DesktopX.IsObject("calander_date"&a) = True Then
				DesktopX.Object("calander_date"&a).Delete
			End If
		Next
		
		first_day_of_month = DatePart("w", selected_month & "/" & "1" & "/"&selected_year)
		column = first_day_of_month-1
		row = 0
		
		For a = 1 To selected_month_day_count
			DesktopX.Object("calander_date_template").Clone "calander_date"&a, dateGridXOffset+dateGridXGap*column, dateGridYOffset+dateGridYGap*(row)
			DesktopX.Object("calander_date"&a).Text = CStr(a)
			DesktopX.Object("calander_date"&a).Visible = True
			
			'just the position variable updates to keep the date objects
			'in a nice grid.
			column = column + 1
			
			If column = 7 Then
				column = 0
				row = row+1
			End If
			
			If row >= 5 Then
				row = 0
			End If
		Next
		
		If DatePart("m", todays_date) = selected_month Then
			Call circle_date(DatePart("d", todays_date))
		Else
			DesktopX.Object("calander_circle").Visible = False
		End If
End Sub

Sub store_date(input_date)
	'this function just stores the currently selected date
	'details into the respective variables.
	'for reference, all variables hold numerical values
	'if the 'text' version of one of these variables is needed,
	'the date will be recombined and then a date function used
	'to extract the text name of a certain part of the date.
	selected_year = DatePart("yyyy", input_date)
	selected_month = DatePart("m", input_date)
	selected_date = DatePart("d", input_date)
	selected_day = DatePart("w", input_date)
	selected_month_day_count = days_in_month(selected_month)
End Sub

Function days_in_month(input_month)
	'this function returns the number of days in any month
	'according to the numerical value stored in selected_month
	
	'this function is identical/similar to other calander day count scripts
	'not because it is copied, but because they all use the same
	'generally available method for determining a leap year.
	'based on the 3 rules: evenly (no remainder) divide by 4 but not 100 as well = leap year
	'and evenly divisible by 400 = leap year
	
	Select Case input_month
		Case 9,4,6,11
			days_in_month = 30
		Case 1,3,5,7,8,9,10,12
			days_in_month = 31
		Case 2
			If (selected_year Mod 4 = 0) And (selected_year Mod 100 <> 0) Or (selected_year Mod 400 = 0) Then
				days_in_month = 29
			Else
				days_in_month = 28
			End If
	End Select
End Function

Sub circle_date(input_date)
	objDate_left = DesktopX.Object("calander_date"&input_date).Left
	objDate_top = DesktopX.Object("calander_date"&input_date).Top
	objDate_width = DesktopX.Object("calander_date"&input_date).Width
	objDate_height = DesktopX.Object("calander_date"&input_date).Height
	objCircle_width = DesktopX.Object("calander_circle").Width
	objCircle_height = DesktopX.Object("calander_circle").Height
	
	objCircle_left = objDate_left + objDate_width/2 - objCircle_width/2
	objCircle_top = objDate_top + objDate_height/2 - objCircle_height/2
	
	DesktopX.Object("calander_circle").Move objCircle_left,objCircle_top
	DesktopX.Object("calander_circle").Visible = True
End Sub

Sub Object_OnMouseEnterEx(obj)
	Select Case obj.Name
		Case "calander_next_month","calander_previous_month"
			'keeps the months changing objects visible if they are
			'being mouse overed
			Object.KillTimer 1
			DesktopX.Object("calander_next_month").Visible = 1
			DesktopX.Object("calander_previous_month").Visible = 1
			DesktopX.Object("calander_next_month").OnTop
			DesktopX.Object("calander_previous_month").OnTop
	End Select
End Sub

REM Sub Object_OnMouseLeaveEx(obj)
	REM 'Catches all mouse leave events for all calander objects
	REM Select Case obj.Name
		REM Case "calander_next_month","calander_previous_month"
			REM 'If the mouse leaves a month changer control
			REM 'then a Timer is set. If the timer expires without
			REM 'being refreshed by another mouse enter over the 
			REM 'month controls, then the controls are hidden.
			REM Object.SetTimer 1,2000
	REM End Select
REM End Sub

'Month control hide timer
REM Sub Object_OnTimer1
	REM month_selector_active = False
	REM DesktopX.Object("calander_next_month").Visible = 0
	REM DesktopX.Object("calander_previous_month").Visible = 0
	REM Object.KillTimer 1
REM End Sub

'Just sets the month label and year when they are changed.
Sub set_monthyear_text
	DesktopX.Object("calander_month_text").Text = MonthName(selected_month,False)
	DesktopX.Object("calander_year").Text = selected_year
End Sub

'set the previous month active
Sub previous_month
	selected_month = selected_month - 1
	If selected_month <= 0 Then
		selected_month = 12
		selected_year = selected_year - 1
	End If
	
	selected_month_day_count = days_in_month(selected_month)
	Call loadSettings()
	Call set_monthyear_text
End Sub

'set next month active
Sub next_month
	selected_month = selected_month + 1
	If selected_month >= 13 Then
		selected_month = 1
		selected_year = selected_year + 1
	End If
	
	selected_month_day_count = days_in_month(selected_month)
	Call loadSettings()
	Call set_monthyear_text
End Sub

Sub Object_OnLButtonUpEx(obj,x,y,dragged)
'catches all left click events for all calander objects
	REM Select Case Left(obj.Name,13)
		REM 'left click on date object changes the currently selected date
		REM 'the selected date is circled
		REM Case "calander_date"
		 REM selected_date = CInt(Mid(obj.Name,14,2))
		 REM Call circle_date(selected_date)
		 
	REM End Select
	
	'the next and previous month controls are triggered active
	'by clicking the month name
	'then, if nothing is done on them for a period of time, 
	'or the month is clicked again they go invisible
	
	Select Case obj.Name
		'next month, previous month and open the month selector controls
		Case "calander_previous_month"
			Call previous_month
		Case "calander_next_month"
			Call next_month
		Case "calander_month_text"
			REM If month_selector_active = True Then
				REM DesktopX.Object("calander_next_month").Visible = 0
				REM DesktopX.Object("calander_previous_month").Visible = 0
				REM month_selector_active = False
			REM Else
				REM Object.KillTimer 1
				REM DesktopX.Object("calander_next_month").Visible = 1
				REM DesktopX.Object("calander_previous_month").Visible = 1
				REM DesktopX.Object("calander_next_month").OnTop
				REM DesktopX.Object("calander_previous_month").OnTop
				REM month_selector_active = True
			REM End If
	End Select
End Sub