Image
-- **************************************************
-- Provide Moho with the name of this script object
-- **************************************************

ScriptName = "SZ_LayerCopies"

-- **************************************************
-- General information about this script
-- **************************************************

SZ_LayerCopies = {}

function SZ_LayerCopies:Name()
	return self:Localize("Name")
end

function SZ_LayerCopies:Version()
	return "1.34"
end

function SZ_LayerCopies:UILabel()
	return self:Localize("UILabel")
end

function SZ_LayerCopies:Creator()
	return "Stan from 2danimator.ru"
end

function SZ_LayerCopies:Description()
	return self:Localize("Description")
end

--[[
function SZ_LayerCopies:LoadPrefs(prefs)
	
end

function SZ_LayerCopies:SavePrefs(prefs)
	
end

function SZ_LayerCopies:ResetPrefs()
	
end
-- ]]

-- **************************************************
-- Defaults
-- **************************************************

SZ_LayerCopies.numberOfCopiesDefault = 10
SZ_LayerCopies.stackBottomToTopDefault = false
SZ_LayerCopies.asReferencesDefault = true
SZ_LayerCopies.putInGroupDefault = false
SZ_LayerCopies.makeInvisibleDefault = false
SZ_LayerCopies.distributeAlongCurveDefault = false
SZ_LayerCopies.bendWithCurveDefault = false
SZ_LayerCopies.backToBackDefault = false

SZ_LayerCopies.applyTimingOffsetDefault = true
SZ_LayerCopies.timingOffsetDefault = 3
SZ_LayerCopies.timingOffsetRandomizeDefault = false
SZ_LayerCopies.timingOffsetMinDefault = 1
SZ_LayerCopies.timingOffsetMaxDefault = 5
SZ_LayerCopies.timingOffsetRandomizeAbsoluteDefault = false

SZ_LayerCopies.axisX_ApplyTranslationDefault = false
SZ_LayerCopies.axisX_TranslationDefault = 0
SZ_LayerCopies.axisX_ApplyLayerSizeDefault = false
SZ_LayerCopies.axisX_TranslationRandomizeDefault = false
SZ_LayerCopies.axisX_TranslationMinDefault = 1
SZ_LayerCopies.axisX_TranslationMaxDefault = 5
SZ_LayerCopies.axisX_TranslationRandomizeAbsoluteDefault = false
SZ_LayerCopies.axisX_RotationDefault = 0
SZ_LayerCopies.axisX_ApplyRotationDefault = false
SZ_LayerCopies.axisX_RotationRandomizeDefault = false
SZ_LayerCopies.axisX_RotationMinDefault = -90
SZ_LayerCopies.axisX_RotationMaxDefault = 90
SZ_LayerCopies.axisX_RotationRandomizeAbsoluteDefault = false
SZ_LayerCopies.axisX_ApplyScaleDefault = false
SZ_LayerCopies.axisX_ScaleDefault = 1.1
SZ_LayerCopies.axisX_ScaleRandomizeDefault = false
SZ_LayerCopies.axisX_ScaleMinDefault = 0.5
SZ_LayerCopies.axisX_ScaleMaxDefault = 5
SZ_LayerCopies.axisX_ScaleRandomizeAbsoluteDefault = false

SZ_LayerCopies.axisY_ApplyTranslationDefault = false
SZ_LayerCopies.axisY_TranslationDefault = 0
SZ_LayerCopies.axisY_TranslationRandomizeDefault = false
SZ_LayerCopies.axisY_TranslationMinDefault = 1
SZ_LayerCopies.axisY_TranslationMaxDefault = 5
SZ_LayerCopies.axisY_TranslationRandomizeAbsoluteDefault = false
SZ_LayerCopies.axisY_RotationDefault = 0
SZ_LayerCopies.axisY_ApplyRotationDefault = false
SZ_LayerCopies.axisY_RotationRandomizeDefault = false
SZ_LayerCopies.axisY_RotationMinDefault = -90
SZ_LayerCopies.axisY_RotationMaxDefault = 90
SZ_LayerCopies.axisY_RotationRandomizeAbsoluteDefault = false
SZ_LayerCopies.axisY_ApplyScaleDefault = false
SZ_LayerCopies.axisY_ScaleDefault = 1.1
SZ_LayerCopies.axisY_ScaleSameAsXDefault = false
SZ_LayerCopies.axisY_ScaleRandomizeDefault = false
SZ_LayerCopies.axisY_ScaleMinDefault = 0.5
SZ_LayerCopies.axisY_ScaleMaxDefault = 5
SZ_LayerCopies.axisY_ScaleRandomizeAbsoluteDefault = false

SZ_LayerCopies.axisZ_ApplyTranslationDefault = false
SZ_LayerCopies.axisZ_TranslationDefault = 0
SZ_LayerCopies.axisZ_TranslationRandomizeDefault = false
SZ_LayerCopies.axisZ_TranslationMinDefault = 1
SZ_LayerCopies.axisZ_TranslationMaxDefault = 5
SZ_LayerCopies.axisZ_TranslationRandomizeAbsoluteDefault = false
SZ_LayerCopies.axisZ_RotationDefault = 0
SZ_LayerCopies.axisZ_ApplyRotationDefault = false
SZ_LayerCopies.axisZ_RotationRandomizeDefault = false
SZ_LayerCopies.axisZ_RotationMinDefault = -90
SZ_LayerCopies.axisZ_RotationMaxDefault = 90
SZ_LayerCopies.axisZ_RotationRandomizeAbsoluteDefault = false
SZ_LayerCopies.axisZ_ApplyScaleDefault = false
SZ_LayerCopies.axisZ_ScaleDefault = 1.1
SZ_LayerCopies.axisZ_ScaleSameAsXDefault = false
SZ_LayerCopies.axisZ_ScaleRandomizeDefault = false
SZ_LayerCopies.axisZ_ScaleMinDefault = 0.5
SZ_LayerCopies.axisZ_ScaleMaxDefault = 5
SZ_LayerCopies.axisZ_ScaleRandomizeAbsoluteDefault = false

-- **************************************************
-- Recurring values
-- **************************************************

SZ_LayerCopies.numberOfCopies = SZ_LayerCopies.numberOfCopiesDefault
SZ_LayerCopies.stackBottomToTop = SZ_LayerCopies.stackBottomToTopDefault
SZ_LayerCopies.asReferences = SZ_LayerCopies.asReferencesDefault
SZ_LayerCopies.putInGroup = SZ_LayerCopies.putInGroupDefault
SZ_LayerCopies.makeInvisible = SZ_LayerCopies.makeInvisibleDefault
SZ_LayerCopies.distributeAlongCurve = SZ_LayerCopies.distributeAlongCurveDefault
SZ_LayerCopies.bendWithCurve = SZ_LayerCopies.bendWithCurveDefault
SZ_LayerCopies.backToBack = SZ_LayerCopies.backToBackDefault

SZ_LayerCopies.applyTimingOffset = SZ_LayerCopies.applyTimingOffsetDefault
SZ_LayerCopies.timingOffset = SZ_LayerCopies.timingOffsetDefault
SZ_LayerCopies.timingOffsetRandomize = SZ_LayerCopies.timingOffsetRandomizeDefault
SZ_LayerCopies.timingOffsetMin = SZ_LayerCopies.timingOffsetMinDefault
SZ_LayerCopies.timingOffsetMax = SZ_LayerCopies.timingOffsetMaxDefault
SZ_LayerCopies.timingOffsetRandomizeAbsolute = SZ_LayerCopies.timingOffsetRandomizeAbsoluteDefault

SZ_LayerCopies.axisX_ApplyTranslation = SZ_LayerCopies.axisX_ApplyTranslationDefault
SZ_LayerCopies.axisX_Translation = SZ_LayerCopies.axisX_TranslationDefault
SZ_LayerCopies.axisX_ApplyLayerSize = SZ_LayerCopies.axisX_ApplyLayerSizeDefault
SZ_LayerCopies.axisX_TranslationRandomize = SZ_LayerCopies.axisX_TranslationRandomizeDefault
SZ_LayerCopies.axisX_TranslationMin = SZ_LayerCopies.axisX_TranslationMinDefault
SZ_LayerCopies.axisX_TranslationMax = SZ_LayerCopies.axisX_TranslationMaxDefault
SZ_LayerCopies.axisX_TranslationRandomizeAbsolute = SZ_LayerCopies.axisX_TranslationRandomizeAbsoluteDefault
SZ_LayerCopies.axisX_Rotation = SZ_LayerCopies.axisX_RotationDefault
SZ_LayerCopies.axisX_ApplyRotation = SZ_LayerCopies.axisX_ApplyRotationDefault
SZ_LayerCopies.axisX_RotationRandomize = SZ_LayerCopies.axisX_RotationRandomizeDefault
SZ_LayerCopies.axisX_RotationMin = SZ_LayerCopies.axisX_RotationMinDefault
SZ_LayerCopies.axisX_RotationMax = SZ_LayerCopies.axisX_RotationMaxDefault
SZ_LayerCopies.axisX_RotationRandomizeAbsolute = SZ_LayerCopies.axisX_RotationRandomizeAbsoluteDefault
SZ_LayerCopies.axisX_ApplyScale = SZ_LayerCopies.axisX_ApplyScaleDefault
SZ_LayerCopies.axisX_Scale = SZ_LayerCopies.axisX_ScaleDefault
SZ_LayerCopies.axisX_ScaleRandomize = SZ_LayerCopies.axisX_ScaleRandomizeDefault
SZ_LayerCopies.axisX_ScaleMin = SZ_LayerCopies.axisX_ScaleMinDefault
SZ_LayerCopies.axisX_ScaleMax = SZ_LayerCopies.axisX_ScaleMaxDefault
SZ_LayerCopies.axisX_ScaleRandomizeAbsolute = SZ_LayerCopies.axisX_ScaleRandomizeAbsoluteDefault

SZ_LayerCopies.axisY_ApplyTranslation = SZ_LayerCopies.axisY_ApplyTranslationDefault
SZ_LayerCopies.axisY_Translation = SZ_LayerCopies.axisY_TranslationDefault
SZ_LayerCopies.axisY_TranslationRandomize = SZ_LayerCopies.axisY_TranslationRandomizeDefault
SZ_LayerCopies.axisY_TranslationMin = SZ_LayerCopies.axisY_TranslationMinDefault
SZ_LayerCopies.axisY_TranslationMax = SZ_LayerCopies.axisY_TranslationMaxDefault
SZ_LayerCopies.axisY_TranslationRandomizeAbsolute = SZ_LayerCopies.axisY_TranslationRandomizeAbsoluteDefault
SZ_LayerCopies.axisY_Rotation = SZ_LayerCopies.axisY_RotationDefault
SZ_LayerCopies.axisY_ApplyRotation = SZ_LayerCopies.axisY_ApplyRotationDefault
SZ_LayerCopies.axisY_RotationRandomize = SZ_LayerCopies.axisY_RotationRandomizeDefault
SZ_LayerCopies.axisY_RotationMin = SZ_LayerCopies.axisY_RotationMinDefault
SZ_LayerCopies.axisY_RotationMax = SZ_LayerCopies.axisY_RotationMaxDefault
SZ_LayerCopies.axisY_RotationRandomizeAbsolute = SZ_LayerCopies.axisY_RotationRandomizeAbsoluteDefault
SZ_LayerCopies.axisY_ApplyScale = SZ_LayerCopies.axisY_ApplyScaleDefault
SZ_LayerCopies.axisY_Scale = SZ_LayerCopies.axisY_ScaleDefault
SZ_LayerCopies.axisY_ScaleSameAsX = SZ_LayerCopies.axisY_ScaleSameAsXDefault
SZ_LayerCopies.axisY_ScaleRandomize = SZ_LayerCopies.axisY_ScaleRandomizeDefault
SZ_LayerCopies.axisY_ScaleMin = SZ_LayerCopies.axisY_ScaleMinDefault
SZ_LayerCopies.axisY_ScaleMax = SZ_LayerCopies.axisY_ScaleMaxDefault
SZ_LayerCopies.axisY_ScaleRandomizeAbsolute = SZ_LayerCopies.axisY_ScaleRandomizeAbsoluteDefault

SZ_LayerCopies.axisZ_ApplyTranslation = SZ_LayerCopies.axisZ_ApplyTranslationDefault
SZ_LayerCopies.axisZ_Translation = SZ_LayerCopies.axisZ_TranslationDefault
SZ_LayerCopies.axisZ_TranslationRandomize = SZ_LayerCopies.axisZ_TranslationRandomizeDefault
SZ_LayerCopies.axisZ_TranslationMin = SZ_LayerCopies.axisZ_TranslationMinDefault
SZ_LayerCopies.axisZ_TranslationMax = SZ_LayerCopies.axisZ_TranslationMaxDefault
SZ_LayerCopies.axisZ_TranslationRandomizeAbsolute = SZ_LayerCopies.axisZ_TranslationRandomizeAbsoluteDefault
SZ_LayerCopies.axisZ_Rotation = SZ_LayerCopies.axisZ_RotationDefault
SZ_LayerCopies.axisZ_ApplyRotation = SZ_LayerCopies.axisZ_ApplyRotationDefault
SZ_LayerCopies.axisZ_RotationRandomize = SZ_LayerCopies.axisZ_RotationRandomizeDefault
SZ_LayerCopies.axisZ_RotationMin = SZ_LayerCopies.axisZ_RotationMinDefault
SZ_LayerCopies.axisZ_RotationMax = SZ_LayerCopies.axisZ_RotationMaxDefault
SZ_LayerCopies.axisZ_RotationRandomizeAbsolute = SZ_LayerCopies.axisZ_RotationRandomizeAbsoluteDefault
SZ_LayerCopies.axisZ_ApplyScale = SZ_LayerCopies.axisZ_ApplyScaleDefault
SZ_LayerCopies.axisZ_Scale = SZ_LayerCopies.axisZ_ScaleDefault
SZ_LayerCopies.axisZ_ScaleSameAsX = SZ_LayerCopies.axisZ_ScaleSameAsXDefault
SZ_LayerCopies.axisZ_ScaleRandomize = SZ_LayerCopies.axisZ_ScaleRandomizeDefault
SZ_LayerCopies.axisZ_ScaleMin = SZ_LayerCopies.axisZ_ScaleMinDefault
SZ_LayerCopies.axisZ_ScaleMax = SZ_LayerCopies.axisZ_ScaleMaxDefault
SZ_LayerCopies.axisZ_ScaleRandomizeAbsolute = SZ_LayerCopies.axisZ_ScaleRandomizeAbsoluteDefault

-- **************************************************
-- Is Enabled
-- **************************************************

function SZ_LayerCopies:IsEnabled(moho)
	return true
end

-- **************************************************
-- Dialog
-- **************************************************

local SZ_LayerCopiesDialog = {}

SZ_LayerCopiesDialog.PADDING = 20
SZ_LayerCopiesDialog.NEGATIVE_PADDING = -18
SZ_LayerCopiesDialog.WHEEL_INCREMENT_FLOAT = 0.01
SZ_LayerCopiesDialog.GENERIC_MESSAGE = MOHO.MSG_BASE
SZ_LayerCopiesDialog.AXIS_X_TRANSLATION_INVERT = MOHO.MSG_BASE			+ 1
SZ_LayerCopiesDialog.AXIS_Y_TRANSLATION_INVERT = MOHO.MSG_BASE 			+ 2
SZ_LayerCopiesDialog.AXIS_Z_TRANSLATION_INVERT = MOHO.MSG_BASE 			+ 3
SZ_LayerCopiesDialog.GET_LAYER_SIZE_AXIS_X = MOHO.MSG_BASE				+ 4
SZ_LayerCopiesDialog.GET_LAYER_SIZE_AXIS_Y = MOHO.MSG_BASE				+ 5
SZ_LayerCopiesDialog.GET_LAYER_SIZE_AXIS_Z = MOHO.MSG_BASE				+ 6
SZ_LayerCopiesDialog.AXIS_X_ROTATION_INVERT = MOHO.MSG_BASE 			+ 7
SZ_LayerCopiesDialog.AXIS_Y_ROTATION_INVERT = MOHO.MSG_BASE 			+ 8
SZ_LayerCopiesDialog.AXIS_Z_ROTATION_INVERT = MOHO.MSG_BASE 			+ 9
SZ_LayerCopiesDialog.MEASURE_CURVE = MOHO.MSG_BASE 						+ 10
SZ_LayerCopiesDialog.RESET = MOHO.MSG_BASE 								+ 11
SZ_LayerCopiesDialog.SAVE = MOHO.MSG_BASE 								+ 12
SZ_LayerCopiesDialog.LOAD = MOHO.MSG_BASE 								+ 13
SZ_LayerCopiesDialog.ROUND_BUTTON_X = MOHO.MSG_BASE 					+ 14
SZ_LayerCopiesDialog.ROUND_BUTTON_Y = MOHO.MSG_BASE 					+ 15
SZ_LayerCopiesDialog.ROUND_BUTTON_Z = MOHO.MSG_BASE 					+ 16


function SZ_LayerCopiesDialog:new(moho)
	local d = LM.GUI.SimpleDialog(SZ_LayerCopies:Localize("UILabel") .. SZ_LayerCopies:Localize("VersionText") .. SZ_LayerCopies:Version(), SZ_LayerCopiesDialog)
	local l = d:GetLayout()
	d.inputs = {}
	
	d.moho = moho
	d.layerBounds = moho.layer:Bounds(moho.layerFrame)	
	
	l:PushV()	
		l:PushH()
			l:AddChild(LM.GUI.StaticText(SZ_LayerCopies:Localize("NumberOfCopies")))
			d.inputs.numberOfCopies = LM.GUI.TextControl(0, "0000", 0, LM.GUI.FIELD_UINT)
			l:AddChild(d.inputs.numberOfCopies)
			d.inputs.asReferences = LM.GUI.CheckBox(SZ_LayerCopies:Localize("AsReferences"))
			l:AddChild(d.inputs.asReferences)
		l:Pop()		
		l:PushH()
			d.inputs.applyTimingOffset = LM.GUI.CheckBox(SZ_LayerCopies:Localize("TimingOffset"), self.GENERIC_MESSAGE)
			l:AddChild(d.inputs.applyTimingOffset, LM.GUI.ALIGN_LEFT)
			d.inputs.timingOffset = LM.GUI.TextControl(0, "0000", 0, LM.GUI.FIELD_INT)
			l:AddChild(d.inputs.timingOffset)
			d.inputs.timingOffsetRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
			l:AddChild(d.inputs.timingOffsetRandomize, LM.GUI.ALIGN_LEFT)
			d.inputs.timingOffsetMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
			l:AddChild(d.inputs.timingOffsetMinLabel, LM.GUI.ALIGN_RIGHT)
			l:AddPadding(self.NEGATIVE_PADDING)
			d.inputs.timingOffsetMin = LM.GUI.TextControl(0, "0000", 0, LM.GUI.FIELD_INT)
			l:AddChild(d.inputs.timingOffsetMin, LM.GUI.ALIGN_LEFT)
			d.inputs.timingOffsetMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
			l:AddChild(d.inputs.timingOffsetMaxLabel, LM.GUI.ALIGN_RIGHT)
			l:AddPadding(self.NEGATIVE_PADDING)
			d.inputs.timingOffsetMax = LM.GUI.TextControl(0, "0000", 0, LM.GUI.FIELD_INT)
			l:AddChild(d.inputs.timingOffsetMax, LM.GUI.ALIGN_LEFT)
			d.inputs.timingOffsetRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
			l:AddChild(d.inputs.timingOffsetRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
		l:Pop()	    
		d.inputs.stackBottomToTop = LM.GUI.CheckBox(SZ_LayerCopies:Localize("StackBottomToTop"))
		l:AddChild(d.inputs.stackBottomToTop, LM.GUI.ALIGN_LEFT)
		d.inputs.makeInvisible = LM.GUI.CheckBox(SZ_LayerCopies:Localize("MakeInvisible"))
		l:AddChild(d.inputs.makeInvisible, LM.GUI.ALIGN_LEFT)
		d.inputs.putInGroup = LM.GUI.CheckBox(SZ_LayerCopies:Localize("PutInGroup"))
		l:AddChild(d.inputs.putInGroup, LM.GUI.ALIGN_LEFT)
		l:PushH()
			d.inputs.distributeAlongCurve = LM.GUI.CheckBox(SZ_LayerCopies:Localize("DistributeAlongCurve"), self.GENERIC_MESSAGE)
			d.inputs.distributeAlongCurve:SetToolTip(SZ_LayerCopies:Localize("FollowCurveMessage"))
			l:AddChild(d.inputs.distributeAlongCurve, LM.GUI.ALIGN_LEFT)
			d.inputs.bendWithCurve = LM.GUI.CheckBox(SZ_LayerCopies:Localize("BendWithCurve"))
			d.inputs.bendWithCurve:SetToolTip(SZ_LayerCopies:Localize("FollowCurveMessage"))
			l:AddChild(d.inputs.bendWithCurve, LM.GUI.ALIGN_LEFT)
			d.inputs.backToBack = LM.GUI.CheckBox(SZ_LayerCopies:Localize("BackToBack"))
			d.inputs.backToBack:SetToolTip(SZ_LayerCopies:Localize("FollowCurveMessage"))
			l:AddChild(d.inputs.backToBack, LM.GUI.ALIGN_LEFT)
			d.inputs.measureCurve = LM.GUI.Button(SZ_LayerCopies:Localize("MeasureCurve"), self.MEASURE_CURVE)
			d.inputs.measureCurve:SetToolTip(SZ_LayerCopies:Localize("FollowCurveMessage"))
			l:AddChild(d.inputs.measureCurve, LM.GUI.ALIGN_LEFT)
		l:Pop()
		d.inputs.followPathWarning = LM.GUI.DynamicText(SZ_LayerCopies:Localize("FollowPathWarning"))
		l:AddPadding(self.NEGATIVE_PADDING)
		l:AddChild(d.inputs.followPathWarning, LM.GUI.ALIGN_LEFT)
		l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
		l:AddPadding(self.NEGATIVE_PADDING + 2)
		l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
		l:AddPadding(self.NEGATIVE_PADDING + 2)
		l:PushH()
			l:PushV() -- X AXIS START
				l:AddChild(LM.GUI.StaticText(SZ_LayerCopies:Localize("AxisX")), LM.GUI.ALIGN_CENTER)
				-- X AXIS TRANSLATION
				d.inputs.axisX_ApplyTranslation = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyTranslation"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisX_ApplyTranslation, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_TranslationPlusMinus = LM.GUI.Button("+/-", self.AXIS_X_TRANSLATION_INVERT)
					l:AddChild(d.inputs.axisX_TranslationPlusMinus, LM.GUI.ALIGN_RIGHT)			
					d.inputs.axisX_Translation = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisX_Translation:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisX_Translation, LM.GUI.ALIGN_RIGHT)
					d.inputs.axisX_GetLayerSize = LM.GUI.Button(SZ_LayerCopies:Localize("AxisX_GetLayerSize"), self.GET_LAYER_SIZE_AXIS_X)
					l:AddChild(d.inputs.axisX_GetLayerSize, LM.GUI.ALIGN_RIGHT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_TranslationRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisX_TranslationRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisX_TranslationMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisX_TranslationMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisX_TranslationMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisX_TranslationMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisX_TranslationMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisX_TranslationMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisX_TranslationMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisX_TranslationMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisX_TranslationMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisX_TranslationMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisX_TranslationRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisX_TranslationRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_ApplyLayerSize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("AxisX_ApplyLayerSize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisX_ApplyLayerSize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
				-- X AXIS ROTATION
				d.inputs.axisX_ApplyRotation = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyRotation"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisX_ApplyRotation, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_RotationPlusMinus = LM.GUI.Button("+/-", self.AXIS_X_ROTATION_INVERT)
					l:AddChild(d.inputs.axisX_RotationPlusMinus, LM.GUI.ALIGN_RIGHT)			
					d.inputs.axisX_Rotation = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisX_Rotation:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisX_Rotation, LM.GUI.ALIGN_RIGHT)
					d.inputs.roundButtonX = LM.GUI.Button(SZ_LayerCopies:Localize("RoundButtonText"), self.ROUND_BUTTON_X)
					l:AddChild(d.inputs.roundButtonX, LM.GUI.ALIGN_RIGHT)
					d.inputs.roundButtonX:SetToolTip(SZ_LayerCopies:Localize("RoundButtonDescription"))
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_RotationRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisX_RotationRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisX_RotationMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisX_RotationMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisX_RotationMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisX_RotationMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisX_RotationMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisX_RotationMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisX_RotationMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisX_RotationMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisX_RotationMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisX_RotationMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisX_RotationRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisX_RotationRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
				-- X AXIS SCALE
				d.inputs.axisX_ApplyScale = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyScale"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisX_ApplyScale, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_Scale = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisX_Scale:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisX_Scale, LM.GUI.ALIGN_RIGHT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisX_ScaleRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisX_ScaleRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisX_ScaleMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisX_ScaleMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisX_ScaleMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisX_ScaleMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisX_ScaleMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisX_ScaleMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisX_ScaleMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisX_ScaleMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisX_ScaleMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisX_ScaleMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisX_ScaleRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisX_ScaleRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
			l:Pop()
			l:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
			l:AddPadding(self.NEGATIVE_PADDING + 2)
			l:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
			l:PushV() -- Y AXIS
				l:AddChild(LM.GUI.StaticText(SZ_LayerCopies:Localize("AxisY")), LM.GUI.ALIGN_CENTER)
				-- Y AXIS TRANSLATION
				d.inputs.axisY_ApplyTranslation = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyTranslation"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisY_ApplyTranslation, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_TranslationPlusMinus = LM.GUI.Button("+/-", self.AXIS_Y_TRANSLATION_INVERT)
					l:AddChild(d.inputs.axisY_TranslationPlusMinus, LM.GUI.ALIGN_RIGHT)			
					d.inputs.axisY_Translation = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisY_Translation:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisY_Translation, LM.GUI.ALIGN_RIGHT)
					d.inputs.axisY_GetLayerSize = LM.GUI.Button(SZ_LayerCopies:Localize("AxisY_GetLayerSize"), self.GET_LAYER_SIZE_AXIS_Y)
					l:AddChild(d.inputs.axisY_GetLayerSize, LM.GUI.ALIGN_RIGHT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_TranslationRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisY_TranslationRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisY_TranslationMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisY_TranslationMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisY_TranslationMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisY_TranslationMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisY_TranslationMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisY_TranslationMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisY_TranslationMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisY_TranslationMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisY_TranslationMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisY_TranslationMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisY_TranslationRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisY_TranslationRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:AddPadding(self.PADDING)
				l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
				-- Y AXIS ROTATION
				d.inputs.axisY_ApplyRotation = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyRotation"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisY_ApplyRotation, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_RotationPlusMinus = LM.GUI.Button("+/-", self.AXIS_Y_ROTATION_INVERT)
					l:AddChild(d.inputs.axisY_RotationPlusMinus, LM.GUI.ALIGN_RIGHT)			
					d.inputs.axisY_Rotation = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisY_Rotation:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisY_Rotation, LM.GUI.ALIGN_RIGHT)
					d.inputs.roundButtonY = LM.GUI.Button(SZ_LayerCopies:Localize("RoundButtonText"), self.ROUND_BUTTON_Y)
					l:AddChild(d.inputs.roundButtonY, LM.GUI.ALIGN_RIGHT)
					d.inputs.roundButtonY:SetToolTip(SZ_LayerCopies:Localize("RoundButtonDescription"))
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_RotationRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisY_RotationRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisY_RotationMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisY_RotationMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisY_RotationMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisY_RotationMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisY_RotationMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisY_RotationMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisY_RotationMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisY_RotationMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisY_RotationMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisY_RotationMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisY_RotationRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisY_RotationRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
				-- Y AXIS SCALE
				d.inputs.axisY_ApplyScale = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyScale"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisY_ApplyScale, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_Scale = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisY_Scale:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisY_Scale, LM.GUI.ALIGN_RIGHT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_ScaleRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisY_ScaleRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisY_ScaleMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisY_ScaleMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisY_ScaleMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisY_ScaleMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisY_ScaleMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisY_ScaleMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisY_ScaleMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisY_ScaleMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisY_ScaleMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisY_ScaleMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisY_ScaleRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisY_ScaleRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisY_ScaleSameAsX = LM.GUI.CheckBox(SZ_LayerCopies:Localize("SameAsX"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisY_ScaleSameAsX, LM.GUI.ALIGN_LEFT)
				l:Pop()
			l:Pop()
			l:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
			l:AddPadding(self.NEGATIVE_PADDING + 2)
			l:AddChild(LM.GUI.Divider(true), LM.GUI.ALIGN_FILL)
			l:PushV() -- Z AXIS
				l:AddChild(LM.GUI.StaticText(SZ_LayerCopies:Localize("AxisZ")), LM.GUI.ALIGN_CENTER)
				-- Z AXIS TRANSLATION
				d.inputs.axisZ_ApplyTranslation = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyTranslation"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisZ_ApplyTranslation, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisZ_TranslationPlusMinus = LM.GUI.Button("+/-", self.AXIS_Z_TRANSLATION_INVERT)
					l:AddChild(d.inputs.axisZ_TranslationPlusMinus, LM.GUI.ALIGN_RIGHT)			
					d.inputs.axisZ_Translation = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisZ_Translation:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisZ_Translation, LM.GUI.ALIGN_RIGHT)
					d.inputs.axisZ_GetLayerSize = LM.GUI.Button(SZ_LayerCopies:Localize("AxisZ_GetLayerSize"), self.GET_LAYER_SIZE_AXIS_Z)
					l:AddChild(d.inputs.axisZ_GetLayerSize, LM.GUI.ALIGN_RIGHT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisZ_TranslationRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisZ_TranslationRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisZ_TranslationMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisZ_TranslationMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisZ_TranslationMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisZ_TranslationMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisZ_TranslationMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisZ_TranslationMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisZ_TranslationMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisZ_TranslationMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisZ_TranslationMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisZ_TranslationMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisZ_TranslationRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisZ_TranslationRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:AddPadding(self.PADDING)
				l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
				-- Z AXIS ROTATION
				d.inputs.axisZ_ApplyRotation = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyRotation"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisZ_ApplyRotation, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisZ_RotationPlusMinus = LM.GUI.Button("+/-", self.AXIS_Z_ROTATION_INVERT)
					l:AddChild(d.inputs.axisZ_RotationPlusMinus, LM.GUI.ALIGN_RIGHT)			
					d.inputs.axisZ_Rotation = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisZ_Rotation:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisZ_Rotation, LM.GUI.ALIGN_RIGHT)
					d.inputs.roundButtonZ = LM.GUI.Button(SZ_LayerCopies:Localize("RoundButtonText"), self.ROUND_BUTTON_Z)
					l:AddChild(d.inputs.roundButtonZ, LM.GUI.ALIGN_RIGHT)
					d.inputs.roundButtonZ:SetToolTip(SZ_LayerCopies:Localize("RoundButtonDescription"))
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisZ_RotationRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisZ_RotationRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisZ_RotationMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisZ_RotationMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisZ_RotationMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisZ_RotationMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisZ_RotationMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisZ_RotationMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisZ_RotationMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisZ_RotationMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisZ_RotationMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisZ_RotationMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisZ_RotationRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisZ_RotationRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
				-- Z AXIS SCALE
				d.inputs.axisZ_ApplyScale = LM.GUI.CheckBox(SZ_LayerCopies:Localize("ApplyScale"), self.GENERIC_MESSAGE)
				l:AddChild(d.inputs.axisZ_ApplyScale, LM.GUI.ALIGN_LEFT)
				l:PushH()
					l:AddPadding(self.PADDING)	
					d.inputs.axisZ_Scale = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					d.inputs.axisZ_Scale:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					l:AddChild(d.inputs.axisZ_Scale, LM.GUI.ALIGN_RIGHT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisZ_ScaleRandomize = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Randomize"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisZ_ScaleRandomize, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING * 2)
					d.inputs.axisZ_ScaleMinLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Min"))
					l:AddChild(d.inputs.axisZ_ScaleMinLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisZ_ScaleMin = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisZ_ScaleMin, LM.GUI.ALIGN_LEFT)
					d.inputs.axisZ_ScaleMin:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisZ_ScaleMaxLabel = LM.GUI.DynamicText(SZ_LayerCopies:Localize("Max"))
					l:AddChild(d.inputs.axisZ_ScaleMaxLabel, LM.GUI.ALIGN_RIGHT)
					l:AddPadding(self.NEGATIVE_PADDING)
					d.inputs.axisZ_ScaleMax = LM.GUI.TextControl(0, "000000", 0, LM.GUI.FIELD_FLOAT)
					l:AddChild(d.inputs.axisZ_ScaleMax, LM.GUI.ALIGN_LEFT)
					d.inputs.axisZ_ScaleMax:SetWheelInc(self.WHEEL_INCREMENT_FLOAT)
					d.inputs.axisZ_ScaleRandomizeAbsolute = LM.GUI.CheckBox(SZ_LayerCopies:Localize("Absolute"))
					l:AddChild(d.inputs.axisZ_ScaleRandomizeAbsolute, LM.GUI.ALIGN_LEFT)
				l:Pop()
				l:PushH()
					l:AddPadding(self.PADDING)
					d.inputs.axisZ_ScaleSameAsX = LM.GUI.CheckBox(SZ_LayerCopies:Localize("SameAsX"), self.GENERIC_MESSAGE)
					l:AddChild(d.inputs.axisZ_ScaleSameAsX, LM.GUI.ALIGN_LEFT)
				l:Pop()
			l:Pop()
		l:Pop()
		l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
		l:AddPadding(self.NEGATIVE_PADDING + 2)
		l:AddChild(LM.GUI.Divider(false), LM.GUI.ALIGN_FILL)
		l:PushH()
			d.saveButton = LM.GUI.Button(SZ_LayerCopies:Localize("Save"), self.SAVE)
			l:AddChild(d.saveButton)			
			d.loadButton = LM.GUI.Button(SZ_LayerCopies:Localize("Load"), self.LOAD)
			l:AddChild(d.loadButton)
			d.resetButton = LM.GUI.Button(SZ_LayerCopies:Localize("Reset"), self.RESET)
			l:AddChild(d.resetButton)
		l:Pop()
	l:Pop()
	
	return d
end

function SZ_LayerCopiesDialog:UpdateWidgets()
	self.inputs.numberOfCopies:SetValue(SZ_LayerCopies.numberOfCopies)
	self.inputs.asReferences:SetValue(SZ_LayerCopies.asReferences)
	self.inputs.applyTimingOffset:SetValue(SZ_LayerCopies.applyTimingOffset)
	self.inputs.timingOffset:SetValue(SZ_LayerCopies.timingOffset)
	self.inputs.timingOffsetRandomize:SetValue(SZ_LayerCopies.timingOffsetRandomize)
	self.inputs.timingOffsetMin:SetValue(SZ_LayerCopies.timingOffsetMin)
	self.inputs.timingOffsetMax:SetValue(SZ_LayerCopies.timingOffsetMax)
	self.inputs.timingOffsetRandomizeAbsolute:SetValue(SZ_LayerCopies.timingOffsetRandomizeAbsolute)
	self.inputs.stackBottomToTop:SetValue(SZ_LayerCopies.stackBottomToTop)
	self.inputs.putInGroup:SetValue(SZ_LayerCopies.putInGroup)
	self.inputs.makeInvisible:SetValue(SZ_LayerCopies.makeInvisible)
	
	local currentLayer = self.moho.layer
		
	if currentLayer:GetFollowingCurve() then
		self.inputs.distributeAlongCurve:SetValue(SZ_LayerCopies.distributeAlongCurve)
		self.inputs.bendWithCurve:SetValue(SZ_LayerCopies.bendWithCurve)
		self.inputs.backToBack:SetValue(SZ_LayerCopies.backToBack)
	else
		self.inputs.distributeAlongCurve:SetValue(false)
		self.inputs.bendWithCurve:SetValue(false)
		self.inputs.backToBack:SetValue(false)
		self.inputs.distributeAlongCurve:Enable(false)
		self.inputs.bendWithCurve:Enable(false)
		self.inputs.backToBack:Enable(false)
		self.inputs.measureCurve:Enable(false)
		self.inputs.followPathWarning:Enable(false)
	end
	
	self.inputs.axisX_ApplyTranslation:SetValue(SZ_LayerCopies.axisX_ApplyTranslation)
	self.inputs.axisX_Translation:SetValue(SZ_LayerCopies.axisX_Translation)
	self.inputs.axisX_ApplyLayerSize:SetValue(SZ_LayerCopies.axisX_ApplyLayerSize)
	self.inputs.axisX_TranslationRandomize:SetValue(SZ_LayerCopies.axisX_TranslationRandomize)
	self.inputs.axisX_TranslationMin:SetValue(SZ_LayerCopies.axisX_TranslationMin)
	self.inputs.axisX_TranslationMax:SetValue(SZ_LayerCopies.axisX_TranslationMax)
	self.inputs.axisX_TranslationRandomizeAbsolute:SetValue(SZ_LayerCopies.axisX_TranslationRandomizeAbsolute)
	self.inputs.axisX_ApplyRotation:SetValue(SZ_LayerCopies.axisX_ApplyRotation)
	self.inputs.axisX_Rotation:SetValue(SZ_LayerCopies.axisX_Rotation)	
	self.inputs.axisX_RotationRandomize:SetValue(SZ_LayerCopies.axisX_RotationRandomize)
	self.inputs.axisX_RotationMin:SetValue(SZ_LayerCopies.axisX_RotationMin)
	self.inputs.axisX_RotationMax:SetValue(SZ_LayerCopies.axisX_RotationMax)	
	self.inputs.axisX_RotationRandomizeAbsolute:SetValue(SZ_LayerCopies.axisX_RotationRandomizeAbsolute)
	self.inputs.axisX_ApplyScale:SetValue(SZ_LayerCopies.axisX_ApplyScale)
	self.inputs.axisX_Scale:SetValue(SZ_LayerCopies.axisX_Scale)	
	self.inputs.axisX_ScaleRandomize:SetValue(SZ_LayerCopies.axisX_ScaleRandomize)
	self.inputs.axisX_ScaleMin:SetValue(SZ_LayerCopies.axisX_ScaleMin)
	self.inputs.axisX_ScaleMax:SetValue(SZ_LayerCopies.axisX_ScaleMax)
	self.inputs.axisX_ScaleRandomizeAbsolute:SetValue(SZ_LayerCopies.axisX_ScaleRandomizeAbsolute)
	
	self.inputs.axisY_ApplyTranslation:SetValue(SZ_LayerCopies.axisY_ApplyTranslation)
	self.inputs.axisY_Translation:SetValue(SZ_LayerCopies.axisY_Translation)
	self.inputs.axisY_TranslationRandomize:SetValue(SZ_LayerCopies.axisY_TranslationRandomize)
	self.inputs.axisY_TranslationMin:SetValue(SZ_LayerCopies.axisY_TranslationMin)
	self.inputs.axisY_TranslationMax:SetValue(SZ_LayerCopies.axisY_TranslationMax)	
	self.inputs.axisY_TranslationRandomizeAbsolute:SetValue(SZ_LayerCopies.axisY_TranslationRandomizeAbsolute)
	self.inputs.axisY_ApplyRotation:SetValue(SZ_LayerCopies.axisY_ApplyRotation)
	self.inputs.axisY_Rotation:SetValue(SZ_LayerCopies.axisY_Rotation)	
	self.inputs.axisY_RotationRandomize:SetValue(SZ_LayerCopies.axisY_RotationRandomize)
	self.inputs.axisY_RotationMin:SetValue(SZ_LayerCopies.axisY_RotationMin)
	self.inputs.axisY_RotationMax:SetValue(SZ_LayerCopies.axisY_RotationMax)	
	self.inputs.axisY_RotationRandomizeAbsolute:SetValue(SZ_LayerCopies.axisY_RotationRandomizeAbsolute)
	self.inputs.axisY_ApplyScale:SetValue(SZ_LayerCopies.axisY_ApplyScale)
	self.inputs.axisY_Scale:SetValue(SZ_LayerCopies.axisY_Scale)
	self.inputs.axisY_ScaleSameAsX:SetValue(SZ_LayerCopies.axisY_ScaleSameAsX)
	self.inputs.axisY_ScaleRandomize:SetValue(SZ_LayerCopies.axisY_ScaleRandomize)
	self.inputs.axisY_ScaleMin:SetValue(SZ_LayerCopies.axisY_ScaleMin)
	self.inputs.axisY_ScaleMax:SetValue(SZ_LayerCopies.axisY_ScaleMax)
	self.inputs.axisY_ScaleRandomizeAbsolute:SetValue(SZ_LayerCopies.axisY_ScaleRandomizeAbsolute)
	
	self.inputs.axisZ_ApplyTranslation:SetValue(SZ_LayerCopies.axisZ_ApplyTranslation)
	self.inputs.axisZ_Translation:SetValue(SZ_LayerCopies.axisZ_Translation)
	self.inputs.axisZ_TranslationRandomize:SetValue(SZ_LayerCopies.axisZ_TranslationRandomize)
	self.inputs.axisZ_TranslationMin:SetValue(SZ_LayerCopies.axisZ_TranslationMin)
	self.inputs.axisZ_TranslationMax:SetValue(SZ_LayerCopies.axisZ_TranslationMax)	
	self.inputs.axisZ_TranslationRandomizeAbsolute:SetValue(SZ_LayerCopies.axisZ_TranslationRandomizeAbsolute)
	self.inputs.axisZ_ApplyRotation:SetValue(SZ_LayerCopies.axisZ_ApplyRotation)
	self.inputs.axisZ_Rotation:SetValue(SZ_LayerCopies.axisZ_Rotation)	
	self.inputs.axisZ_RotationRandomize:SetValue(SZ_LayerCopies.axisZ_RotationRandomize)
	self.inputs.axisZ_RotationMin:SetValue(SZ_LayerCopies.axisZ_RotationMin)
	self.inputs.axisZ_RotationMax:SetValue(SZ_LayerCopies.axisZ_RotationMax)	
	self.inputs.axisZ_RotationRandomizeAbsolute:SetValue(SZ_LayerCopies.axisZ_RotationRandomizeAbsolute)
	self.inputs.axisZ_ApplyScale:SetValue(SZ_LayerCopies.axisZ_ApplyScale)
	self.inputs.axisZ_Scale:SetValue(SZ_LayerCopies.axisZ_Scale)
	self.inputs.axisZ_ScaleSameAsX:SetValue(SZ_LayerCopies.axisZ_ScaleSameAsX)
	self.inputs.axisZ_ScaleRandomize:SetValue(SZ_LayerCopies.axisZ_ScaleRandomize)
	self.inputs.axisZ_ScaleMin:SetValue(SZ_LayerCopies.axisZ_ScaleMin)
	self.inputs.axisZ_ScaleMax:SetValue(SZ_LayerCopies.axisZ_ScaleMax)
	self.inputs.axisZ_ScaleRandomizeAbsolute:SetValue(SZ_LayerCopies.axisZ_ScaleRandomizeAbsolute)
	
	self:HandleMessage(self.GENERIC_MESSAGE)
end

function SZ_LayerCopiesDialog:HandleMessage(msg)
	self:EnableDisable(self.inputs.distributeAlongCurve, {self.inputs.bendWithCurve, self.inputs.backToBack, self.inputs.measureCurve, self.inputs.followPathWarning})
	
	self:EnableDisable(
		self.inputs.applyTimingOffset,
		{self.inputs.timingOffset, self.inputs.timingOffsetRandomize, self.inputs.timingOffsetMinLabel, self.inputs.timingOffsetMin, self.inputs.timingOffsetMaxLabel, self.inputs.timingOffsetMax, self.inputs.timingOffsetRandomizeAbsolute}
	)
	
	self:EnableDisable(
		self.inputs.timingOffsetRandomize,
		{self.inputs.timingOffsetMinLabel, self.inputs.timingOffsetMin, self.inputs.timingOffsetMaxLabel, self.inputs.timingOffsetMax, self.inputs.timingOffsetRandomizeAbsolute},
		{self.inputs.timingOffset}
	)
	
	self:EnableDisable(self.inputs.axisX_ApplyTranslation, {self.inputs.axisX_Translation, self.inputs.axisX_TranslationPlusMinus, self.inputs.axisX_GetLayerSize, self.inputs.axisX_ApplyLayerSize, self.inputs.axisX_TranslationRandomize, self.inputs.axisX_TranslationMinLabel, self.inputs.axisX_TranslationMin, self.inputs.axisX_TranslationMaxLabel, self.inputs.axisX_TranslationMax, self.inputs.axisX_TranslationRandomizeAbsolute})
	
	self:EnableDisable(self.inputs.axisX_ApplyLayerSize, nil, {self.inputs.axisX_Translation, self.inputs.axisX_TranslationPlusMinus, self.inputs.axisX_GetLayerSize, self.inputs.axisX_TranslationRandomize, self.inputs.axisX_TranslationMinLabel, self.inputs.axisX_TranslationMin, self.inputs.axisX_TranslationMaxLabel, self.inputs.axisX_TranslationMax, self.inputs.axisX_TranslationRandomizeAbsolute})
		
	self:EnableDisable(
		self.inputs.axisX_TranslationRandomize,
		{self.inputs.axisX_TranslationMinLabel, self.inputs.axisX_TranslationMin, self.inputs.axisX_TranslationMaxLabel, self.inputs.axisX_TranslationMax, self.inputs.axisX_TranslationRandomizeAbsolute},
		{self.inputs.axisX_Translation, self.inputs.axisX_TranslationPlusMinus, self.inputs.axisX_GetLayerSize, self.inputs.axisX_ApplyLayerSize}
	)
	
	self:EnableDisable(self.inputs.axisX_ApplyRotation, {self.inputs.axisX_Rotation, self.inputs.axisX_RotationPlusMinus, self.inputs.axisX_RotationRandomize, self.inputs.axisX_RotationMinLabel, self.inputs.axisX_RotationMin, self.inputs.axisX_RotationMaxLabel, self.inputs.axisX_RotationMax, self.inputs.axisX_RotationRandomizeAbsolute, self.inputs.roundButtonX})
		
	self:EnableDisable(
		self.inputs.axisX_RotationRandomize,
		{self.inputs.axisX_RotationMinLabel, self.inputs.axisX_RotationMin, self.inputs.axisX_RotationMaxLabel, self.inputs.axisX_RotationMax, self.inputs.axisX_RotationRandomizeAbsolute},
		{self.inputs.axisX_Rotation, self.inputs.axisX_RotationPlusMinus, self.inputs.roundButtonX}
	)
	
	self:EnableDisable(self.inputs.axisX_ApplyScale, {self.inputs.axisX_Scale, self.inputs.axisX_ScaleRandomize, self.inputs.axisX_ScaleMinLabel, self.inputs.axisX_ScaleMin, self.inputs.axisX_ScaleMaxLabel, self.inputs.axisX_ScaleMax, self.inputs.axisX_ScaleRandomizeAbsolute})
		
	self:EnableDisable(
		self.inputs.axisX_ScaleRandomize,
		{self.inputs.axisX_ScaleMinLabel, self.inputs.axisX_ScaleMin, self.inputs.axisX_ScaleMaxLabel, self.inputs.axisX_ScaleMax, self.inputs.axisX_ScaleRandomizeAbsolute},
		{self.inputs.axisX_Scale}
	)
	
	-- Do not allow to enable "Same as X" if ScaleX is not applied
	if self.inputs.axisX_ApplyScale:Value() == false then
		self.inputs.axisY_ScaleSameAsX:SetValue(false)
		self.inputs.axisZ_ScaleSameAsX:SetValue(false)
	end
	
	-- Y AXIS
	self:EnableDisable(self.inputs.axisY_ApplyTranslation, {self.inputs.axisY_Translation, self.inputs.axisY_TranslationPlusMinus, self.inputs.axisY_GetLayerSize, self.inputs.axisY_TranslationRandomize, self.inputs.axisY_TranslationMinLabel, self.inputs.axisY_TranslationMin, self.inputs.axisY_TranslationMaxLabel, self.inputs.axisY_TranslationMax, self.inputs.axisY_TranslationRandomizeAbsolute})
		
	self:EnableDisable(
		self.inputs.axisY_TranslationRandomize,
		{self.inputs.axisY_TranslationMinLabel, self.inputs.axisY_TranslationMin, self.inputs.axisY_TranslationMaxLabel, self.inputs.axisY_TranslationMax, self.inputs.axisY_TranslationRandomizeAbsolute},
		{self.inputs.axisY_Translation, self.inputs.axisY_TranslationPlusMinus, self.inputs.axisY_GetLayerSize}
	)
	
	self:EnableDisable(self.inputs.axisY_ApplyRotation, {self.inputs.axisY_Rotation, self.inputs.axisY_RotationPlusMinus, self.inputs.axisY_RotationRandomize, self.inputs.axisY_RotationMinLabel, self.inputs.axisY_RotationMin, self.inputs.axisY_RotationMaxLabel, self.inputs.axisY_RotationMax, self.inputs.axisY_RotationRandomizeAbsolute, self.inputs.roundButtonY})
		
	self:EnableDisable(
		self.inputs.axisY_RotationRandomize,
		{self.inputs.axisY_RotationMinLabel, self.inputs.axisY_RotationMin, self.inputs.axisY_RotationMaxLabel, self.inputs.axisY_RotationMax, self.inputs.axisY_RotationRandomizeAbsolute},
		{self.inputs.axisY_Rotation, self.inputs.axisY_RotationPlusMinus, self.inputs.roundButtonY}
	)
	
	self:EnableDisable(self.inputs.axisY_ApplyScale, {self.inputs.axisY_Scale,self.inputs.axisY_ScaleSameAsX, self.inputs.axisY_ScaleRandomize, self.inputs.axisY_ScaleMinLabel, self.inputs.axisY_ScaleMin, self.inputs.axisY_ScaleMaxLabel, self.inputs.axisY_ScaleMax, self.inputs.axisY_ScaleRandomizeAbsolute})
	
	self:EnableDisable(self.inputs.axisY_ScaleSameAsX, nil, {self.inputs.axisY_Scale, self.inputs.axisY_ScaleRandomize, self.inputs.axisY_ScaleMinLabel, self.inputs.axisY_ScaleMin, self.inputs.axisY_ScaleMaxLabel, self.inputs.axisY_ScaleMax, self.inputs.axisY_ScaleRandomizeAbsolute})
		
	self:EnableDisable(
		self.inputs.axisY_ScaleRandomize,
		{self.inputs.axisY_ScaleMinLabel, self.inputs.axisY_ScaleMin, self.inputs.axisY_ScaleMaxLabel, self.inputs.axisY_ScaleMax, self.inputs.axisY_ScaleRandomizeAbsolute},
		{self.inputs.axisY_Scale}
	)
			
	-- Z AXIS
	self:EnableDisable(self.inputs.axisZ_ApplyTranslation, {self.inputs.axisZ_Translation, self.inputs.axisZ_TranslationPlusMinus, self.inputs.axisZ_GetLayerSize, self.inputs.axisZ_TranslationRandomize, self.inputs.axisZ_TranslationMinLabel, self.inputs.axisZ_TranslationMin, self.inputs.axisZ_TranslationMaxLabel, self.inputs.axisZ_TranslationMax, self.inputs.axisZ_TranslationRandomizeAbsolute})
		
	self:EnableDisable(
		self.inputs.axisZ_TranslationRandomize,
		{self.inputs.axisZ_TranslationMinLabel, self.inputs.axisZ_TranslationMin, self.inputs.axisZ_TranslationMaxLabel, self.inputs.axisZ_TranslationMax, self.inputs.axisZ_TranslationRandomizeAbsolute},
		{self.inputs.axisZ_Translation, self.inputs.axisZ_TranslationPlusMinus, self.inputs.axisZ_GetLayerSize}
	)
	
	self:EnableDisable(self.inputs.axisZ_ApplyRotation, {self.inputs.axisZ_Rotation, self.inputs.axisZ_RotationPlusMinus, self.inputs.axisZ_RotationRandomize, self.inputs.axisZ_RotationMinLabel, self.inputs.axisZ_RotationMin, self.inputs.axisZ_RotationMaxLabel, self.inputs.axisZ_RotationMax, self.inputs.axisZ_RotationRandomizeAbsolute, self.inputs.roundButtonZ})
		
	self:EnableDisable(
		self.inputs.axisZ_RotationRandomize,
		{self.inputs.axisZ_RotationMinLabel, self.inputs.axisZ_RotationMin, self.inputs.axisZ_RotationMaxLabel, self.inputs.axisZ_RotationMax, self.inputs.axisZ_RotationRandomizeAbsolute},
		{self.inputs.axisZ_Rotation, self.inputs.axisZ_RotationPlusMinus, self.inputs.roundButtonZ}
	)
	
	self:EnableDisable(self.inputs.axisZ_ApplyScale, {self.inputs.axisZ_Scale, self.inputs.axisZ_ScaleSameAsX, self.inputs.axisZ_ScaleRandomize, self.inputs.axisZ_ScaleMinLabel, self.inputs.axisZ_ScaleMin, self.inputs.axisZ_ScaleMaxLabel, self.inputs.axisZ_ScaleMax, self.inputs.axisZ_ScaleRandomizeAbsolute})
	
	self:EnableDisable(self.inputs.axisZ_ScaleSameAsX, nil, {self.inputs.axisZ_Scale, self.inputs.axisZ_ScaleRandomize, self.inputs.axisZ_ScaleMinLabel, self.inputs.axisZ_ScaleMin, self.inputs.axisZ_ScaleMaxLabel, self.inputs.axisZ_ScaleMax, self.inputs.axisZ_ScaleRandomizeAbsolute})
		
	self:EnableDisable(
		self.inputs.axisZ_ScaleRandomize,
		{self.inputs.axisZ_ScaleMinLabel, self.inputs.axisZ_ScaleMin, self.inputs.axisZ_ScaleMaxLabel, self.inputs.axisZ_ScaleMax, self.inputs.axisZ_ScaleRandomizeAbsolute},
		{self.inputs.axisZ_Scale}
	)

	if msg == self.AXIS_X_TRANSLATION_INVERT then
		self.inputs.axisX_Translation:SetValue(0-self.inputs.axisX_Translation:FloatValue())
	elseif msg == self.AXIS_X_ROTATION_INVERT then
		self.inputs.axisX_Rotation:SetValue(0-self.inputs.axisX_Rotation:FloatValue())
	elseif msg == self.AXIS_Y_TRANSLATION_INVERT then
		self.inputs.axisY_Translation:SetValue(0-self.inputs.axisY_Translation:FloatValue())
	elseif msg == self.AXIS_Y_ROTATION_INVERT then
		self.inputs.axisY_Rotation:SetValue(0-self.inputs.axisY_Rotation:FloatValue())
  	elseif msg == self.AXIS_Z_TRANSLATION_INVERT then
		self.inputs.axisZ_Translation:SetValue(0-self.inputs.axisZ_Translation:FloatValue())		
  	elseif msg == self.AXIS_Z_ROTATION_INVERT then
		self.inputs.axisZ_Rotation:SetValue(0-self.inputs.axisZ_Rotation:FloatValue())
		
	elseif msg == self.GET_LAYER_SIZE_AXIS_X then
		local x = self.layerBounds.fMax.x - self.layerBounds.fMin.x
		self.inputs.axisX_Translation:SetValue(x)
	elseif msg == self.GET_LAYER_SIZE_AXIS_Y then
		local y = self.layerBounds.fMax.y - self.layerBounds.fMin.y
		self.inputs.axisY_Translation:SetValue(y)
	elseif msg == self.GET_LAYER_SIZE_AXIS_Z then
		local z = self.layerBounds.fMax.z - self.layerBounds.fMin.z
		self.inputs.axisZ_Translation:SetValue(z)
		
	elseif msg == self.ROUND_BUTTON_X then
		local n = self.inputs.numberOfCopies:IntValue()
		self.inputs.axisX_Rotation:SetValue(self:Divide360by(n + 1))
	elseif msg == self.ROUND_BUTTON_Y then
		local n = self.inputs.numberOfCopies:IntValue()
		self.inputs.axisY_Rotation:SetValue(self:Divide360by(n + 1))
	elseif msg == self.ROUND_BUTTON_Z then
		local n = self.inputs.numberOfCopies:IntValue()
		self.inputs.axisZ_Rotation:SetValue(self:Divide360by(n + 1))
		
	elseif msg == self.MEASURE_CURVE then
		local curve = self.moho.layer:GetFollowingCurve()
		local curveLength = curve:CurveLength()
		local layerWidth = self.layerBounds.fMax.x - self.layerBounds.fMin.x
		local n = curveLength/layerWidth
		self.inputs.numberOfCopies:SetValue(math.floor(n+0.5))
		
	elseif msg == self.RESET then
		for name, input in pairs(self.inputs) do
			if SZ_LayerCopies[name.."Default"] ~= nil then
				input:SetValue(SZ_LayerCopies[name.."Default"])
			end
		end
		self:HandleMessage(self.GENERIC_MESSAGE)
	
	elseif msg == self.SAVE then
		local fileName = LM.GUI.SaveFile(SZ_LayerCopies:Localize("SaveCaption"))
		if fileName ~= "" then
			local str = ""
			for name, input in pairs(self.inputs) do
				if(input.Value) then
					local val = input:Value()
					str = str .. name .. "=" .. tostring(val) .. "\n"
				end
			end
			local f = io.open(fileName, "w")
			f:write(str)
			f:close()
		end
		
	elseif msg == self.LOAD then
		local fileName = LM.GUI.OpenFile(SZ_LayerCopies:Localize("LoadCaption"))
		if fileName ~= "" then
			local fileLines = io.lines(fileName)
			if fileLines then
				for line in fileLines do
					local name, value = string.match(line, "(.+)=(.+)")
					self.inputs[name]:SetValue(self:ConvertToCorrectDataType(value))
				end
			end
			self:HandleMessage(self.GENERIC_MESSAGE)
		end
	end
end

function SZ_LayerCopiesDialog:ConvertToCorrectDataType(v)
	local n = tonumber(v)
	if n then return n end
	
	if v == "true" then
		return true
	elseif v == "false" then
		return false
	else
		return v
	end		
end

function SZ_LayerCopiesDialog:Divide360by(n)
	return 0 - (2 * math.pi) / (n * 0.0174533)
end

function SZ_LayerCopiesDialog:EnableDisable(checkbox, elementsToEnableOnTrue, elementsToDisableOnTrue)
	if not checkbox:IsEnabled() then
		return false
	end
	
	local b = checkbox:Value()
	if elementsToEnableOnTrue then
		for _, element in ipairs(elementsToEnableOnTrue) do
			element:Enable(b)
		end
	end
	
	if elementsToDisableOnTrue then
		for _, element in ipairs(elementsToDisableOnTrue) do
			element:Enable(not b)
		end
	end
end



function SZ_LayerCopiesDialog:OnValidate()
	local b = true
	
	return b
end

function SZ_LayerCopiesDialog:OnOK()
	SZ_LayerCopies.numberOfCopies = self.inputs.numberOfCopies:IntValue()
	SZ_LayerCopies.asReferences = self.inputs.asReferences:Value()
	SZ_LayerCopies.applyTimingOffset = self.inputs.applyTimingOffset:Value()
	SZ_LayerCopies.timingOffset = self.inputs.timingOffset:IntValue()
	SZ_LayerCopies.timingOffsetRandomize = self.inputs.timingOffsetRandomize:Value()
	SZ_LayerCopies.timingOffsetMin = self.inputs.timingOffsetMin:IntValue()
	SZ_LayerCopies.timingOffsetMax = self.inputs.timingOffsetMax:IntValue()
	SZ_LayerCopies.timingOffsetRandomizeAbsolute = self.inputs.timingOffsetRandomizeAbsolute:Value()
	SZ_LayerCopies.stackBottomToTop = self.inputs.stackBottomToTop:Value()
	SZ_LayerCopies.putInGroup = self.inputs.putInGroup:Value()
	SZ_LayerCopies.makeInvisible = self.inputs.makeInvisible:Value()
	SZ_LayerCopies.distributeAlongCurve = self.inputs.distributeAlongCurve:IsEnabled() and self.inputs.distributeAlongCurve:Value() or false
	SZ_LayerCopies.bendWithCurve = self.inputs.bendWithCurve:IsEnabled() and self.inputs.bendWithCurve:Value() or false
	SZ_LayerCopies.backToBack = self.inputs.bendWithCurve:IsEnabled() and self.inputs.backToBack:Value() or false
	
	-- X AXIS
	SZ_LayerCopies.axisX_ApplyTranslation = self.inputs.axisX_ApplyTranslation:Value()
	SZ_LayerCopies.axisX_Translation = self.inputs.axisX_Translation:FloatValue()
	SZ_LayerCopies.axisX_ApplyLayerSize = self.inputs.axisX_ApplyLayerSize:Value()
	SZ_LayerCopies.axisX_TranslationRandomize = self.inputs.axisX_TranslationRandomize:Value()
	SZ_LayerCopies.axisX_TranslationMin = self.inputs.axisX_TranslationMin:FloatValue()
	SZ_LayerCopies.axisX_TranslationMax = self.inputs.axisX_TranslationMax:FloatValue()
	SZ_LayerCopies.axisX_TranslationRandomizeAbsolute = self.inputs.axisX_TranslationRandomizeAbsolute:Value()
	
	SZ_LayerCopies.axisX_ApplyRotation = self.inputs.axisX_ApplyRotation:Value()
	SZ_LayerCopies.axisX_Rotation = self.inputs.axisX_Rotation:FloatValue()
	SZ_LayerCopies.axisX_RotationRandomize = self.inputs.axisX_RotationRandomize:Value()
	SZ_LayerCopies.axisX_RotationMin = self.inputs.axisX_RotationMin:FloatValue()
	SZ_LayerCopies.axisX_RotationMax = self.inputs.axisX_RotationMax:FloatValue()
	SZ_LayerCopies.axisX_RotationRandomizeAbsolute = self.inputs.axisX_RotationRandomizeAbsolute:Value()
	
	SZ_LayerCopies.axisX_ApplyScale = self.inputs.axisX_ApplyScale:Value()
	SZ_LayerCopies.axisX_Scale = self.inputs.axisX_Scale:FloatValue()
	SZ_LayerCopies.axisX_ScaleRandomize = self.inputs.axisX_ScaleRandomize:Value()
	SZ_LayerCopies.axisX_ScaleMin = self.inputs.axisX_ScaleMin:FloatValue()
	SZ_LayerCopies.axisX_ScaleMax = self.inputs.axisX_ScaleMax:FloatValue()
	SZ_LayerCopies.axisX_ScaleRandomizeAbsolute = self.inputs.axisX_ScaleRandomizeAbsolute:Value()
	
	-- Y AXIS
	SZ_LayerCopies.axisY_ApplyTranslation = self.inputs.axisY_ApplyTranslation:Value()
	SZ_LayerCopies.axisY_Translation = self.inputs.axisY_Translation:FloatValue()
	SZ_LayerCopies.axisY_TranslationRandomize = self.inputs.axisY_TranslationRandomize:Value()
	SZ_LayerCopies.axisY_TranslationMin = self.inputs.axisY_TranslationMin:FloatValue()
	SZ_LayerCopies.axisY_TranslationMax = self.inputs.axisY_TranslationMax:FloatValue()
	SZ_LayerCopies.axisY_TranslationRandomizeAbsolute = self.inputs.axisY_TranslationRandomizeAbsolute:Value()
	
	SZ_LayerCopies.axisY_ApplyRotation = self.inputs.axisY_ApplyRotation:Value()
	SZ_LayerCopies.axisY_Rotation = self.inputs.axisY_Rotation:FloatValue()
	SZ_LayerCopies.axisY_RotationRandomize = self.inputs.axisY_RotationRandomize:Value()
	SZ_LayerCopies.axisY_RotationMin = self.inputs.axisY_RotationMin:FloatValue()
	SZ_LayerCopies.axisY_RotationMax = self.inputs.axisY_RotationMax:FloatValue()
	SZ_LayerCopies.axisY_RotationRandomizeAbsolute = self.inputs.axisY_RotationRandomizeAbsolute:Value()
	
	SZ_LayerCopies.axisY_ApplyScale = self.inputs.axisY_ApplyScale:Value()
	SZ_LayerCopies.axisY_Scale = self.inputs.axisY_Scale:FloatValue()
	SZ_LayerCopies.axisY_ScaleSameAsX = self.inputs.axisY_ScaleSameAsX:Value()
	SZ_LayerCopies.axisY_ScaleRandomize = self.inputs.axisY_ScaleRandomize:Value()
	SZ_LayerCopies.axisY_ScaleMin = self.inputs.axisY_ScaleMin:FloatValue()
	SZ_LayerCopies.axisY_ScaleMax = self.inputs.axisY_ScaleMax:FloatValue()
	SZ_LayerCopies.axisY_ScaleRandomizeAbsolute = self.inputs.axisY_ScaleRandomizeAbsolute:Value()
	
	-- Z AXIS
	SZ_LayerCopies.axisZ_ApplyTranslation = self.inputs.axisZ_ApplyTranslation:Value()
	SZ_LayerCopies.axisZ_Translation = self.inputs.axisZ_Translation:FloatValue()
	SZ_LayerCopies.axisZ_TranslationRandomize = self.inputs.axisZ_TranslationRandomize:Value()
	SZ_LayerCopies.axisZ_TranslationMin = self.inputs.axisZ_TranslationMin:FloatValue()
	SZ_LayerCopies.axisZ_TranslationMax = self.inputs.axisZ_TranslationMax:FloatValue()
	SZ_LayerCopies.axisZ_TranslationRandomizeAbsolute = self.inputs.axisZ_TranslationRandomizeAbsolute:Value()
	
	SZ_LayerCopies.axisZ_ApplyRotation = self.inputs.axisZ_ApplyRotation:Value()
	SZ_LayerCopies.axisZ_Rotation = self.inputs.axisZ_Rotation:FloatValue()
	SZ_LayerCopies.axisZ_RotationRandomize = self.inputs.axisZ_RotationRandomize:Value()
	SZ_LayerCopies.axisZ_RotationMin = self.inputs.axisZ_RotationMin:FloatValue()
	SZ_LayerCopies.axisZ_RotationMax = self.inputs.axisZ_RotationMax:FloatValue()
	SZ_LayerCopies.axisZ_RotationRandomizeAbsolute = self.inputs.axisZ_RotationRandomizeAbsolute:Value()
	
	SZ_LayerCopies.axisZ_ApplyScale = self.inputs.axisZ_ApplyScale:Value()
	SZ_LayerCopies.axisZ_Scale = self.inputs.axisZ_Scale:FloatValue()
	SZ_LayerCopies.axisZ_ScaleSameAsX = self.inputs.axisZ_ScaleSameAsX:Value()
	SZ_LayerCopies.axisZ_ScaleRandomize = self.inputs.axisZ_ScaleRandomize:Value()
	SZ_LayerCopies.axisZ_ScaleMin = self.inputs.axisZ_ScaleMin:FloatValue()
	SZ_LayerCopies.axisZ_ScaleMax = self.inputs.axisZ_ScaleMax:FloatValue()
	SZ_LayerCopies.axisZ_ScaleRandomizeAbsolute = self.inputs.axisZ_ScaleRandomizeAbsolute:Value()

end

-- **************************************************
-- The guts of this script
-- **************************************************

function SZ_LayerCopies:Run(moho)
	local dlog = SZ_LayerCopiesDialog:new(moho)
	if (dlog:DoModal() == LM.GUI.MSG_CANCEL) then
		return
	end
	local layers = self:GetSelectedLayers(moho)
	for _, layer in ipairs(layers) do
		self:RunSilently(moho, layer)
	end
end


function SZ_LayerCopies:RunSilently(moho, layer)
	moho.document:SetDirty()
	moho.document:PrepUndo(nil)
	
	local FLOAT_COEFFICIENT = 10000 -- 4 digits after decimal point for float numbers randomization
	
	local srcLayer = layer
	local srcLayerName = srcLayer:Name()
	
	local doFollow = self.distributeAlongCurve -- this variable will be used in the loop to define if the layer needs to follow curve
	local curve, followingLayer, layerFollowingPercentage
	if doFollow then
		curve = srcLayer:GetFollowingCurve()
		followingLayer = srcLayer:GetFollowingLayer()
		local plusOneIfClosed = curve.fClosed and 1 or 0 -- if the curve is closed, then the source layer will be the first and the last
		layerFollowingPercentage = 100 / (self.numberOfCopies + plusOneIfClosed) / 100
	end
	
	local group = moho:CreateNewLayer(MOHO.LT_GROUP, false)
	group:SetName(self:Localize("CopiesOf") .. srcLayerName)
	local groupLayer = moho:LayerAsGroup(group)
	groupLayer:Expand(false)
	-- put the original into the group
	moho:PlaceLayerInGroup(srcLayer, group, self.stackBottomToTop, false)
	
	if doFollow then
		-- put the followingLayer into the group as well, if applicable
		moho:PlaceLayerInGroup(followingLayer, group, self.stackBottomToTop, false)
		srcLayer:SetFollowingCurve(followingLayer, curve, 0, self.bendWithCurve)
		srcLayer.fFollowing:SetValue(0, 0)
	end
	
	local srcLayerBounds = srcLayer:Bounds(moho.layerFrame)
	
	
	-- variables to store last value:
	local lastTimingOffset = 0
	local axisX_lastTranslation = 0
	local axisX_lastWidth = srcLayerBounds.fMax.x - srcLayerBounds.fMin.x
	local axisY_lastTranslation = 0
	local axisZ_lastTranslation = 0
	
	local axisX_lastRotation = 0
	local axisY_lastRotation = 0
	local axisZ_lastRotation = 0
	
	local axisX_lastScale = 1
	local axisY_lastScale = 1
	local axisZ_lastScale = 1
	
	local lastFollowingTranslation = 0
	local lastFollowingWidth = srcLayerBounds.fMax.x - srcLayerBounds.fMin.x
	
	-- Height compensation variables
	local layerBounds, layerScale, originalHeight, newBounds, newScale, newHeight
		
	-- MAIN LOOP
	for i=1, self.numberOfCopies do
		-- moho:SetSelLayer(srcLayer)
		local newLayer = moho:DuplicateLayer(layer, self.asReferences)
		newLayer:SetName(srcLayerName .. self:Localize("Ref") .. i)
		local pos = newLayer.fTranslation:GetValue(0)
		local scale = newLayer.fScale:GetValue(0)
		
		-- manipulatableLayer will be either the copy itself or the wrapper group layer
		local manipulatableLayer = newLayer
		if self.putInGroup then
			local wrapperGroup = moho:CreateNewLayer(MOHO.LT_GROUP, false)
			wrapperGroup:SetName(srcLayerName .. self:Localize("Ref") .. i)
			moho:PlaceLayerInGroup(newLayer, wrapperGroup, false, false)
			manipulatableLayer = wrapperGroup
		end		
		moho:PlaceLayerInGroup(manipulatableLayer, group, self.stackBottomToTop, false)
				
		-- TIMING OFFSET
		if self.applyTimingOffset then
			local timingOffset = self:IdentifyValue(i, self.timingOffset, self.timingOffsetRandomize, self.timingOffsetMin, self.timingOffsetMax, 1, self.timingOffsetRandomizeAbsolute, lastTimingOffset)
			lastTimingOffset = timingOffset
			manipulatableLayer:SetTimingOffset( 0-timingOffset )
			if self.makeInvisible then
				manipulatableLayer.fVisibility:SetValue(0 - timingOffset, false)
				manipulatableLayer.fVisibility:SetValue(0, false)
				manipulatableLayer.fVisibility:SetValue(1, true)
			end
		end
				
				
		-- ROTATION
		if self.axisX_ApplyRotation or self.axisY_ApplyRotation or self.axisZ_ApplyRotation then
			-- X AXIS
			if self.axisX_ApplyRotation then
				local axisX_Rotation = self:IdentifyValue(i, self.axisX_Rotation, self.axisX_RotationRandomize, self.axisX_RotationMin, self.axisX_RotationMax, 1, self.axisX_RotationRandomizeAbsolute, axisX_lastRotation)
				axisX_lastRotation = axisX_Rotation
				manipulatableLayer.fRotationX:SetValue(0, axisX_Rotation * 0.0174533) -- convert degrees to radians
			end
			
			-- Y AXIS
			if self.axisY_ApplyRotation then
				local axisY_Rotation = self:IdentifyValue(i, self.axisY_Rotation, self.axisY_RotationRandomize, self.axisY_RotationMin, self.axisY_RotationMax, 1, self.axisY_RotationRandomizeAbsolute, axisY_lastRotation)
				axisY_lastRotation = axisY_Rotation
				manipulatableLayer.fRotationY:SetValue(0, axisY_Rotation * 0.0174533) -- convert degrees to radians
			end
			
			-- Z AXIS
			if self.axisZ_ApplyRotation then
				local axisZ_Rotation = self:IdentifyValue(i, self.axisZ_Rotation, self.axisZ_RotationRandomize, self.axisZ_RotationMin, self.axisZ_RotationMax, 1, self.axisZ_RotationRandomizeAbsolute, axisZ_lastRotation)
				axisZ_lastRotation = axisZ_Rotation
				manipulatableLayer.fRotationZ:SetValue(0, axisZ_Rotation * 0.0174533) -- convert degrees to radians
			end
		end
		
		-- SCALE
		if self.axisX_ApplyScale or self.axisY_ApplyScale or self.axisZ_ApplyScale then
			-- X AXIS
			if self.axisX_ApplyScale then
				local axisX_Scale = self:IdentifyValue(i, self.axisX_Scale, self.axisX_ScaleRandomize, self.axisX_ScaleMin, self.axisX_ScaleMax, FLOAT_COEFFICIENT, self.axisX_ScaleRandomizeAbsolute, axisX_lastScale, "scale")
				axisX_lastScale = axisX_Scale
				scale.x = axisX_Scale
			end
			
			-- Y AXIS
			if self.axisY_ApplyScale then					
				if self.axisY_ScaleSameAsX then
					scale.y = scale.x
				else
					local axisY_Scale = self:IdentifyValue(i, self.axisY_Scale, self.axisY_ScaleRandomize, self.axisY_ScaleMin, self.axisY_ScaleMax, FLOAT_COEFFICIENT, self.axisY_ScaleRandomizeAbsolute, axisY_lastScale, "scale")
					axisY_lastScale = axisY_lastScale * axisY_Scale
					scale.y = axisY_Scale
				end
			end
			
			-- Z AXIS
			if self.axisZ_ApplyScale then
				if self.axisZ_ScaleSameAsX then
					scale.z = scale.x
				else
					local axisZ_Scale = self:IdentifyValue(i, self.axisZ_Scale, self.axisZ_ScaleRandomize, self.axisZ_ScaleMin, self.axisZ_ScaleMax, FLOAT_COEFFICIENT, self.axisZ_ScaleRandomizeAbsolute, axisZ_lastScale, "scale")
					axisZ_lastScale = axisZ_lastScale * axisZ_Scale
					scale.z = axisZ_Scale
				end
			end
		
			manipulatableLayer.fScale:SetValue(0, scale)
		end
		
		-- TRANSLATION
		if self.axisX_ApplyTranslation or self.axisY_ApplyTranslation or self.axisZ_ApplyTranslation then
			-- X AXIS
			if self.axisX_ApplyTranslation then
				if self.axisX_ApplyLayerSize then
					local layerBounds = manipulatableLayer:Bounds(0)
					local layerScale = manipulatableLayer.fScale:GetValue(0)
					local width = (layerBounds.fMax.x - layerBounds.fMin.x) * layerScale.x					
					axisX_lastTranslation = axisX_lastTranslation + (width/2) + (axisX_lastWidth/2)
					axisX_lastWidth = width
					pos.x = axisX_lastTranslation
					-- print("width: " .. width .. ", pos: " .. pos.x)
				else
					local axisX_Translation = self:IdentifyValue(i, self.axisX_Translation, self.axisX_TranslationRandomize, self.axisX_TranslationMin, self.axisX_TranslationMax, FLOAT_COEFFICIENT, self.axisX_TranslationRandomizeAbsolute, axisX_lastTranslation)
					axisX_lastTranslation = axisX_Translation
					pos.x = axisX_Translation
				end
			end		
			
			-- Y AXIS
			if self.axisY_ApplyTranslation then
				local axisY_Translation = self:IdentifyValue(i, self.axisY_Translation, self.axisY_TranslationRandomize, self.axisY_TranslationMin, self.axisY_TranslationMax, FLOAT_COEFFICIENT, self.axisY_TranslationRandomizeAbsolute, axisY_lastTranslation)
				axisY_lastTranslation = axisY_Translation
				pos.y = axisY_Translation
			end
			
			-- Z AXIS
			if self.axisZ_ApplyTranslation then
				local axisZ_Translation = self:IdentifyValue(i, self.axisZ_Translation, self.axisZ_TranslationRandomize, self.axisZ_TranslationMin, self.axisZ_TranslationMax, FLOAT_COEFFICIENT, self.axisZ_TranslationRandomizeAbsolute, axisZ_lastTranslation)
				axisZ_lastTranslation = axisZ_Translation
				pos.z = axisZ_Translation
			end
			
			manipulatableLayer.fTranslation:SetValue(0, pos)
		end
		
		-- FOLLOWING
		if doFollow then
			local p
			if self.backToBack then
				local layerBounds = manipulatableLayer:Bounds(0)
				local layerScale = manipulatableLayer.fScale:GetValue(0)
				local width = (layerBounds.fMax.x - layerBounds.fMin.x) * layerScale.x					
				lastFollowingTranslation = lastFollowingTranslation + (width/2) + (lastFollowingWidth/2)
				lastFollowingWidth = width
				p = (lastFollowingTranslation/curve:CurveLength())
			else			
				p = layerFollowingPercentage * i
			end
			manipulatableLayer:SetFollowingCurve(followingLayer, curve, p, self.bendWithCurve)
			manipulatableLayer.fFollowing:SetValue(0, p)
		end
		
		
	end	
	moho:SetSelLayer(groupLayer)
	moho:UpdateUI()
	-- moho.view:DrawMe()
	-- moho.view:RefreshView()
	layer:UpdateCurFrame(true)
end

function SZ_LayerCopies:roundToFourDecimals(num)
    local multiplier = 10^4
    return math.floor(num * multiplier + 0.5) / multiplier
end

function SZ_LayerCopies:GetSelectedLayers(moho)
	local layers = {}
	for i = 0, moho.document:CountSelectedLayers()-1 do
		local layer = moho.document:GetSelectedLayer(i)
		table.insert(layers, layer)
	end
	return layers
end

function SZ_LayerCopies:IdentifyValue(iteration, staticValue, randomize, minValue, maxValue, rndCoefficient, rndAbsolute, prevValue, operation)
	local result
	if operation == "scale" then
		result = iteration * (staticValue - 1) + 1
	else 
		result = staticValue * iteration
	end
	if randomize then
		local rndMin, rndMax = minValue, maxValue
		-- in case if the min value is greater than the max value, let's swap them, since the range of 1-10 is the same as the range of 10-1
		if minValue > maxValue then
			rndMin = maxValue
			rndMax = minValue
		end
		-- Initialize math.random a few times to make sure the randomization is good
		math.random()
		math.random()
		math.random()

		local minValue = math.floor(self:roundToFourDecimals(rndMin) * rndCoefficient)
		local maxValue = math.floor(self:roundToFourDecimals(rndMax) * rndCoefficient)
		local rnd = math.random(minValue, maxValue) / rndCoefficient
		if rndAbsolute then
			result = rnd
		else
			if operation == "scale" then
				result = prevValue + (rnd - 1) + 1
			else
				result = prevValue + rnd
			end
		end
	end	
	return result
end

-- **************************************************
-- Localization
-- **************************************************

function SZ_LayerCopies:Localize(text)
	local fileWord = MOHO.Localize("/Menus/File/File=File")	
	local phrase = {}	
	phrase["Name"] = "Layer Copies"
	phrase["VersionText"] = " - Version "
	phrase["Description"] = "Creates copies of the selected layer"
	phrase["UILabel"] = "Layer Copies"
	phrase["NumberOfCopies"] = "Number of copies to create:"
	phrase["AsReferences"] = "As references"
	phrase["StackBottomToTop"] = "Stack copies bottom to top"
	phrase["MakeInvisible"] = "Make copies invisible before frame 1"
	phrase["PutInGroup"] = "Put each copy in a group layer"
	phrase["DistributeAlongCurve"] = "Distribute copies along the curve"
	phrase["BendWithCurve"] = "Bend along"
	phrase["BackToBack"] = "Back to back"
	phrase["MeasureCurve"] = "Set the number of copies by the curve's length"
	phrase["FollowPathWarning"] = "        (Warning! Don't use layer's translation when using follow path!)"
	phrase["FollowCurveMessage"] = "To use this feature, the layer must follow a curve"
	phrase["TimingOffset"] = "Timeline delay (frames):"
	phrase["AxisX"] = "X Axis:"
	phrase["AxisY"] = "Y Axis:"
	phrase["AxisZ"] = "Z Axis:"
	phrase["Randomize"] = "Randomize"
	phrase["Absolute"] = "Absolute"
	phrase["Min"] = "From:"
	phrase["Max"] = "To:"
	phrase["ApplyTranslation"] = "Translation:"
	phrase["AxisX_GetLayerSize"] = "Get layer's width"
	phrase["AxisY_GetLayerSize"] = "Get layer's height"
	phrase["AxisZ_GetLayerSize"] = "Get layer's depth"
	phrase["AxisX_ApplyLayerSize"] = "Apply individual layer's width every time"
	phrase["ApplyRotation"] = "Rotation (in degrees):"
	phrase["ApplyScale"] = "Scale:"
	phrase["SameAsX"] = "Same as X"
	phrase["CompensateHeight"] = "Compensate height"
	phrase["CopiesOf"] = self.asReferences and "References of " or "Copies of "
	phrase["Ref"] = self.asReferences and " ref " or " copy "
	phrase["Reset"] = "Reset"
	phrase["Save"] = "Save settings"
	phrase["Load"] = "Load settings"
	phrase["SaveCaption"] = "Layer Copies - Save settings"
	phrase["LoadCaption"] = "Layer Copies - Load settings"
	-- phrase["RoundButtonText"] = " ↻ " -- ⟳⥁↻◯⚪⭮????????⭘
	phrase["RoundButtonText"] = " 360°÷ N "
	phrase["RoundButtonDescription"] = "Count how many degrees is needed to perform full turn"
	
	if fileWord == "Файл" then
		phrase["Name"] = "Копии слоя"
		phrase["VersionText"] = " - Версия "
		phrase["Description"] = "Создает копии активного слоя, с расширенными настройками"
		phrase["UILabel"] = "Копии слоя"
		phrase["NumberOfCopies"] = "Сколько копий создать:"
		phrase["AsReferences"] = "Сделать ссылками"
		phrase["StackBottomToTop"] = "Сортировать копии снизу вверх"
		phrase["MakeInvisible"] = "Сделать копии невидимыми до первого кадра"
		phrase["PutInGroup"] = "Поместить каждую копию в групповой слой"
		phrase["DistributeAlongCurve"] = "Распределить копии по кривой"
		phrase["BendWithCurve"] = "Включить изгиб"
		phrase["BackToBack"] = "Укладывать \"плечом к плечу\""
		phrase["MeasureCurve"] = "Установить количество копий по длине кривой"
		phrase["FollowPathWarning"] = "        (Внимание! Не используйте одновременно движение по вектору и перемещение слоя!)"
		phrase["FollowCurveMessage"] = "Эта опция включается когда у слоя есть вектор движения"
		phrase["TimingOffset"] = "Смещение в таймлайне:"
		phrase["AxisX"] = "Ось X:"
		phrase["AxisY"] = "Ось Y:"
		phrase["AxisZ"] = "Ось Z:"
		phrase["Randomize"] = "Случайное"
		phrase["Absolute"] = "Абсолютное"
		phrase["Min"] = "От:"
		phrase["Max"] = "До:"
		phrase["ApplyTranslation"] = "Смещение:"
		phrase["AxisX_GetLayerSize"] = "Взять ширину слоя"
		phrase["AxisY_GetLayerSize"] = "Взять высоту слоя"
		phrase["AxisZ_GetLayerSize"] = "Взять глубину слоя"
		phrase["AxisX_ApplyLayerSize"] = "Применять ширину слоя каждый раз"
		phrase["ApplyRotation"] = "Вращение (в градусах):"
		phrase["ApplyScale"] = "Масштабирование:"
		phrase["SameAsX"] = "Такое же как у оси Х"
		phrase["CompensateHeight"] = "Компенсировать высоту"
		phrase["CopiesOf"] = self.asReferences and "Ссылки слоя " or "Копии слоя "
		phrase["Ref"] = self.asReferences and " ссылка " or " копия "
		phrase["Reset"] = "Сбросить"
		phrase["Save"] = "Сохранить настройки"
		phrase["Load"] = "Загрузить настройки"
		phrase["SaveCaption"] = "Копии слоя - Сохранить настройки"
		phrase["LoadCaption"] = "Копии слоя - Загрузить настройки"
		-- phrase["RoundButtonText"] = " ↻ "
		phrase["RoundButtonText"] = " 360°÷ N "
		phrase["RoundButtonDescription"] = "Посчитать сколько нужно градусов на полный поворот"
	end
	return phrase[text];
end



Icon
Layer Copies
Listed

Author: Stan View Script
Script type: Button/Menu

Uploaded: Jul 13 2020, 09:52

Last modified: Sep 17 2024, 07:45

Script Version: 1.34

Creates a number of copies (or references) for the selected layer. With a lot of additional settings!
Script allows you to create copies/references with timeline shift and distribute them along a curve. It also supports XYZ axes manipulation and randomization of all kinds. Enjoy!

The videos are in Russian but English subtitles are available.






Installation Options:

This script, and all other scripts on this site are distributed as free software under the GNU General Public License 3.0 or later.
Downloads count: 1543