EarTagColourPickerDialog = {}

local earTagColourPickerDialog_mt = Class(EarTagColourPickerDialog, MessageDialog)
local modDirectory = g_currentModDirectory

EarTagColourPickerDialog.INPUT_THRESHOLD = 0.01
EarTagColourPickerDialog.INPUT_SCALE = 10000
EarTagColourPickerDialog.DOUBLE_CLICK_INTERVAL = 400


function EarTagColourPickerDialog.register()

    local dialog = EarTagColourPickerDialog.new()
    g_gui:loadGui(modDirectory .. "gui/EarTagColourPickerDialog.xml", "EarTagColourPickerDialog", dialog)
    EarTagColourPickerDialog.INSTANCE = dialog

end


function EarTagColourPickerDialog.show()

    if EarTagColourPickerDialog.INSTANCE ~= nil then
        local dialog = EarTagColourPickerDialog.INSTANCE
        g_gui:showDialog("EarTagColourPickerDialog")
    end

end


function EarTagColourPickerDialog.new(target, customMt)

    local self = MessageDialog.new(target, customMt or earTagColourPickerDialog_mt)

    self.animalTypes = g_currentMission.animalSystem:getTypes()
    self.texts = {
        ["earTagLeft"] = {},
        ["earTagRight"] = {}
    }

    return self

end


function EarTagColourPickerDialog.createFromExistingGui(gui, _)

    EarTagColourPickerDialog.register()
    EarTagColourPickerDialog.show()

end


function EarTagColourPickerDialog:onGuiSetupFinished()

    EarTagColourPickerDialog:superClass().onGuiSetupFinished(self)

    local typeTexts = {}

    for _, type in pairs(self.animalTypes) do

        table.insert(typeTexts, type.name)

    end

    self.animalTypePicker:setTexts(typeTexts)

    local rgbTexts = {}
    local hsvTexts = {}

	for i = 0, 360 do

        table.insert(hsvTexts, tostring(i))

        if i <= 255 then table.insert(rgbTexts, tostring(i)) end

    end
    
	self.hueSliderBase:setTexts(hsvTexts)
	self.hueSliderText:setTexts(hsvTexts)
    self.baseRgbRed:setTexts(rgbTexts)
	self.baseRgbGreen:setTexts(rgbTexts)
	self.baseRgbBlue:setTexts(rgbTexts)
    self.textRgbRed:setTexts(rgbTexts)
	self.textRgbGreen:setTexts(rgbTexts)
	self.textRgbBlue:setTexts(rgbTexts)

end


function EarTagColourPickerDialog:onOpen()

    EarTagColourPickerDialog:superClass().onOpen(self)
	
    self.customPickerUpDownEventId = g_inputBinding:registerActionEvent(InputAction.AXIS_PICK_COLOR_UPDOWN, self, self.onVerticalCursorInput, false, false, true, true)
	self.customPickerLeftRightEventId = g_inputBinding:registerActionEvent(InputAction.AXIS_PICK_COLOR_LEFTRIGHT, self, self.onHorizontalCursorInput, false, false, true, true)
    
    self.accumHorizontalInput, self.accumVerticalInput = 0, 0

	self.colorRender:createScene()

    self.animalTypePicker:setState(1)

    self.context = "earTagLeft"
    self:setColourFromType(1)

end


function EarTagColourPickerDialog:onClose()

    EarTagColourPickerDialog:superClass().onClose(self)

	g_inputBinding:removeActionEventsByTarget(self)
    
	self.colorRender:destroyScene()
    self.renderNode = nil

end


function EarTagColourPickerDialog:onAnimalTypeChanged()

    local index = self.animalTypePicker:getState()

    self:setColourFromType(index)

end


function EarTagColourPickerDialog:setColourFromType(index)

    local baseColour = self.animalTypes[index].colours[self.context]
    local textColour = self.animalTypes[index].colours[self.context .. "_text"]

    self.baseRgbRed:setState(math.floor(baseColour[1] * 255) + 1)
    self.baseRgbGreen:setState(math.floor(baseColour[2] * 255) + 1)
    self.baseRgbBlue:setState(math.floor(baseColour[3] * 255) + 1)

    self.textRgbRed:setState(math.floor(textColour[1] * 255) + 1)
    self.textRgbGreen:setState(math.floor(textColour[2] * 255) + 1)
    self.textRgbBlue:setState(math.floor(textColour[3] * 255) + 1)

    self:onBaseRGBChanged()
    self:onTextRGBChanged()

end


function EarTagColourPickerDialog:onBaseRGBChanged()

    local baseR = (self.baseRgbRed:getState() - 1) / 255
    local baseG = (self.baseRgbGreen:getState() - 1) / 255
    local baseB = (self.baseRgbBlue:getState() - 1) / 255

	local hsvR, hsvG, hsvB = GuiUtils.rgbToHSV(baseR, baseG, baseB)
	local r, g, b = GuiUtils.hsvToRGB(hsvR)

	self.customPickerBase:setImageColor(nil, math.pow(r, 2.2), math.pow(g, 2.2), math.pow(b, 2.2), 1)
	self.hueSliderBase:setState(math.floor(hsvR * 360) + 1)

	self.baseCursor:setAbsolutePosition(self.customPickerBase.absPosition[1] + self.customPickerBase.absSize[1] * hsvG - self.baseCursor.absSize[1] * 0.5, self.customPickerBase.absPosition[2] + self.customPickerBase.absSize[2] * hsvB - self.baseCursor.absSize[2] * 0.5)

    self:setCustomColorHSVBase(math.floor(hsvR * 360), hsvG, hsvB)

    self.pendingRenderUpdate = true

end


function EarTagColourPickerDialog:onTextRGBChanged()

    local textR = (self.textRgbRed:getState() - 1) / 255
    local textG = (self.textRgbGreen:getState() - 1) / 255
    local textB = (self.textRgbBlue:getState() - 1) / 255

	local hsvR, hsvG, hsvB = GuiUtils.rgbToHSV(textR, textG, textB)
	local r, g, b = GuiUtils.hsvToRGB(hsvR)

	self.customPickerText:setImageColor(nil, math.pow(r, 2.2), math.pow(g, 2.2), math.pow(b, 2.2), 1)
	self.hueSliderText:setState(math.floor(hsvR * 360) + 1)

	self.textCursor:setAbsolutePosition(self.customPickerText.absPosition[1] + self.customPickerText.absSize[1] * hsvG - self.textCursor.absSize[1] * 0.5, self.customPickerText.absPosition[2] + self.customPickerText.absSize[2] * hsvB - self.textCursor.absSize[2] * 0.5)

    self:setCustomColorHSVText(math.floor(hsvR * 360), hsvG, hsvB)

    self.pendingRenderUpdate = true

end


function EarTagColourPickerDialog:onBaseHueChanged(index)

	local hsvR, hsvG, hsvB = GuiUtils.hsvToRGB((index - 1) / 360)

	local r = math.pow(hsvR, 2.2)
	local g = math.pow(hsvG, 2.2)
	local b = math.pow(hsvB, 2.2)

	self.customPickerBase:setImageColor(nil, r, g, b, 1)
	
    self.baseRgbRed:setState(math.floor(r * 255) + 1)
    self.baseRgbGreen:setState(math.floor(g * 255) + 1)
    self.baseRgbBlue:setState(math.floor(b * 255) + 1)

    self:setCustomColorHSVBase(index - 1)

    self.pendingRenderUpdate = true

end


function EarTagColourPickerDialog:onTextHueChanged(index)

	local hsvR, hsvG, hsvB = GuiUtils.hsvToRGB((index - 1) / 360)

	local r = math.pow(hsvR, 2.2)
	local g = math.pow(hsvG, 2.2)
	local b = math.pow(hsvB, 2.2)

	self.customPickerText:setImageColor(nil, r, g, b, 1)
	
    self.textRgbRed:setState(math.floor(r * 255) + 1)
    self.textRgbGreen:setState(math.floor(g * 255) + 1)
    self.textRgbBlue:setState(math.floor(b * 255) + 1)

    self:setCustomColorHSVText(index - 1)

    self.pendingRenderUpdate = true

end


function EarTagColourPickerDialog:setCustomColorHSVBase(index, hsvG, hsvB)

    if hsvG ~= nil and hsvB ~= nil then
		self.baseCursor:setAbsolutePosition(self.customPickerBase.absPosition[1] + self.customPickerBase.absSize[1] * hsvG - self.baseCursor.absSize[1] * 0.5, self.customPickerBase.absPosition[2] + self.customPickerBase.absSize[2] * hsvB - self.baseCursor.absSize[2] * 0.5)
	end

	if not hsvG then
		local sG = (self.baseCursor.absPosition[1] + self.baseCursor.absSize[1] * 0.5 - self.customPickerBase.absPosition[1]) / self.customPickerBase.absSize[1]
		hsvG = math.clamp(sG, 0, 1)
	end

	if not hsvB then
		local sB = (self.baseCursor.absPosition[2] + self.baseCursor.absSize[2] * 0.5 - self.customPickerBase.absPosition[2]) / self.customPickerBase.absSize[2]
		hsvB = math.clamp(sB, 0, 1)
	end

    local r, g, b = GuiUtils.hsvToRGB(index / 360, hsvG, hsvB)

    self.baseRgbRed:setState(math.floor(r * 255) + 1)
    self.baseRgbGreen:setState(math.floor(g * 255) + 1)
    self.baseRgbBlue:setState(math.floor(b * 255) + 1)

    self.pendingRenderUpdate = true

end


function EarTagColourPickerDialog:setCustomColorHSVText(index, hsvG, hsvB)

    if hsvG ~= nil and hsvB ~= nil then
		self.textCursor:setAbsolutePosition(self.customPickerText.absPosition[1] + self.customPickerText.absSize[1] * hsvG - self.textCursor.absSize[1] * 0.5, self.customPickerText.absPosition[2] + self.customPickerText.absSize[2] * hsvB - self.textCursor.absSize[2] * 0.5)
	end

	if not hsvG then
		local sG = (self.textCursor.absPosition[1] + self.textCursor.absSize[1] * 0.5 - self.customPickerText.absPosition[1]) / self.customPickerText.absSize[1]
		hsvG = math.clamp(sG, 0, 1)
	end

	if not hsvB then
		local sB = (self.textCursor.absPosition[2] + self.textCursor.absSize[2] * 0.5 - self.customPickerText.absPosition[2]) / self.customPickerText.absSize[2]
		hsvB = math.clamp(sB, 0, 1)
	end

    local r, g, b = GuiUtils.hsvToRGB(index / 360, hsvG, hsvB)

    self.textRgbRed:setState(math.floor(r * 255) + 1)
    self.textRgbGreen:setState(math.floor(g * 255) + 1)
    self.textRgbBlue:setState(math.floor(b * 255) + 1)

    self.pendingRenderUpdate = true

end


function EarTagColourPickerDialog:onClickOk()

    local typeIndex = self.animalTypePicker:getState()

    local baseR = (self.baseRgbRed:getState() - 1) / 255
    local baseG = (self.baseRgbGreen:getState() - 1) / 255
    local baseB = (self.baseRgbBlue:getState() - 1) / 255

    local textR = (self.textRgbRed:getState() - 1) / 255
    local textG = (self.textRgbGreen:getState() - 1) / 255
    local textB = (self.textRgbBlue:getState() - 1) / 255

    local type = g_currentMission.animalSystem.types[typeIndex]
    type.colours[self.context] = { baseR, baseG, baseB }
    type.colours[self.context .. "_text"] = { textR, textG, textB }


    local leftTag, leftText, rightTag, rightText

    if self.context == "earTagLeft" then leftTag, leftText = { baseR, baseG, baseB }, { textR, textG, textB } end
    if self.context == "earTagRight" then rightTag, rightText = { baseR, baseG, baseB }, { textR, textG, textB } end


    for _, placeable in pairs(g_currentMission.husbandrySystem.placeables) do

        if placeable:getAnimalTypeIndex() ~= typeIndex then continue end

        local animals = placeable:getClusters()

        for _, animal in pairs(animals) do animal:setVisualEarTagColours(leftTag, leftText, rightTag, rightText) end

    end

end


function EarTagColourPickerDialog:onClickEarTagLeft()

    self.context = "earTagLeft"
    self.animalTypePicker:setState(1)
    self:setColourFromType(1)

    for _, node in pairs(self.texts.earTagLeft) do setVisibility(node, true) end
    for _, node in pairs(self.texts.earTagRight) do setVisibility(node, false) end

end


function EarTagColourPickerDialog:onClickEarTagRight()

    self.context = "earTagRight"
    self.animalTypePicker:setState(1)
    self:setColourFromType(1)

    for _, node in pairs(self.texts.earTagLeft) do setVisibility(node, false) end
    for _, node in pairs(self.texts.earTagRight) do setVisibility(node, true) end

end


function EarTagColourPickerDialog:update(dT)

    EarTagColourPickerDialog:superClass().update(self, dT)

    if self.pendingRenderUpdate and self.colorRender.scene ~= nil then

        local baseR = (self.baseRgbRed:getState() - 1) / 255
        local baseG = (self.baseRgbGreen:getState() - 1) / 255
        local baseB = (self.baseRgbBlue:getState() - 1) / 255

        local textR = (self.textRgbRed:getState() - 1) / 255
        local textG = (self.textRgbGreen:getState() - 1) / 255
        local textB = (self.textRgbBlue:getState() - 1) / 255

        if self.renderNode == nil then self:setupScene() end

        setShaderParameter(self.renderNode, "colorScale", baseR, baseG, baseB)

        for _, node in pairs(self.texts[self.context]) do RealisticLivestock.change3DLinkedTextColour(node, textR, textG, textB, 1) end

        self.colorRender:setRenderDirty()
        self.pendingRenderUpdate = false

    end

end


function EarTagColourPickerDialog:setupScene()

    self.renderNode = getChildAt(getChildAt(self.colorRender.scene, 0), 0)

    local node = getChild(self.renderNode, "front")

    local uniqueId, farmId, countryCode, name, birthday = "405070", "109824", "UK", "Little Megan", "05/11/22"

	RealisticLivestock.set3DTextAutoScale(true)
	RealisticLivestock.set3DTextRemoveSpaces(true)
	RealisticLivestock.setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_MIDDLE)
	RealisticLivestock.setTextAlignment(RenderText.ALIGN_CENTER)
	RealisticLivestock.setTextColor(0, 0, 0, 1)
	RealisticLivestock.setTextFont(RealisticLivestock.FONTS.dejavu_sans)

    self.texts.earTagLeft = {
		["uniqueId"] = RealisticLivestock.create3DLinkedText(node, 0, -0.006, -0.015, 0, 0, 0, 0.035, uniqueId),
		["farmId"] = RealisticLivestock.create3DLinkedText(node, 0, -0.041, -0.02, 0, 0, 0, 0.05, farmId),
		["country"] = RealisticLivestock.create3DLinkedText(node, 0, 0.021, -0.015, 0, 0, 0, 0.03, countryCode)
	}

    self.texts.earTagRight = {
        ["birthday"] = RealisticLivestock.create3DLinkedText(node, 0, 0.018, -0.015, 0, 0, 0, 0.02, birthday)
	}

	RealisticLivestock.setTextFont(RealisticLivestock.FONTS.toms_handwritten)
	RealisticLivestock.set3DTextWrapWidth(0.14)
	RealisticLivestock.set3DTextWordsPerLine(1)
	RealisticLivestock.setTextLineHeightScale(0.75)
	
	self.texts.earTagRight.name = RealisticLivestock.create3DLinkedText(node, 0, -0.01, -0.015, 0, 0, 0, 0.035, name)

	RealisticLivestock.setTextLineHeightScale(1.1)
	RealisticLivestock.set3DTextWordsPerLine(0)
	RealisticLivestock.set3DTextAutoScale(false)
	RealisticLivestock.set3DTextRemoveSpaces(false)
	RealisticLivestock.setTextVerticalAlignment(RenderText.VERTICAL_ALIGN_BASELINE)
	RealisticLivestock.setTextAlignment(RenderText.ALIGN_LEFT)
	RealisticLivestock.setTextColor(1, 1, 1, 1)
	RealisticLivestock.set3DTextWrapWidth(0)
	RealisticLivestock.setTextFont()

    setVisibility(self.texts.earTagRight.birthday, false)
    setVisibility(self.texts.earTagRight.name, false)

end


function EarTagColourPickerDialog:mouseEvent(pixelX, pixelY, isDown, isUp)

	local pixelsX = 20 * g_pixelSizeX
	local pixelsY = 20 * g_pixelSizeY

	if GuiUtils.checkOverlayOverlap(pixelX, pixelY, self.customPickerBase.absPosition[1] - pixelsX, self.customPickerBase.absPosition[2] - pixelsY, self.customPickerBase.absSize[1] + pixelsX * 2, self.customPickerBase.absSize[2] + pixelsY * 2) and self.customPickerBase:getIsVisible() then

		if isDown then
			self.inputDown = true
		end

		if self.inputDown then

			local positionX = math.clamp(pixelX, self.customPickerBase.absPosition[1], self.customPickerBase.absPosition[1] + self.customPickerBase.absSize[1])
			local positionY = math.clamp(pixelY, self.customPickerBase.absPosition[2], self.customPickerBase.absPosition[2] + self.customPickerBase.absSize[2])

			self.baseCursor:setAbsolutePosition(positionX - self.baseCursor.absSize[1] * 0.5, positionY - self.baseCursor.absSize[2] * 0.5)
			self:setCustomColorHSVBase(self.hueSliderBase:getState() - 1)

		end
	end

	if GuiUtils.checkOverlayOverlap(pixelX, pixelY, self.customPickerText.absPosition[1] - pixelsX, self.customPickerText.absPosition[2] - pixelsY, self.customPickerText.absSize[1] + pixelsX * 2, self.customPickerText.absSize[2] + pixelsY * 2) and self.customPickerText:getIsVisible() then

		if isDown then
			self.inputDown = true
		end

		if self.inputDown then

			local positionX = math.clamp(pixelX, self.customPickerText.absPosition[1], self.customPickerText.absPosition[1] + self.customPickerText.absSize[1])
			local positionY = math.clamp(pixelY, self.customPickerText.absPosition[2], self.customPickerText.absPosition[2] + self.customPickerText.absSize[2])

			self.textCursor:setAbsolutePosition(positionX - self.textCursor.absSize[1] * 0.5, positionY - self.textCursor.absSize[2] * 0.5)
			self:setCustomColorHSVText(self.hueSliderText:getState() - 1)

		end
	end

	if isUp then
		self.inputDown = false
	end

end


function EarTagColourPickerDialog:onHorizontalCursorInput(_, amount)
	self.accumHorizontalInput = self.accumHorizontalInput + amount
end


function EarTagColourPickerDialog:onVerticalCursorInput(_, amount)
	self.accumVerticalInput = self.accumVerticalInput + amount
end