-- Craft Research Timer (CRT) by @aTo (EU)
-- v0.4.11


--sorting functions for grid. Arguments are character names
local function SortAlphaD (a,b)  return a>b
  end

local function SortAlphaA (a,b)  return a<b
end

local function SortTimeA (a,b)
  return CRT.SV.data.Craft[a].shortest < CRT.SV.data.Craft[b].shortest
end

function CRT.Init(eventCode, addOnName)

	if(addOnName == CRT.name) then
		CRT.Init_done = false
		CRT.playername = GetUnitName("player")

	    -- SavedVariables
	    CRT.SV.Settings = ZO_SavedVars:New(CRT.svName, CRT.svVersion*100, nil, CRT.svDefaults, nil)
	    CRT.SV.data = ZO_SavedVars:NewAccountWide(CRT.svName, 1, nil, CRT.data_defaults,nil )

		--get rid of bad "version" key from CRT releases prior to this one
	--	CRT.SV.data.Craft.versionx = nil
	--	CRT.SV.Hireling_data.versionxx = nil

	    -- Slash commands
	    SLASH_COMMANDS[CRT.cmdsetup] = CRT.CommandText_setup

      -- Default sort
      CRT.SortFunction = SortTimeA


	    -- Create Keybinds
	    ZO_CreateStringId("SI_BINDING_NAME_CRT_ToggleUI", "|c96FF00Toggle craft windows|r")
	    ZO_CreateStringId("SI_BINDING_NAME_CRT_toggleGRID", "|c96FF00Toggle GRID|r")

	    -- options panel
	    local LAM = LibStub:GetLibrary("LibAddonMenu-2.0")

	    local panelData = {
	        type = "panel",
	        name = "Craft Research Timer",
	        displayName = "|c96FF00Craft Research Timer|r Settings"
	    }

		local optionsTable = {

	        -- Main settings
	        {
				type = "header",
				name = "|c96FF00Options|r"
	        }, {
	            type = "checkbox",
	            name = "Unlock all windows",
	            tooltip = "Toggle lock on/off",
	            getFunc = function() return CRT.SV.Settings.lock end,
	            setFunc = CRT.SetLock
	        }, {
	            type = "dropdown",
	            name = "Select Mode",
	            tooltip = "Display researched items as icon or text?",
	            choices = {"Icon", "Text"},
	            getFunc = function() return CRT.SV.Settings.mode end,
	            setFunc = CRT.SetMode,
	            warning = "Will need to reload the UI"
	        }, {
	            type = "dropdown",
	            name = "Timer format",
	            tooltip = "How to display remaining time?",
	            choices = {"smart", "fixed", "compact"},
	            getFunc = CRT.Gettimer_format,
	            setFunc = CRT.Settimer_format,
	        }, {
	            type = "button",
	            name = "Reset to default",
	            tooltip = "Load default values",
	            func = CRT.Reset,
	            warning = "Will need to reload the UI"
	        },

	        -- Alert
	        {
	            type = "header",
	            name = "|c96FF00Alert Components|r"
	        }, {
	            type = "checkbox",
				name = "Enable Alert window",
				tooltip = "Enable Alert window",
				getFunc = function() return CRT.SV.Settings.ALERT.hidden end,
				setFunc = CRT.SetAlert
			}, {
				type = "checkbox",
				name = "Preview Alert window",
				tooltip = "Toggle preview on/off",
				getFunc = function() return CRT.SV.Settings.ALERT.preview end,
				setFunc = CRT.SetPreview
			}, {
				type = "colorpicker",
				name = "Text Color",
				tooltip = "Select the text color",
				getFunc = CRT.GetALERTColor,
				setFunc = CRT.SetALERTColor
			}, {
				type = "checkbox",
				name = "Enable Blacksmithing alert",
				tooltip = "Enable Blacksmithing alert",
				getFunc = function() return CRT.SV.Settings.ALERT.BS end,
				setFunc = CRT.SetALERTBS
			}, {
				type = "checkbox",
				name = "Enable Clothing alert",
				tooltip = "Enable Clothing alert",
				getFunc = function() return CRT.SV.Settings.ALERT.CL end,
				setFunc = CRT.SetALERTCL
			}, {
				type = "checkbox",
				name = "Enable Woodworking alert",
				tooltip = "Enable Woodworking alert",
				getFunc = function() return CRT.SV.Settings.ALERT.WO end,
				setFunc = CRT.SetALERTWO
			},

			-- Grid
			{
				type = "header",
				name = "|c96FF00Grid|r"
			}, {
				type = "slider",
				name = "Alpha",
				tooltip = "Change the transparency of the window",
				min = 0,
				max = 100,
				step = 1,
				getFunc = CRT.GetGRIDBackdropAlpha,
				setFunc = CRT.SetGRIDBackdropAlpha
			}, {
				type = "slider",
				name = "Scale",
				tooltip = "Change the scale of the window",
				min = 0,
				max = 200,
				step = 1,
				getFunc = CRT.GetGRIDScale,
				setFunc = CRT.SetGRIDScale
			}, {
				type = "colorpicker",
				name = "Text Color",
				tooltip = "Select the text color",
				getFunc = CRT.GetGRIDColor,
				setFunc = CRT.SetGRIDColor
			}, {
				type = "button",
				name = "Apply new colors",
				tooltip = "Apply new colors",
				func = function() ReloadUI() end, true,
				warning = "Will reload the UI"
			}, {
				type = "button",
				name = "Toggle grid view",
				tooltip = "Display or hide the grid view",
				func = function() CRT.toggleGRID() end, true,
			},

			--Blacksmithing
			{
				type = "header",
				name = "|c96FF00Blacksmithing Components|r"
			}, {
				type = "checkbox",
				name = "Enable Blacksmithing Tracker",
				tooltip = "Enable Blacksmithing Tracker",
				getFunc = function() return CRT.SV.Settings.BS.craft end,
				setFunc = CRT.SetTrackerBS
			}, {
				type = "checkbox",
				name = "Hide if no research",
				tooltip = "Hide if no research",
				getFunc = function() return CRT.SV.Settings.BS.Hide_0 end,
				setFunc = CRT.SetBSHide0
			}, {
				type = "dropdown",
				name = "Display when",
				tooltip = "Display when",
				choices = {"Always", "Hide in menus","Menus only", "Toggle keybind"},
				getFunc = function() return CRT.SV.Settings.BS.Hide_Type end,
				setFunc = CRT.SetBSHideMenu
			}, {
				type = "slider",
				name = "Alpha",
				tooltip = "Change the transparency of the blacksmithing window",
				min = 0,
				max = 100,
				step = 1,
				getFunc = CRT.GetBSBackdropAlpha,
				setFunc = CRT.SetBSBackdropAlpha
			}, {
				type = "slider",
				name = "Scale",
				tooltip = "Change the scale of the blacksmithing window",
				min = 0,
				max = 200,
				step = 1,
				getFunc = CRT.GetBSScale,
				setFunc = CRT.SetBSScale
			},

			--Clothing
			{
				type = "header",
				name = "|c96FF00Clothing Components|r"
			}, {
				type = "checkbox",
				name = "Enable Clothing Tracker",
				tooltip = "Enable Clothing Tracker",
				getFunc = function() return CRT.SV.Settings.CL.craft end,
				setFunc = CRT.SetTrackerCL
			}, {
				type = "checkbox",
				name = "Hide if no research",
				tooltip = "Hide if no research",
				getFunc = function() return CRT.SV.Settings.CL.Hide_0 end,
				setFunc = CRT.SetCLHide0
			}, {
				type = "dropdown",
				name = "Display when",
				tooltip = "Display when",
				choices = {"Always", "Hide in menus","Menus only", "Toggle keybind"},
				getFunc = function() return CRT.SV.Settings.CL.Hide_Type end,
				setFunc = CRT.SetCLHideMenu
			}, {
				type = "slider",
				name = "Alpha",
				tooltip = "Change the transparency of the clothing window",
				min = 0,
				max = 100,
				step = 1,
				getFunc = CRT.GetCLBackdropAlpha,
				setFunc = CRT.SetCLBackdropAlpha
			}, {
				type = "slider",
				name = "Scale",
				tooltip = "Change the scale of the clothing window",
				min = 0,
				max = 200,
				step = 1,
				getFunc = CRT.GetCLScale,
				setFunc = CRT.SetCLScale
			},

			--Woodworking
			{
				type = "header",
				name = "|c96FF00 Woodworking Components|r"
			}, {
				type = "checkbox",
				name = "Enable Woodworking Tracker",
				tooltip = "Enable Woodworking Tracker",
				getFunc = function() return CRT.SV.Settings.WO.craft end,
				setFunc = CRT.SetTrackerWO
			}, {
				type = "checkbox",
				name = "Hide if no research",
				tooltip = "Hide if no research",
				getFunc = function() return CRT.SV.Settings.WO.Hide_0 end,
				setFunc = CRT.SetWOHide0
			}, {
				type = "dropdown",
				name = "Display when",
				tooltip = "Display when",
				choices = {"Always", "Hide in menus","Menus only", "Toggle keybind"},
				getFunc = function() return CRT.SV.Settings.WO.Hide_Type end,
				setFunc = CRT.SetWOHideMenu
			}, {
				type = "slider",
				name = "Alpha",
				tooltip = "Change the transparency of the woodworking window",
				min = 0,
				max = 100,
				step = 1,
				getFunc = CRT.GetWOBackdropAlpha,
				setFunc = CRT.SetWOBackdropAlpha
			}, {
				type = "slider",
				name = "Scale",
				tooltip = "Change the scale of the woodworking window",
				min = 0,
				max = 200,
				step = 1,
				getFunc = CRT.GetWOScale,
				setFunc = CRT.SetWOScale
			}

		}
		LAM:RegisterAddonPanel("CRT_OptionsPanel", panelData);
		LAM:RegisterOptionControls("CRT_OptionsPanel", optionsTable);

		CRT.Start_PlayerPosition = GetMapPlayerPosition("player")
		local timestamp = GetTimeStamp()

		CRT.Alert_Create()

		-- check if old alert before erase data
		--CRT_Alert_Check(playername,timestamp)

		-- erase data for this character
	--	if CRT.SV.data.Craft == nil
	--	then CRT.SV.data.Craft = {}
	--	end
		CRT.SV.data.Craft[CRT.playername] = {}
		CRT.SV.data.Craft[CRT.playername]["Start"] = true

		CRT.Collect_Data()
		-- Create GRID
		CRT.GRID_Create()
		-- Create SOLO CRAFT
		CRT.CRAFT_Create()
		CRT.Init_done = true
		-- Only after initialised do we hook any other events.
		EVENT_MANAGER:RegisterForEvent(CRT.name, EVENT_SMITHING_TRAIT_RESEARCH_STARTED, CRT.Research_started)
	end
end

function CRT.Update()
	if not CRT.Init_done then return; end
	if not BufferReached("Info_Research", CRT.tic)  then return; end
	local timestamp = GetTimeStamp()
	CRT.ALERT_Update(timestamp)
	CRT.GRID_Update(timestamp)
	CRT.CRAFT_Update(timestamp)
	CRT.toggleGUI()
end

local bt= {}
function BufferReached( BufferName, ThrottleInSeconds )
		if not BufferName then return end
		local ct, ThrottleInSeconds = GetGameTimeMilliseconds(), ((ThrottleInSeconds or 3) * 1000)
		--d("start:"..start.. "test "..ThrottleInSeconds )
		if not bt[BufferName] then bt[BufferName] = ct end
		if (ct - bt[BufferName]) >= ThrottleInSeconds
		then bt[BufferName] = ct; return true;
		else return false; end
end

local btwait = {}
function BufferWait(BufferName, WaitTime)
	if (btwait["BufferName"] ~= nil and GetGameTimeMilliseconds() < btwait["BufferName"]) then
		d("false")
		return false
	else
		btwait["BufferName"] = GetGameTimeMilliseconds() + (WaitTime * 1000)
		d("true")
		return true
	end
end

function CRT.ToggleUI()
	if (CRT.SV.Settings.BS.craft == true and CRT.SV.Settings.BS.Hide_Type == "Toggle keybind") then
		if (CRT.UI.CRAFT_TLW[0]:IsHidden() == true) then
			CRT.UI.CRAFT_TLW[0]:SetHidden(false)
		else
			CRT.UI.CRAFT_TLW[0]:SetHidden(true)
		end
	end
	if (CRT.SV.Settings.CL.craft == true and CRT.SV.Settings.CL.Hide_Type == "Toggle keybind") then
			if (CRT.UI.CRAFT_TLW[1]:IsHidden() == true) then
			CRT.UI.CRAFT_TLW[1]:SetHidden(false)
			else
			CRT.UI.CRAFT_TLW[1]:SetHidden(true)
			end
	end
	if (CRT.SV.Settings.WO.craft == true and CRT.SV.Settings.WO.Hide_Type == "Toggle keybind") then
			if (CRT.UI.CRAFT_TLW[2]:IsHidden() == true) then
			CRT.UI.CRAFT_TLW[2]:SetHidden(false)
			else
			CRT.UI.CRAFT_TLW[2]:SetHidden(true)
			end
	end
end

function CRT.toggleGRID()
			if (CRT.UI.GRID_TLW:IsHidden() == true) then
			CRT.UI.GRID_TLW:SetHidden(false)
			CRT.SV.Settings.GRID.hidden = false
			else
			CRT.UI.GRID_TLW:SetHidden(true)
			CRT.SV.Settings.GRID.hidden = true
			end
end

function CRT.toggleGUI()

			local checkUI = ZO_Compass:IsHidden()
			local hidemenu ={}
			hidemenu[0] = CRT.SV.Settings.BS.Hide_Type
			hidemenu[1] = CRT.SV.Settings.CL.Hide_Type
			hidemenu[2] = CRT.SV.Settings.WO.Hide_Type


	for id_craft = 0, 2 , 1 do
		if ((id_craft == 0 and CRT.SV.Settings.BS.craft == true) or (id_craft == 1 and CRT.SV.Settings.CL.craft == true) or (id_craft == 2 and CRT.SV.Settings.WO.craft == true)) then
			if (hidemenu[id_craft] ~= "Toggle keybind") then
				if (hidemenu[id_craft] == "Hide in menus" and checkUI == true)then
					CRT.UI.CRAFT_TLW[id_craft]:SetHidden(true)
				elseif (hidemenu[id_craft] == "Hide in menus" and checkUI == false)then
					CRT.UI.CRAFT_TLW[id_craft]:SetHidden(false)
				elseif (hidemenu[id_craft] == "Menus only" and checkUI == true) then
					CRT.UI.CRAFT_TLW[id_craft]:SetHidden(false)
				elseif (hidemenu[id_craft] == "Menus only" and checkUI == false) then
					CRT.UI.CRAFT_TLW[id_craft]:SetHidden(true)
				elseif (hidemenu[id_craft] == "Always") then
					CRT.UI.CRAFT_TLW[id_craft]:SetHidden(false)
				end
			end
		end

		local hide0 ={}
		hide0[0] = CRT.SV.Settings.BS.Hide_0
		hide0[1] = CRT.SV.Settings.CL.Hide_0
		hide0[2] = CRT.SV.Settings.WO.Hide_0


		if (hide0[id_craft] == true and hidemenu[id_craft] ~= "Toggle keybind" and CRT.SV.data.Craft[CRT.playername][id_craft]["Simu_craft"] == 0) then
			CRT.UI.CRAFT_TLW[id_craft]:SetHidden(true)
		end
	end
end

function CRT.Converthms(timesec)

    local showDays = false
    local showSeconds = false

    local days = 0
    local hours = 0
    local minutes = 0
    local seconds = 0

    local function extractIntegerUnits(sec, unitduration)
        local units = math.floor(sec / unitduration)
        return units, sec - (units * unitduration)
    end

    local format = CRT.SV.Settings.timer_format
    if ((format ~= "fixed") and (format ~= "compact")) then
        format = "smart"
    end

    if (format == "smart") then
        days, timesec = extractIntegerUnits(timesec, 60*60*24)
    end
    hours, timesec = extractIntegerUnits(timesec, 60*60)
    minutes, seconds = extractIntegerUnits(timesec, 60)

    local humanDuration
    if (format == "smart") then
        humanDuration = string.format("%d:%02d", hours, minutes)
        if (days > 0) then
            humanDuration = string.format("%dd ", days)..humanDuration
        end
    else
        humanDuration = string.format("%02d:%02d", hours, minutes)
        if (format == "fixed") then
            humanDuration = humanDuration..(string.format(":%02d", seconds))
        end
    end

    return humanDuration

end


function CRT.Save_position(id_craft)
	if (id_craft == 0) then
		CRT.SV.Settings.BS.offset.X = math.floor(CRT.UI.CRAFT_TLW[id_craft]:GetLeft())
		CRT.SV.Settings.BS.offset.Y = math.floor(CRT.UI.CRAFT_TLW[id_craft]:GetTop())
	elseif (id_craft == 1) then
		CRT.SV.Settings.CL.offset.X = math.floor(CRT.UI.CRAFT_TLW[id_craft]:GetLeft())
		CRT.SV.Settings.CL.offset.Y = math.floor(CRT.UI.CRAFT_TLW[id_craft]:GetTop())
	elseif (id_craft == 2) then
		CRT.SV.Settings.WO.offset.X = math.floor(CRT.UI.CRAFT_TLW[id_craft]:GetLeft())
		CRT.SV.Settings.WO.offset.Y = math.floor(CRT.UI.CRAFT_TLW[id_craft]:GetTop())
	elseif (id_craft == "GRID") then
		CRT.SV.Settings.GRID.offset.X = math.floor(CRT.UI.GRID_TLW:GetLeft())
		CRT.SV.Settings.GRID.offset.Y = math.floor(CRT.UI.GRID_TLW:GetTop())
	elseif (id_craft == "ALERT") then
		CRT.SV.Settings.ALERT.offset.X = math.floor(CRT.UI.ALERT_TLW:GetLeft())
		CRT.SV.Settings.ALERT.offset.Y = math.floor(CRT.UI.ALERT_TLW:GetTop())
	end
end



function CRT.CommandText_setup(lparam)
	if (lparam == "info") then
		d("Craft Research Timer (CRT) by @aTo (EU)")
		d("Version " .. CRT.version)
		d("The CRT have moved to the normal game settings")
		d("Player: " .. CRT.playername)
		d("Shortest: " .. CRT.Converthms(CRT.SV.data.Craft[CRT.playername].shortest))
	elseif (lparam == "grid") then
		CRT.toggleGRID()
	else
		CRT.ToggleUI()
	end
end

EVENT_MANAGER:RegisterForEvent(CRT.name, EVENT_ADD_ON_LOADED, CRT.Init)