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

'------
'Initialize
Dim dxs
Dim initialized
Dim strScriptDirectory
Dim dxShortcutsXML
Dim dxEditXML
Dim dxEdit_allowDrag

Sub dxExit()
	On Error Resume Next
	
	'kill any resource timers and objects
	Object.KillTimer 1
	If Not IsEmpty(objRefresher) Then
		Call objRefresher.DeleteAll()
		Set objRefresher = Nothing
		Set objServicesCimv2 = Nothing
	End If
	
	Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers.xml")
	Call dxEditXML.Save(Object.Directory & "dxEdit.xml")
	
	Set eventPipeObjects = dxEditXML.selectNodes("//eventPipes/eventPipe")
	For each eventPipeObject in eventPipeObjects
		strObjectName = eventPipeObject.selectSingleNode("@name").text
		strPipeObjectName = eventPipeObject.selectSingleNode("@eventObject").text
		If DesktopX.IsObject(strObjectName) and DesktopX.IsObject(strPipeObjectName) Then
			DesktopX.Object(strObjectName).SetScript("")
		End If
	Next
	
	Set controlObjects = dxEditXML.selectNodes("//controls/control")
	For each controlObject in controlObjects
		strObjectName = controlObject.selectSingleNode("@name").text
		strScriptName = controlObject.selectSingleNode("@script").text
		strControlType = controlObject.selectSingleNode("@type").text
		If DesktopX.IsObject(strObjectName) Then
			If strScriptName <> "" Then
				On Error Resume Next
				Call DesktopX.ScriptObject(strObjectName).dxExit()
				Set obj = DesktopX.Object(strObjectName)
				obj.SetScript("")
			End If
			
			Select Case strControlType
				Case "dropLayer"
					If DesktopX.IsObject(strObjectName & "_magicScroller") Then
						DesktopX.Object(strObjectName & "_magicScroller").SetScript("")
					End If
					
			End Select
		End If
	Next
	
	DesktopX.Object("dxScriptor").SetScript("")
	DesktopX.Object("dxEdit_script").SetScript("")
	DesktopX.Object("dxPlayer").SetScript("")
End Sub

Sub dxInit()
	dxEdit_allowDrag = False
	strScriptDirectory = Object.Directory & "temp_scripts\"
	Set dxs = DesktopX.ScriptObject("dxScriptor")
	
	If DesktopX.IsObject("dxEdit_sink") Then
		DesktopX.Object("dxEdit_sink").SetScript(strScriptDirectory & "dxSWEBM.txt")
	End If
	
	Set dxEditXML = dxs.xmlLoadFile(Object.Directory & "dxEdit.xml")
	If dxEditXML.xml = "" Then
		Call dxEdit_restoreXML
		Exit Sub
	Else
		Call dxEdit_backupXML()
	End If
	
	Set dxShortcutsXML = dxs.xmlLoadFile(Object.Directory & "shortcutLayers.xml")
	If dxShortcutsXML.xml = "" Then
		Call dxShortcuts_restoreXML()
		Exit Sub
	Else
		Call dxShortcuts_backupXML()
	End If
	
	Set eventPipeObjects = dxEditXML.selectNodes("//eventPipes/eventPipe")
	For each eventPipeObject in eventPipeObjects
		strObjectName = eventPipeObject.selectSingleNode("@name").text
		strPipeObjectName = eventPipeObject.selectSingleNode("@eventObject").text
		If DesktopX.IsObject(strObjectName) and DesktopX.IsObject(strPipeObjectName) Then
			Call dxPipeEvents(strObjectName,strPipeObjectName)
		End If
	Next
	
	Set controlObjects = dxEditXML.selectNodes("//controls/control")
	For each controlObject in controlObjects
		strObjectName = controlObject.selectSingleNode("@name").text
		strScriptName = controlObject.selectSingleNode("@script").text
		strControlType = controlObject.selectSingleNode("@type").text
		If DesktopX.IsObject(strObjectName) Then
			Set obj = DesktopX.Object(strObjectName)
			obj.SetScript(strScriptDirectory & strScriptName)
			Select Case strControlType
				Case "dropLayer"
					If DesktopX.IsObject(strObjectName & "_magicScroller") Then
						Call dxPipeEvents(strObjectName & "_magicScroller",strObjectName)
					End If
					
			End Select
		End If
	Next
	
	On Error Resume Next
	Set objShell = CreateObject("Shell.Application")
	strPublicDocumentsPath = objShell.Namespace(&h2e).Self.Path
	For each obj in DesktopX.Objects
		If obj.Name <> Object.Name and obj.Name <> "" Then
			If dxs.filFileExists(Object.Directory & obj.Name & ".zip") Then
				If Not dxs.filFolderExists(strPublicDocumentsPath & "\Stardock\" & obj.Name & "\") Then
					MsgBox("DesktopX will now perform a once off unzip of files needed for this DesktopX theme." & chr(13) & chr(13) & "All files will be located in: " & chr(13) & strPublicDocumentsPath & "\Stardock\" & obj.Name)
					Call dxs.filCreateFolderPath(strPublicDocumentsPath & "\Stardock\" & obj.Name)
					Call dxs.zipUn(Object.Directory & obj.Name & ".zip",strPublicDocumentsPath & "\Stardock\" & obj.Name & "\")
				End If
			End If
			Call DesktopX.ScriptObject(obj.Name).dxInit()
			Err.Clear
		End If
	Next
	On Error Goto 0
	
	If DesktopX.IsObject("selectImage") Then
		Call dxs.dxDestroy("selectImage")
	End If
	
	initialized = True
End Sub

Sub dxEdit_backupXML()
	Call dxEditXML.Save(Object.Directory & "dxEdit_restore.xml")
End Sub

Sub dxShortcuts_backupXML()
	Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers_restore.xml")
End Sub

Sub dxEdit_restoreXML()
	restore = dxs.filFileCopy(Object.Directory & "dxEdit_restore.xml",Object.Directory,"dxEdit.xml")
	Call dxInit()
End Sub

Sub dxShortcuts_restoreXML()
	Call dxs.filFileCopy(Object.Directory & "shortcutLayers_restore.xml",Object.Directory,"shortcutLayers.xml")
	Call dxInit()
End Sub

Sub Object_OnScriptExit
	call dxExit()
End Sub

'Object events
Function Object_OnLButtonUpEx(obj,x,y,dragged)
	Select Case obj.Name
		Case "dxEdit_butt_addScript"
			Call dxCreateScriptObject("normal")
		
		Case "dxEdit_controls"
		
	End Select
End Function

Function Object_OnRButtonUpEx(obj,x,y,dragged)
	Object_OnRButtonUpEx = True
	Call menu_dxEdit
End Function

Sub Object_OnDragEx(obj,x,y,newX,newY)
	Select Case obj.Group
		Case "dxEdit_tools"
		
		Case Else
			obj.Left = obj.Left
			obj.Top = obj.Top

	End Select
End Sub

Function Object_OnStateChangedEx(obj,state)
	'used to initiate various control/animation functions
	arrState = Split(state,"_")
	strCommand = arrState(0)
	strObject = arrState(1)
	arrParams = Split(arrState(2),",")
	
	Select Case strCommand
		Case "fadeIn"
			Set obj = DesktopX.Object(strObject)
			intFrames = arrParams(0)
			intTimer = arrParams(1)
			Call animStart(obj,"fadeIn",intFrames,intTimer)
			
		Case "slideOut"
			Call dxs.anim_slideOut(strObject,arrParams(0))
			
		Case "slideIn"
			Call dxs.anim_slideIn(strObject,arrParams(0))
			
		Case "slideToggle"
			Call dxs.anim_slideToggle(strObject,arrParams(0))
			
	End Select
End Function

'dxEdit Support Functions
Function dxCreateObject(strType,strObjectName,strObjectParentName,blnContained,blnOnTop)	'not used
	If DesktopX.IsObject(strObjectName) Then
		Set dxCreateObject = DesktopX.Object(strObjectName)
		Exit Function
	End If
	
	strTemplateObjectName = "dxEdit_"
	Select Case strObjectParentName
		Case ""
			strTemplateObjectName = strTemplateObjectName & "parent"
			
		Case Else
			If blnContained = True Then
				strTemplateObjectName = strTemplateObjectName & "child"
			Else
				strTemplateObjectName = strTemplateObjectName & "cousin"
			End If
	End Select
	
	Select Case strType
		Case "text"
			strTemplateObjectName = strTemplateObjectName & "Text"
		
		Case "image"
			strTemplateObjectName = strTemplateObjectName & "Layer"
			
		Case "command"
			strTemplateObjectName = strTemplateObjectName & "Command"
			
	End Select
	
	Select Case blnOnTop
		Case True
			strTemplateObjectName = strTemplateObjectName & "OnTop"
		
	End Select
	
	Set objTemplate = DesktopX.Object(strTemplateObjectName)
	If strObjectParentName <> "" Then
		Set objTemplateParent = DesktopX.Object(objTemplate.ParentName)
		Set objParent = DesktopX.Object(strObjectParentName)
		objTemplate.Parent = objParent
	End If
	
	Call objTemplate.Clone(strObjectName,0,0)
	
	If strObjectParentName <> "" Then
		objTemplate.Parent = objTemplateParent
	End If
	
	Set dxCreateObject = DesktopX.Object(strObjectName)
End Function

Function dxPipeEvents(strObjectName,strPipeObjectName)	'sets the script of an object to pipe its events to another object
	Set objPipe = DesktopX.Object(strObjectName)
	objPipe.SetScript(strScriptDirectory & "dxEventPiper.txt")
	objPipe.Comments = strPipeObjectName
End Function

Function dxAddState(strObjectName,strStateName)	'not implemented
	'to add a state to an object it must be unloaded and reloaded.
End Function

Function dxExportObjectIni(strObjectName,strOutputPath)	'not implemented
	'load desktopx object ini template
	
	'read all the object properties and place into the ini template
	
	'save out the object ini as a dxpack
	
End Function

Function dxImageHeight(strFilePath)	'returns height of image file
	Set obj = DesktopX.Object("dxEdit_images")
	obj.Picture = strFilePath
	dxImageHeight = obj.Height
End Function

Function dxImageWidth(strFilePath)	'returns width of image file
	Set obj = DesktopX.Object("dxEdit_images")
	obj.Picture = strFilePath
	dxImageWidth = obj.Height
End Function

'controls
Function conCreateTreeView(strRootName,intX,intY,intW,intH,blnVisible)	'not functional
	'base
	Set base = dxCreateObject("image",strRootName,"",false,false)
	base.Picture = "box.png"
	Call base.SetMargins(1, 1, 1, 1, false, false)
	base.Resize intW,intH
	base.Move intX,intY
	base.Group = strRootName
	
	'treeTextBack
	Set treeTextBack = dxCreateObject("image",strRootName & "_treeTextBack",strRootName,true,false)
	treeTextBack.Picture = "box.png"
	Call treeTextBack.SetMargins(1, 1, 1, 1, false, false)
	treeTextBack.Resize 2000,2000
	treeTextBack.Move 0,0
	REM treeTextBack.Opacity = 1
	
	'treeText
	Set treeText = dxCreateObject("text",strRootName & "_treeText",strRootName & "_treeTextBack",true,false)
	treeText.Text = ""
	Call dxs.dxTextFontSet(treeText,"Courier New,10,0,0,0,0,0,0,0")
	treeText.Move 10,20
	
	'columnText
	Set columnText = dxCreateObject("text",strRootName & "_columnText",strRootName & "_treeTextBack",true,false)
	columnText.Text = ""
	Call dxs.dxTextFontSet(columnText,"Courier New,10,0,0,0,0,0,0,0")
	columnText.Visible = False
	columnText.Text = "|"
	columnText.Move 0,0
	
	'drag box
	Set drag = dxCreateObject("image",strRootName & "_drag",strRootName,true,false)
	drag.Picture = "ball.png"
	Call drag.SetMargins(1, 1, 1, 1, false, false)
	drag.Resize 12,12
	drag.Move 3,3
	drag.Group = strRootName
	
	'columnCollapse box
	Set columnCollapse = dxCreateObject("image",strRootName & "_collapse",strRootName,true,false)
	columnCollapse.Picture = "ball.png"
	Call columnCollapse.SetMargins(1, 1, 1, 1, false, false)
	columnCollapse.Resize 12,12
	columnCollapse.Move 16,3
	columnCollapse.Group = strRootName
	
	'border
	Set baseBorder = dxCreateObject("image",strRootName & "_border",base.Name,true,false)
	baseBorder.Picture = "boxClear.png"
	Call baseBorder.SetMargins(1, 1, 1, 1, false, false)
	baseBorder.Resize intW,intH
	baseBorder.Move 0,0
	
	Call base.SetScript(strScriptDirectory & "dxTreeView.txt")
	Call DesktopX.ScriptObject(base.Name).init
	
	drag.OnTop
	columnCollapse.OnTop
	baseBorder.OnTop
	Set conCreateTreeView = DesktopX.ScriptObject(base.Name)
End Function

Function conCreateImageSelector(strRootName,arrImages,intImageWidth)	'creates a TEMPORARY DesktopX control displaying images in arrImages and returns click image path.
	Call dxs.filCreateFolderPath(Object.Directory & "temp")
	Call dxs.filFileCopy(Object.Directory & "dxEdit_imageSelect.dxp",Object.Directory & "temp","dxEdit_imageSelect.dxpack")
	Call dxs.filRun3(Object.Directory & "temp\dxEdit_imageSelect.dxpack","")
	strObjects = "imageSelect,imageSelect_scrollBack,imageSelect_border,imageSelect_titleBack,imageSelect_titleText,imageSelect_magicScroll,imageSelect_scrollText"
	arrObjects = Split(strObjects,",")
	flagExists = False
	While flagExists = False
		flagExists = True
		For each strObject in arrObjects
			If Not DesktopX.IsObject(strObject) Then
				flagExists = False
			End If
		Next
		Object.Sleep 500
	Wend
	
	strRootName = "imageSelect"
	Set base = DesktopX.Object(strRootName)
	Set scrollBack = DesktopX.Object(strRootName & "_scrollBack")
	Set titleBack = DesktopX.Object(strRootName & "_titleBack")
	Set titleText = DesktopX.Object(strRootName & "_titleText")
	
	intImageCount = 0
	xPos = 0
	
	'clear existing icons first
	For each obj in DesktopX.GroupObjects(strRootName & "_icons")
		Call dxs.dxDestroy(obj.Name)
	Next
	
	scrollBack_height = scrollBack.Height
	imageCount = 0
	xPos = 0
	yPos = 0
	column = 0
	row = 0
	rowMax = Int(scrollBack_height/(intImageWidth+2))
	imageCount = 1
	
	For each strImagePath in arrImages
		DesktopX.Object(strRootName & "_iconMate").Clone strRootName & "_imageIcon_" & imageCount,-1000,-1000
		Set imageIcon = DesktopX.Object(strRootName & "_imageIcon_" & imageCount)
		imageIcon.Picture = strImagePath
		strIconText = dxImageWidth(imageIcon.Picture) & "x" & dxImageHeight(imageIcon.Picture)
		imageIcon.Width = intImageWidth
		Call imageIcon.SetMargins(0, 0, 0, 0, true, true)
		imageIcon.Move xPos, yPos
		imageIcon.Cursor = 14
		imageIcon.Group = strRootName & "_icons"
		If imageCount Mod rowMax = 0 Then
			xPos = xPos + intImageWidth + 2
			yPos = 0
		Else
			yPos = yPos + intImageWidth + 2
		End If
		
		imageCount = imageCount + 1
		imageIcon.Visible = True
		imagesWidth = xPos
	Next
	
	'border
	Set baseBorder = DesktopX.Object(strRootName & "_border")
	baseBorder.OnTop
	titleBack.OnTop
	
	base.SetScript(strScriptDirectory & "dxImageSelector.txt")
	Set conImageSelector = DesktopX.ScriptObject(base.Name)
	Call conImageSelector.dxInit()
	
	conImageSelector.imageCount = imageCount
	conImageSelector.imageWidth = intImageWidth
	conImageSelector.imagesWidth = imagesWidth
	
	intCenterXPos = System.ScreenWidth/2 - DesktopX.Object(strRootName).Width/2
	intCenterYPos = System.ScreenHeight/2 - DesktopX.Object(strRootName).Height/2
	DesktopX.Object(strRootName).Move intCenterXPos,intCenterYPos
	
	DesktopX.Object(strRootName).Visible = True
	
	strComments = ""
	base.Comments = ""
	While strComments = ""
		strComments = base.Comments
		Object.Sleep 100
	Wend
	base.Comments = ""
	If strComments = "%cancel%" Then
		conCreateImageSelector = False
	Else
		conCreateImageSelector = strComments
	End If
	Call dxs.dxDestroy(strRootName)
End Function

Function conRegisterDropLayer(strRootName)
	Set conExists = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']")
	If conExists Is Nothing Then
		'add to dxEdit XML
		Set conTemplate = dxEditXML.selectSingleNode("//templates/control[@type='dropLayer']").cloneNode(true)
		Set conParent = dxEditXML.selectSingleNode("//controls")
		conTemplate.selectSingleNode("@name").text = strRootName
		conParent.appendChild(conTemplate)
		dxEditXML.Save(Object.Directory & "dxEdit.xml")
		
		Set base = DesktopX.Object(strRootName)
		base.SetScript(strScriptDirectory & "dxShortcutLayer.txt")
		Set conRegisterDropLayer = DesktopX.ScriptObject(base.Name)
		Call conRegisterDropLayer.dxInit()
	Else
		strControlType = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']/@type").text
		MsgBox("That object is already registered as a control type " & strControlType)
	End If
End Function

Function conCreateDropLayer(strRootName,intX,intY,intW,intH,strTemplate)	'creates a set of objects which can hold shortcuts.
	Call dxs.filCreateFolderPath(Object.Directory & "temp")
	Call dxs.filFileCopy(Object.Directory & "dxEdit_dropLayer.dxp",Object.Directory & "temp","dxEdit_dropLayer.dxpack")
	Call dxs.filRun3(Object.Directory & "temp\dxEdit_dropLayer.dxpack","")
	While Not DesktopX.IsObject("dxEdit_dropLayerTemplate")
		Object.Sleep 3000
	Wend
	
	Set objTemplate = DesktopX.Object("dxEdit_dropLayerTemplate")
	
	'tweak template to desired settings
	Call dxs.dxRename(objTemplate,"dxEdit_dropLayerTemplate",strRootName)
	Set base = DesktopX.Object(strRootName)
	base.Resize intW,intH
	base.Group = strRootName
	
	Set scrollArea = DesktopX.Object(strRootName & "_scrollArea")
	scrollArea.Resize intW,10000
	scrollArea.Move 0,0
	
	Set magicScroller = DesktopX.Object(strRootName & "_magicScroller")
	magicScroller.Move intX + intW - 15,intY

	base.Move intX,intY
	
	'add to dxEdit XML
	Set conTemplate = dxEditXML.selectSingleNode("//templates/control[@type='dropLayer']").cloneNode(true)
	Set conParent = dxEditXML.selectSingleNode("//controls")
	conTemplate.selectSingleNode("@name").text = strRootName
	conParent.appendChild(conTemplate)
	dxEditXML.Save(Object.Directory & "dxEdit.xml")
	
	base.SetScript(strScriptDirectory & "dxShortcutLayer.txt")
	Call dxPipeEvents(strRootName & "_magicScroller",strRootName)
	
	Set conCreateDropLayer = DesktopX.ScriptObject(base.Name)
	Call conCreateDropLayer.dxInit()
	base.Visible = True
End Function

Function conCreateClock(strRootName,intX,intY,strTemplate)
	Call dxs.filCreateFolderPath(Object.Directory & "temp")
	Call dxs.filFileCopy(Object.Directory & "dxEdit_clock.dxp",Object.Directory & "temp","dxEdit_clock.dxpack")
	Call dxs.filRun3(Object.Directory & "temp\dxEdit_clock.dxpack","")
	While Not DesktopX.IsObject("dxEdit_clockTemplate")
		Object.Sleep 3000
	Wend
	
	Set objTemplate = DesktopX.Object("dxEdit_clockTemplate")
	objTemplate.Name = strRootName
	Set objTemplate = DesktopX.Object("dxEdit_clockTemplate_secondHand")
	objTemplate.Name = strRootName & "_secondHand"
	Set objTemplate = DesktopX.Object("dxEdit_clockTemplate_minuteHand")
	objTemplate.Name = strRootName & "_minuteHand"
	Set objTemplate = DesktopX.Object("dxEdit_clockTemplate_hourHand")
	objTemplate.Name = strRootName & "_hourHand"
		
	While Not DesktopX.IsObject(strRootName)
		Object.Sleep 3000
	Wend
	Set base = DesktopX.Object(strRootName)
	
	'add to dxEdit XML
	Set conTemplate = dxEditXML.selectSingleNode("//templates/control[@type='clock']").cloneNode(true)
	Set conParent = dxEditXML.selectSingleNode("//controls")
	conTemplate.selectSingleNode("@name").text = strRootName
	conParent.appendChild(conTemplate)
	dxEditXML.Save(Object.Directory & "dxEdit.xml")
	
	base.SetScript(strScriptDirectory & "dxClock.txt")
	Set conCreateClock = DesktopX.ScriptObject(base.Name)
	Call conCreateClock.dxInit()
	base.Visible = True
End Function

Function conRegisterClock(strRootName)
	Set conExists = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']")
	If conExists Is Nothing Then
		'add to dxEdit XML
		Set conTemplate = dxEditXML.selectSingleNode("//templates/control[@type='clock']").cloneNode(true)
		Set conParent = dxEditXML.selectSingleNode("//controls")
		conTemplate.selectSingleNode("@name").text = strRootName
		conParent.appendChild(conTemplate)
		dxEditXML.Save(Object.Directory & "dxEdit.xml")
		
		Set base = DesktopX.Object(strRootName)
		base.SetScript(strScriptDirectory & "dxClock.txt")
		Set conRegisterClock = DesktopX.ScriptObject(base.Name)
		Call conRegisterClock.dxInit()
	Else
		strControlType = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']/@type").text
		MsgBox("That object is already registered as a control type " & strControlType)
	End If
End Function

Function conRegisterDrawer(strRootName)
	'Set conExists = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']")
	'If conExists Is Nothing Then
		'add to dxEdit XML
		Set conTemplate = dxEditXML.selectSingleNode("//templates/control[@type='slider']").cloneNode(true)
		Set conParent = dxEditXML.selectSingleNode("//controls")
		Set obj = DesktopX.Object(strRootName)
		conTemplate.selectSingleNode("@name").text = strRootName
		conTemplate.selectSingleNode("initX").text = CStr(obj.Left)
		conTemplate.selectSingleNode("initY").text = CStr(obj.Top)
		
		conParent.appendChild(conTemplate)
		dxEditXML.Save(Object.Directory & "dxEdit.xml")
	'Else
	'	strControlType = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']/@type").text
	'	MsgBox("That object is already registered as a control type " & strControlType)
	'End If
End Function

Function conRegisterTrash(strRootName)
	Set conExists = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']")
	If conExists Is Nothing Then
		'add to dxEdit XML
		Set conTemplate = dxEditXML.selectSingleNode("//templates/control[@type='trash']").cloneNode(true)
		Set conParent = dxEditXML.selectSingleNode("//controls")
		Set obj = DesktopX.Object(strRootName)
		conTemplate.selectSingleNode("@name").text = strRootName
		
		Set base = DesktopX.Object(strRootName)
		base.SetScript(strScriptDirectory & "dxTrash.txt")
		Set conRegisterTrash = DesktopX.ScriptObject(base.Name)
		Call conRegisterTrash.dxInit()
		
		conParent.appendChild(conTemplate)
		dxEditXML.Save(Object.Directory & "dxEdit.xml")
	Else
		strControlType = dxEditXML.selectSingleNode("//controls/control[@name = '" & strRootName & "']/@type").text
		MsgBox("That object is already registered as a control type " & strControlType)
	End If
End Function


'resources
Dim objRefresher
Dim objServicesCimv2
Dim colCPUCores
Dim colNetworkAdapters
Dim colNetworkConfig

Function resCreateRefresher
	If IsEmpty(objRefresher) Then
		Set objRefresher = CreateObject("WbemScripting.SWbemRefresher")
		Set objServicesCimv2 = GetObject("winmgmts:\\.\root\cimv2")
		Object.SetTimer 1,1000
	End If
End Function

Function resCreate_NetworkAdapterConfiguration
	Call resCreateRefresher
	Set colNetworkConfig = objServicesCimv2.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration",,32) 
End Function

Function resCPUCount()
	Call resAddCPUs()
	resCPUCount = 0
	For each cpuCore in colCPUCores.ObjectSet
		If cpuCore.Name <> "_Total" Then
			resCPUCount = resCPUCount + 1
		End If
	Next
End Function

Function resAddCPUs
	Call resCreateRefresher()
	If IsEmpty(colCPUCores) Then
		Set colCPUCores = objRefresher.AddEnum(objServicesCimv2, "Win32_PerfFormattedData_PerfOS_Processor")
		Call objRefresher.Refresh
	End If
End Function

Function resAddNetwork
	Call resCreateRefresher()
	If IsEmpty(colNetworkAdapters) Then
		Set colNetworkAdapters = objRefresher.AddEnum(objServicesCimv2, "Win32_PerfFormattedData_Tcpip_NetworkInterface")
		Set colNetworkConfig = objRefresher.AddEnum(objServicesCimv2, "Win32_NetworkAdapterConfiguration") 
		Call objRefresher.Refresh
	End If
End Function

Function resNetworkIPAddress(strAdapterName)
	resNetworkIPAddress = "undefined"
	If strAdapterName = "undefined" or strAdapterName = "" Then
		resNetworkIPAddress = "undefined"
		Exit Function
	End If
	
	Call resAddNetwork()
	For each networkConfig in colNetworkConfig.ObjectSet
		If Not IsNull(networkConfig.Description) Then
			strAdapterDescription = networkConfig.Description
			If LCase(Trim(CStr(strAdapterDescription))) = LCase(Trim(CStr(strAdapterName))) Then
				On Error Resume Next
				If Not IsNull(networkConfig.IPAddress) Then
					resNetworkIPAddress = Join(networkConfig.IPAddress,",")
					arrNetworkIPAddress = Split(resNetworkIPAddress,",")
					resNetworkIPAddress = arrNetworkIPAddress(0)
					Exit For
				Else
					resNetworkIPAddress = "undefined"
				End If
				Err.Clear
			End If
		End If
	Next
End Function

Function resNetworkAdapterCount()
	Call resAddNetwork()
	resNetworkAdapterCount = 0
	For each adapter in colNetworkAdapters.ObjectSet
		resNetworkAdapterCount = resNetworkAdapterCount + 1
	Next
End Function

Function resNetworkName(intAdapter)
	Call resAddNetwork()
	
	resNetworkName = "undefined"
	intAdapterIndex = 0
	For each adapter in colNetworkAdapters.ObjectSet
		intAdapterIndex = intAdapterIndex + 1
		If intAdapterIndex = intAdapter Then
			resNetworkName = adapter.Name
			If IsNull(resNetworkName) Then
				resNetworkName = "undefined"
			End If
			Exit For
		End If
	Next
End Function

Function resNetworkBandwidth(intAdapter)
	Call resAddNetwork()
	
	resNetworkBandwidth = 0
	intAdapterCount = 0
	For each adapter in colNetworkAdapters.ObjectSet
		intAdapterCount = intAdapterCount + 1
		If intAdapterCount = intAdapter Then
			resNetworkBandwidth = adapter.CurrentBandwidth
			If IsNull(resNetworkBandwidth) Then
				resNetworkBandwidth = 0
			End If
			Exit For
		End If
	Next
End Function

Function resNetworkSendSpeed(intAdapter)
	Call resAddNetwork()
	
	resNetworkSendSpeed = 0
	intAdapterCount = 0
	For each adapter in colNetworkAdapters.ObjectSet
		intAdapterCount = intAdapterCount + 1
		If intAdapterCount = intAdapter Then
			resNetworkSendSpeed = adapter.BytesSentPersec
			If IsNull(resNetworkSendSpeed) Then
				resNetworkSendSpeed = 0
			End If
			Exit For
		End If
	Next
End Function

Function resNetworkReceiveSpeed(intAdapter)
	Call resAddNetwork()

	resNetworkReceiveSpeed = 0
	intAdapterCount = 0
	For each adapter in colNetworkAdapters.ObjectSet
		intAdapterCount = intAdapterCount + 1
		If intAdapterCount = intAdapter Then
			resNetworkReceiveSpeed = adapter.BytesReceivedPersec
			If IsNull(resNetworkReceiveSpeed) Then
				resNetworkReceiveSpeed = 0
			End If
			Exit For
		End If
	Next
End Function

Function resCPUPercent(intCore)
	Call resAddCPUs()
	
	resCPUPercent = False
	intCoreCount = 0
	If intCore = -1 then
		intCore = "_Total"
	End If
	
	For each cpuCore in colCPUCores.ObjectSet
		If cpuCore.Name = CStr(intCore) Then
			resCPUPercent = cpuCore.Name & ":   " & cpuCore.PercentProcessorTime
			Exit For
		End If
	Next
End Function

Sub Object_OnTimer1
	On Error Resume Next
	Call objRefresher.Refresh
	Err.Clear
End Sub

'menus
Function menu_dxEdit()
	On Error Resume Next
	menu_dxEdit = True
	Dim menu
	Set menu = DesktopX.CreatePopupMenu
	
	'trash menus
	'===========
	Set trash = DesktopX.CreatePopupMenu
	'type	controlNumber 	subMenu				resultValue
	'04		00				00 (menu root)		*
	trash.AppendMenu 0,04000002,"register trash object"
	trash.AppendMenu &H00000800,0,"-"
	
		'trash controls
		Set nodeControls = dxEditXML.selectNodes("//controls/control[@type='trash']")
		intControlCount = 01
		For Each nodeControl In nodeControls
			strControlName = nodeControl.selectSingleNode("@name").text
			'						type	controlNumber 	subMenu				resultValue
			'						04		*				00 (control root)	*
			intMenuRootIndex = CDbl("04" & Right("00" & intControlCount,2) & "00" & "00")
			Set trash_control = DesktopX.CreatePopupMenu
			trash_control.AppendMenu 0,intMenuRootIndex + 1,"de-register"
			
			intControlCount = intControlCount + 1
			trash.AppendMenu &H00000010, trash_control.MenuID,strControlName
		Next
		
	dropLayer.AppendMenu &H00000800,0,"-"
	menu.AppendMenu &H00000010, trash.MenuID, "trash bins"
	
	'droplayer/shortcutlayer menus
	'=============================
	Set dropLayer = DesktopX.CreatePopupMenu
	dropLayer.AppendMenu 0,01000002,"register shortcutLayer object"
	dropLayer.AppendMenu &H00000800,0,"-"
	
		'droplayer controls
		Set nodeControls = dxEditXML.selectNodes("//controls/control[@type='dropLayer']")
		intControlCount = 01
		For Each nodeControl In nodeControls
			strControlName = nodeControl.selectSingleNode("@name").text
			dropLayer_type = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@layoutType").text
			'						type	controlNumber 	subMenu				resultValue
			'						01		*				00 (control root)	*
			intMenuRootIndex = CDbl("01" & Right("00" & intControlCount,2) & "00" & "00")
			'droplayer controls root menu
			Set dropLayer_control = DesktopX.CreatePopupMenu
			dropLayer_control.AppendMenu 0,intMenuRootIndex + 9,"de-register"
			dropLayer_control.AppendMenu 0,intMenuRootIndex + 1,"delete"
			dropLayer_control.AppendMenu 0,intMenuRootIndex + 2,"settings"
			If dropLayer_type = "1" Then
				dropLayer_control.AppendMenu &H00000800,0,"-"
				dropLayer_control.AppendMenu 0,intMenuRootIndex + 3,"add Ring"
				Set nodesRings = dxShortcutsXML.selectNodes("//layer[@name='" & strControlName & "']/rings/ring")
				intRingCount = 1
				For each nodeRing in nodesRings
					'submenu for each ring of icons in dropLayer
					'						type	controlNumber 	subMenu		resultValue
					'						01		*				01> (rings)	*
					intMenuRootIndex = CDbl("01" & Right("00" & intControlCount,2) & Right("00" & intRingCount,2) & "00")
					Set ring_submenu = DesktopX.CreatePopupMenu
					ring_submenu.AppendMenu 0,intMenuRootIndex + 1,"settings"
					ring_submenu.AppendMenu 0,intMenuRootIndex + 2,"delete Ring"
					dropLayer_control.AppendMenu &H00000010, ring_submenu.MenuID,"ring " & CStr(intRingCount)
					intRingCount = intRingCount + 1
				Next
			End If
			If dropLayer_type = "3" Then
				dropLayer_control.AppendMenu &H00000800,0,"-"
				dropLayer_control.AppendMenu 0,intMenuRootIndex + 4,"save custom layout"
			End If
			
			intControlCount = intControlCount + 1
			dropLayer.AppendMenu &H00000010, dropLayer_control.MenuID,strControlName
		Next
	dropLayer.AppendMenu &H00000800,0,"-"
	menu.AppendMenu &H00000010, dropLayer.MenuID, "shortcutLayers"
	
	'clock menus
	'===========
	Set clock = DesktopX.CreatePopupMenu
	'type	controlNumber 	subMenu				resultValue
	'03		00				00 (menu root)		*
	clock.AppendMenu 0,03000001,"register clock object"
	clock.AppendMenu &H00000800,0,"-"
		'clock controls
		Set nodeControls = dxEditXML.selectNodes("//controls/control[@type='clock']")
		intControlCount = 01
		For Each nodeControl In nodeControls
			'type	controlNumber 	subMenu				resultValue
			'03		*				00 (control root)	*
			intMenuRootIndex = CDbl("03" & Right("00" & intControlCount,2) & "00" & "00")
			'clock controls root menu
			strControlName = nodeControl.selectSingleNode("@name").text
			Set clock_control = DesktopX.CreatePopupMenu
			clock_control.AppendMenu 0,intMenuRootIndex + 5,"de-register"
			clock_control.AppendMenu 0,intMenuRootIndex + 1,"delete"
			clock_control.AppendMenu 0,intMenuRootIndex + 2,"seconds frames"
			clock_control.AppendMenu 0,intMenuRootIndex + 3,"minutes frames"
			clock_control.AppendMenu 0,intMenuRootIndex + 4,"hours frames"
			
			intControlCount = intControlCount + 1
			clock.AppendMenu &H00000010, clock_control.MenuID, strControlName
		Next
	clock.AppendMenu &H00000800,0,"-"
	clock.AppendMenu 0,03000003,"generate hand animation strip"
	clock.AppendMenu 0,03000004,"create clock template images"
	
	menu.AppendMenu &H00000010, clock.MenuID, "clocks"
	
	'drawer menus
	'============
	Set drawer = DesktopX.CreatePopupMenu
	'type	controlNumber 	subMenu				resultValue
	'02		00				00 (menu root)		*
	drawer.AppendMenu 0,02000001,"register drawer object"
	drawer.AppendMenu &H00000800,0,"-"
	
		'drawer controls
		Set nodeControls = dxEditXML.selectNodes("//controls/control[@type='slider']")
		intControlCount = 01
		For Each nodeControl In nodeControls
			'type	controlNumber 	subMenu				resultValue
			'02		*				01 (control root)	*
			intMenuRootIndex = CDbl("02" & Right("00" & intControlCount,2) & "00" & "00")
			'drawer controls root menu
			strControlName = nodeControl.selectSingleNode("@name").text
			Set slider_control = DesktopX.CreatePopupMenu
			slider_control.AppendMenu 0,intMenuRootIndex + 1,"de-register drawer"
			slider_control.AppendMenu 0,intMenuRootIndex + 2,"options"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 2,"left in-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 3,"left out-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 4,"right in-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 5,"right out-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 6,"top in-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 7,"top out-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 8,"bottom in-offset"
			REM slider_control.AppendMenu 0,intMenuRootIndex + 9,"bottom out-offset"
			
			intControlCount = intControlCount + 1
			drawer.AppendMenu &H00000010, slider_control.MenuID, strControlName
		Next
		
	menu.AppendMenu &H00000010, drawer.MenuID, "drawers"
	menu.AppendMenu &H00000800,0,"-"
	
	'further root menu options
	'-------------------------
	If dxEdit_allowDrag = True Then
		menuOpt = &H00000008
	Else
		menuOpt = 0
	End If
	menu.AppendMenu menuOpt, 00000001, "allow locked objects reposition"
	'menu.AppendMenu 0, 00000002, "delete dxEdit template files"
	menu.AppendMenu 0, 00000003, "cancel"
	
	'====================================
	'	menu results
	'====================================
	result = menu.TrackPopupMenu(0, System.CursorX, System.CursorY)
	result = Right("00000000" & result,8)
	strControlType = CInt(Left(result,2))
	strControlNumber = CInt(Mid(result,3,2))
	strSubControlNumber = CInt(Mid(result,5,2))
	strResult = Cint(Mid(result,7,2))
	
	Select Case strControlType
		Case 0	'root menu
			Select Case strControlSubMenu
				Case 0	'root menu
					Select Case strResult
						Case 1
							dxEdit_allowDrag = Not dxEdit_allowDrag
						
						Case 2
							Call dxs.filDelete(Object.Directory & "dxEdit_clock.dxp")
							Call dxs.filDelete(Object.Directory & "dxEdit_dropLayer.dxp")
							
						Case 3
							Call dxs.filFileCopy(Object.Directory & "dxEdit.xml",Object.Directory,"dxEdit_restore.xml")
			
					End Select
			End Select
			
		Case 1	'dropLayer
			Select Case strControlNumber
				Case 0	'root menu
					Select Case strSubControlNumber
						Case 0	'root menu
							Select Case strResult
								Case 1
									strControlName = InputBox("Enter a name for the control:","New dropLayer")
									If strControlName = "" Then Exit Function
									If DesktopX.IsObject(strControlName) Then
										MsgBox("An object with that name already exists!")
										Exit Function
									End If
									Call conCreateDropLayer(strControlName,200,200,200,200,"")
									
								Case 2
									strSelectedObjectName = dxs.frmObjectSelect()
									If strSelectedObjectName = False Then
										Exit Function
									Else
										Call conRegisterDropLayer(strSelectedObjectName)
									End If
								
							End Select
					End Select
				
				Case Else	'each control
					Select Case strSubControlNumber
						Case 0	'control root menu
							Set nodeControl = dxEditXML.selectSingleNode("(//control[@type='dropLayer'])[" & strControlNumber & "]")
							strControlName = nodeControl.selectSingleNode("@name").text
							Select Case strResult
								Case 1
									'remove shortcutLayer node from shortcuts XML.
									Set nodeLayer = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]")
									Call nodeControl.parentNode.removeChild(nodeControl)
									Call nodeLayer.parentNode.removeChild(nodeLayer)
									If DesktopX.IsObject(strControlName & "_magicScroller") Then
										DesktopX.Object(strControlName & "_magicScroller").Delete
									End If
									If DesktopX.IsObject(strControlName) Then
										Call dxs.dxDestroy(strControlName)
									End If
									
								Case 2
									'drop layer settings form
									dropLayer_type = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@layoutType").text
									dropLayer_toggleObject = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@toggleObject").text
									intCurrentW = DesktopX.Object(strControlName).Width
									intCurrentH = DesktopX.Object(strControlName).Height
									allowGrid = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowGrid").text
									allowRing = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowRing").text
									allowFree = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowFree").text
									allowCustom = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowCustom").text
									
									Set frm = DesktopX.CreateForm
									Call dxs.frmAddPref(frm,"width","Text","width: ","",CStr(intCurrentW))
									Call dxs.frmAddPref(frm,"height","Text","height: ","",CStr(intCurrentH))
									If dropLayer_type = "0" Then
										strType = "grid"
									Else
										strType = "ring"
									End If
									Call dxs.frmAddPref(frm,"type","ComboList","type: ","",strType)
									Call frm.Preference("type").AddValue("grid")
									Call frm.Preference("type").AddValue("ring")
									Call frm.Preference("type").AddValue("free")
									Call frm.Preference("type").AddValue("custom")
									
									Call dxs.frmAddPref(frm,"toggleObject","ComboList","hide object: ","",dropLayer_toggleObject)
									frm.Preference("toggleObject").AddValue "* none"
									frm.Preference("toggleObject").AddValue "* layer"
									frm.Preference("toggleObject").AddValue "* layer parent"
									For each obj in DesktopX.Objects
										frm.Preference("toggleObject").AddValue obj.Name
									Next
									
									Call dxs.frmAddPref(frm,"allowGrid","Checkbox"," allow grid layout ","",allowGrid)
									Call dxs.frmAddPref(frm,"allowRing","Checkbox"," allow ring layout ","",allowRing)
									Call dxs.frmAddPref(frm,"allowCustom","Checkbox"," allow custom layout ","",allowCustom)
									Call dxs.frmAddPref(frm,"allowFree","Checkbox"," allow free layout ","",allowFree)
									
									If frm.Prompt Then
										intCurrentW = dxs.frmValue(frm,"width",2)
										intCurrentH = dxs.frmValue(frm,"height",2)
										dropLayer_type = dxs.frmValue(frm,"type",0)
										dropLayer_toggleObject = dxs.frmValue(frm,"toggleObject",0)
										allowGrid = dxs.frmValue(frm,"allowGrid",0)
										allowRing = dxs.frmValue(frm,"allowRing",0)
										allowCustom = dxs.frmValue(frm,"allowCustom",0)
										allowFree = dxs.frmValue(frm,"allowFree",0)
										
										DesktopX.Object(strControlName).Resize intCurrentW,intCurrentH
										Select Case dropLayer_type
											Case "grid"
												dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@layoutType").text = "0"
											Case "ring"
												dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@layoutType").text = "1"
											Case "free"
												dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@layoutType").text = "3"
											Case "custom"	
												dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@layoutType").text = "2"
												
										End Select
										dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@toggleObject").text = dropLayer_toggleObject
										
										dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowGrid").text = allowGrid
										dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowRing").text = allowRing
										dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowFree").text = allowFree
										dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/@allowCustom").text = allowCustom
									
										Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers.xml")
										Call DesktopX.ScriptObject(strControlName).dxInit()
									End If
								
								Case 3
									'add Ring
									Set conTemplate = dxShortcutsXML.selectSingleNode("//templates/ring").cloneNode(true)
									Set conParent = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/rings")
									Call conParent.appendChild(conTemplate)
									Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers.xml")
									Call DesktopX.ScriptObject(strControlName).refreshShortcuts()
								
								Case 4
									'save custom layout
									Set nodesShortcuts = dxShortcutsXML.selectNodes("//layer[@name=""" & strControlName & """]/shortcuts/shortcut")
									Set nodesCustomPositions = dxShortcutsXML.selectNodes("//layer[@name=""" & strControlName & """]/customs/pos")
									For each nodeCustom in nodesCustomPositions
										Call nodeCustom.parentNode.removeChild(nodeCustom)
									Next
									
									For each nodeShortcut In nodesShortcuts
										strShortcutName = nodeShortcut.selectSingleNode("name").text
										If DesktopX.IsObject(strControlName & "_" & strShortcutName & "*") Then
											Set nodeCustomClone = dxShortcutsXML.selectNodes("//templates/pos").cloneNode(true)
											Set nodeCustomPositionsParent = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]/customs")
											Call nodeCustomPositionsParent.appendChild(nodeCustomClone)
											Set dxObjShortcut = DesktopX.Object(strControlName & "_" & strShortcutName & "*")
											xPos = dxObjShortcut.Left
											yPos = dxObjShortcut.Top
											nodeCustomPositionsParent.selectSingleNode("@x").text = xPos
											nodeCustomPositionsParent.selectSingleNode("@y").text = yPos
											Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers.xml")
										End If
									Next
											
								Case 9
									Set nodeLayer = dxShortcutsXML.selectSingleNode("//layer[@name=""" & strControlName & """]")
									Call nodeControl.parentNode.removeChild(nodeControl)
									Call nodeLayer.parentNode.removeChild(nodeLayer)
									Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers.xml")
									Call dxEditXML.Save(Object.Directory & "dxEdit.xml")
									Call DesktopX.Object(strControlName).SetScript("")
									Call DesktopX.Object(strControlName & "_magicScroller").SetScript("")
									
							End Select
					
						Case Else	'ring menus where strSubControlNumber is Ring number
							Set nodeControl = dxEditXML.selectSingleNode("//control[@type='dropLayer'][" & strControlNumber & "]")
							strControlName = nodeControl.selectSingleNode("@name").text
							Select Case strResult
								Case 1
									'ring settings form
									Set nodeRing = dxShortcutsXML.selectSingleNode("//layer[@name='" & strControlName & "']/rings/ring[" & CInt(strSubControlNumber) & "]")
									ring_distribute = nodeRing.selectSingleNode("@distribute").text
									ring_radius = nodeRing.selectSingleNode("@radius").text
									ring_maxCount = nodeRing.selectSingleNode("@maxCount").text
									ring_xOffset = nodeRing.selectSingleNode("@xOffset").text
									ring_yOffset = nodeRing.selectSingleNode("@yOffset").text
									ring_angleOffset = nodeRing.selectSingleNode("@angleOffset").text
									ring_angleRange  = nodeRing.selectSingleNode("@angleRange").text
									
									Set frm = DesktopX.CreateForm
									Call dxs.frmAddPref(frm,"distribute","Checkbox","distribute: ","",ring_distribute)
									Call dxs.frmAddPref(frm,"radius","Text","radius: ","",ring_radius)
									Call dxs.frmAddPref(frm,"maxCount","Text","max shortcuts: ","",ring_maxCount)
									Call dxs.frmAddPref(frm,"xOffset","Text","x-Offset: ","",ring_xOffset)
									Call dxs.frmAddPref(frm,"yOffset","Text","y-Offset: ","",ring_yOffset)
									Call dxs.frmAddPref(frm,"angleOffset","Text","angle-Offset: ","Value will be multiplied by pi.",ring_angleOffset)
									Call dxs.frmAddPref(frm,"angleRange","Text","angle-Range: ","Value will be multiplied by pi",ring_angleRange)
								
									If frm.Prompt Then
										ring_distribute = dxs.frmValue(frm,"distribute",1)
										ring_radius = dxs.frmValue(frm,"radius",1)
										ring_maxCount = dxs.frmValue(frm,"maxCount",1)
										ring_xOffset = dxs.frmValue(frm,"xOffset",1)
										ring_yOffset = dxs.frmValue(frm,"yOffset",1)
										ring_angleOffset = dxs.frmValue(frm,"angleOffset",1)
										ring_angleRange  = dxs.frmValue(frm,"angleRange",1)
										
										nodeRing.selectSingleNode("@distribute").text = ring_distribute
										nodeRing.selectSingleNode("@radius").text = ring_radius
										nodeRing.selectSingleNode("@maxCount").text = ring_maxCount
										nodeRing.selectSingleNode("@xOffset").text = ring_xOffset
										nodeRing.selectSingleNode("@yOffset").text = ring_yOffset
										nodeRing.selectSingleNode("@angleOffset").text = ring_angleOffset
										nodeRing.selectSingleNode("@angleRange").text = ring_angleRange
									
										Call dxShortcutsXML.Save(Object.Directory & "shortcutLayers.xml")
										Call DesktopX.ScriptObject(strControlName).refreshShortcuts()
									End If
							
							End Select						
					End Select
			End Select
			
		Case 2	'drawer/slider
			Select Case strControlNumber
				Case 0	'root menu
					Select Case strSubControlNumber
						Case 0	'root menu
							Select Case strResult
								Case 1
									strSelectedObjectName = dxs.frmObjectSelect()
									If strSelectedObjectName = False Then
										Exit Function
									Else
										Call conRegisterDrawer(strSelectedObjectName)
									End If
							
							End Select
					End Select
					
				Case Else	'each control
					Set nodeControl = dxEditXML.selectSingleNode("//control[@type='slider'][" & strControlNumber & "]")
					strControlName = nodeControl.selectSingleNode("@name").text
					Select Case strSubControlNumber
						Case 0	'root menu
							Select Case strResult
								Case 1
									Call nodeControl.parentNode.removeChild(nodeControl)
									Call dxEditXML.Save(Object.Directory & "dxEdit.xml")
									Call DesktopX.Object(strControlName).SetScript("")
							
								Case 2
									'drawer settings form
									drawer_fixedPos = nodeControl.selectSingleNode("fixedPos").text
									Set frm = DesktopX.CreateForm
									Call dxs.frmAddPref(frm,"fixedPos","ComboList","fixed position: ","",drawer_fixedPos)
									Call frm.Preference("fixedPos").AddValue("yes")
									Call frm.Preference("fixedPos").AddValue("no")
									Call frm.Preference("fixedPos").AddValue("center")
	
									If frm.Prompt Then
										drawer_fixedPos = dxs.frmValue(frm,"fixedPos",1)
										nodeControl.selectSingleNode("fixedPos").text = drawer_fixedPos
										Call dxEditXML.Save(Object.Directory & "dxEdit.xml")
									End If
									
							End Select
					
					End Select
			End Select
			
		Case 3	'clock
			Select Case strControlNumber
				Case 0	'root menu
					Select Case strSubControlNumber
						Case 0	'root menu
							Select Case strResult
								Case 1
									strSelectedObjectName = dxs.frmObjectSelect()
									If strSelectedObjectName = False Then
										Exit Function
									Else
										Call conRegisterClock(strSelectedObjectName)
									End If
									
								Case 2
									strControlName = InputBox("Enter a name for the control:","New clock")
									If strControlName = "" Then Exit Function
									If DesktopX.IsObject(strControlName) Then
										MsgBox("An object with that name already exists!")
										Exit Function
									End If
									Call conCreateClock(strControlName,200,200,"")
					
								Case 3
									strOutputImageName = InputBox("Name of created PNG bitstrip file e.g. 'secondHand'")
									If strOutputImageName = "" Then
										MsgBox("You must provide a name for the output file")
										Exit Function
									End If
									
									Set objShell = CreateObject("Shell.Application")
									strMyPicturesPath = objShell.Namespace(&h27).Self.Path
									strInputImagePath = System.FileOpenDialog ("Select an image file:", "", strMyPicturesPath, "All files|*.*", &H100000)
									If strInputImagePath = "" Then
										Exit Function
									End If
									
									intFrames = CInt(InputBox("Enter the number of frames:"))
									If intFrames < 60 Then
										MsgBox("Please provide a number >= 60")
										Exit Function
									End If
									Call clockStrip(strInputImagePath,strOutputImageName,intFrames)
									MsgBox(strOutputImageName & ".png has been created in the theme's DesktopX folder.")
									
								Case 4
									Set frmClockTemplate = DesktopX.CreateForm
									Call dxs.frmAddPref(frmClockTemplate,"size","Text","width/height: ","Enter an odd value.","251")
									If frmClockTemplate.Prompt Then
										intSize = dxs.frmValue(frmClockTemplate,"size",2)
										If intSize Mod 2 = 0 then
											MsgBox("size of clock face must be odd")
											Exit Function
										End If
														
										strImageFilePath = System.FileSaveDialog ("Save image:", "clockFace.png", "", "PNG|*.png", 0)
										strImageFolderPath = dxs.filParentFolder(strImageFilePath)
										strImageFileName = dxs.filGetBaseName(strImageFilePath)
										Call clockFace(strImageFilePath,intSize)
										intSize = dxs.frmValue(frmClockTemplate,"size",2)
										intHandWidth = 0.2 * intSize
										If intHandWidth Mod 2 = 0 then intHandWidth = intHandWidth - 1
										Call clockHand(strImageFolderPath & "\" & strImageFileName & "_secondHand.png",intHandWidth,intSize)
									End If						
									
							End Select
					End Select
					
				Case Else
					Select Case strSubControlNumber
						Case 0	'root menu
							Set nodeControl = dxEditXML.selectSingleNode("//control[@type='clock'][" & strControlNumber & "]")
							strControlName = nodeControl.selectSingleNode("@name").text
							Select Case strResult
								Case 1
									Call nodeControl.parentNode.removeChild(nodeControl)
									If DesktopX.IsObject(strControlName & "_minuteHand") Then
										DesktopX.Object(strControlName & "_minuteHand").Delete
									End If
									If DesktopX.IsObject(strControlName & "_hourHand") Then
										DesktopX.Object(strControlName & "_hourHand").Delete
									End If
									If DesktopX.IsObject(strControlName) Then
										Call dxs.dxDestroy(strControlName)
									End If
								
								Case 2
									Set nodeSeconds = nodeControl.selectSingleNode("secFrames")
									intSecFrames = InputBox("Second frames:","",intSecFrames)
									If intSecFrames = "" Then Exit Function
									nodeSeconds.text = intSecFrames
									dxEditXML.Save(Object.Directory & "dxEdit.xml")
									DesktopX.ScriptObject(strControlName).intSecFrames = intSecFrames
									
								Case 3
									Set nodeMinutes = nodeControl.selectSingleNode("minFrames")
									intMinFrames = InputBox("Minute frames:","",intMinFrames)
									If intMinFrames = "" Then Exit Function
									nodeMinutes.text = intMinFrames
									dxEditXML.Save(Object.Directory & "dxEdit.xml")
									DesktopX.ScriptObject(strControlName).intMinFrames = intMinFrames
									
								Case 4
									Set nodeHours = nodeControl.selectSingleNode("hourFrames")
									intHourFrames = InputBox("Hour frames:","",intHourFrames)
									If intHourFrames = "" Then Exit Function
									nodeHours.text = intHourFrames
									dxEditXML.Save(Object.Directory & "dxEdit.xml")
									DesktopX.ScriptObject(strControlName).intHourFrames = intHourFrames
								
								Case 5
									Call nodeControl.parentNode.removeChild(nodeControl)
									Call dxEditXML.Save(Object.Directory & "dxEdit.xml")
									Call DesktopX.Object(strControlName).SetScript("")
							
							End Select
					End Select
			End Select
	
		Case 4	'trash bin
			Select Case strControlNumber
				Case 0	'root menu
					Select Case strSubControlNumber
						Case 0	'root menu
							Select Case strResult
								Case 2
									strSelectedObjectName = dxs.frmObjectSelect()
									If strSelectedObjectName = False Then
										Exit Function
									Else
										Call conRegisterTrash(strSelectedObjectName)
									End If
							
							End Select
					End Select
					
				Case Else	'each control
					Set nodeControl = dxEditXML.selectSingleNode("//control[@type='trash'][" & strControlNumber & "]")
					strControlName = nodeControl.selectSingleNode("@name").text
					Select Case strSubControlNumber
						Case 0	'root menu
							Select Case strResult
								Case 1
									Call nodeControl.parentNode.removeChild(nodeControl)
									Call dxEditXML.Save(Object.Directory & "dxEdit.xml")
									Call DesktopX.Object(strControlName).SetScript("")
									
							End Select
					End Select
			End Select
	End Select
End Function

Function clockHand(strOutputImagePath,intWidth,intHeight)
	intMiddleWidth = 1 + (intWidth - 1)/2
	intMiddleHeight = 1 + (intHeight - 1)/2
	Set img = CreateObject("ImageMagickObject.MagickImage.1")
	img.Convert "-size",intWidth & "x" & intHeight,"canvas:transparent","mpr:main"
	img.Convert "mpr:main","-fill","green","-stroke","green","-draw","line " & intMiddleWidth & "," & intHeight       & " " & intMiddleWidth & "," & intHeight * 0.5, "mpr:main"
	img.Convert "mpr:main","-fill","green","-stroke","green","-draw","line " & "0"            & "," & intMiddleHeight & " " & intSize        & "," & intMiddleHeight, "mpr:main"
	img.Convert "mpr:main","png32:" & strOutputImagePath
	Set img = Nothing
End Function

Function clockFace(strOutputImageName,intSize)
	On Error Goto 0
	intMiddle = 1 + (intSize - 1)/2
	Set img = CreateObject("ImageMagickObject.MagickImage.1")
	img.Convert "-size",intSize + 2 & "x" & intSize + 2,"canvas:transparent","mpr:main"
	img.Convert "mpr:main","-fill","black","-stroke","black","-draw","line " & intMiddle & ",1 " & intMiddle & "," & intSize, "mpr:black"
	img.Convert "mpr:main","-fill","red","-stroke","red","-draw","line "     & intMiddle & ",1 " & intMiddle & "," & intSize, "mpr:red"
	img.Convert "mpr:red","mpr:total"
	For angle = 6 to 90 step 6
		If angle mod 30 = 0 then
			img.Convert "mpr:red",  "-background","transparent","-distort","SRT",angle,"mpr:rotated"
		Else
			img.Convert "mpr:black","-background","transparent","-distort","SRT",angle,"mpr:rotated"
		End If
		img.Composite "mpr:rotated","mpr:total","mpr:total"
	Next
	
	img.Convert "mpr:total","-flip","mpr:flip"
	img.Composite "mpr:total","mpr:flip","mpr:total"
	img.Convert "mpr:total","-flop","mpr:flip"
	img.Composite "mpr:total","mpr:flip","mpr:total"
	img.Convert "mpr:total","-crop",intSize & "x" & intSize & "+0+0","mpr:total"
	img.Convert "mpr:total","png32:" & strOutputImageName
	Set img = Nothing
End Function

Function clockStrip(strInputImagePath,strOutputImageName,intFrames)
	Set img = CreateObject("ImageMagickObject.MagickImage.1")
	On Error Goto 0
	DesktopX.Object("dxEdit_images").Picture = strInputImagePath
	intWidth = DesktopX.Object("dxEdit_images").Width
	intHeight = DesktopX.Object("dxEdit_images").Height
	intSize = intHeight
		
	img.Convert strInputImagePath,"-matte","-bordercolor","none","-border",(intSize - intWidth)/2 & "x0","mpr:main"
	img.Convert "mpr:main","-background","transparent","-extent",intSize + 2 & "x" & intSize + 2,"mpr:base"
	
	DesktopX.Object("dxEdit_debug").Visible = True
	
	imageCount = 0
	For frameStep = 0 to (intFrames - 1)
			
		strImageNumber = Right("0000" & imageCount,4)
		angle = 360/intFrames * frameStep
		strImageName = strOutputImageName & "_" & strImageNumber
		
		img.Convert "mpr:base","+antialias","-background","transparent","-channel","RGBA","-distort","SRT",angle,"-blur","1x1","mpr:rotate"
		img.Convert "mpr:rotate","-background","transparent","-crop",intSize & "x" & intSize & "+0+0","+repage","png32:" & Object.Directory & strImageName & ".png"
		
		DesktopX.Object("dxEdit_debug").Text = "Processing image: " & angle
		imageCount = imageCount + 1
		attachmentCount = attachmentCount + 1
	Next
	Set img = Nothing
	
	DesktopX.Object("dxEdit_debug").Visible = False
End Function