local scriptPath = _G.globalvariables['script_path']
package.path	= package.path .. ';' .. scriptPath .. '?.lua'
local TIMED_OPTIONS = require('TimedCommandOptions')

local utils = require('Utils')

local function TimedCommand(domoticz, commandName, value, mode, currentState, currentLevel)

	if (type(mode) == 'string') then
		mode = TIMED_OPTIONS[mode]
	end

	math.randomseed(os.time())
	-- mode can be 'device', 'updatedevice' or 'variable'

	local valueValue = value
	local atValue, afterValue, forValue, randomValue, silentValue, repeatValue, repeatIntervalValue, checkValue
	local _for, _after, _within, _rpt, _silent, _repeatAfter, _at

	local constructCommand = function()

		local command = {} -- array of command parts

		if checkValue and ( tostring(currentState):find(valueValue) or ( currentLevel and currentState == currentLevel )) then
			return nil
		end

		table.insert(command, valueValue)

		if (randomValue ~= nil) then
			table.insert(command, 'RANDOM ' .. tostring(randomValue) .. ' SECONDS')
		end

		if (afterValue ~= nil) then
			table.insert(command, 'AFTER ' .. tostring(afterValue) .. ' SECONDS')
		end

		if (forValue ~= nil) then
			table.insert(command, 'FOR ' .. tostring(forValue) .. ' SECONDS')
		end

		if (mode._triggerMode == 'TRIGGER') then
			if (not silentValue == true) then
				table.insert(command, 'TRIGGER')
			end
		else
			if (silentValue == true) then
				table.insert(command, 'NOTRIGGER')
			end
		end

		if (repeatValue ~= nil) then
			table.insert(command, 'REPEAT ' .. tostring(repeatValue))
		end

		if (repeatIntervalValue ~= nil) then
			table.insert(command, 'INTERVAL ' .. tostring(repeatIntervalValue) .. ' SECONDS')
		end

		local sCommand = table.concat(command, " ")

		utils.log('Constructed timed-command: ' .. sCommand, utils.LOG_DEBUG)

		return sCommand
	end

	local constructCommandForTable = function()

		if (randomValue ~= nil) then
			-- value._after = tostring(math.random(randomValue))
			value._random = randomValue
		end

		if (afterValue ~= nil) then
			value._after = afterValue
		end

		if (forValue ~= nil) then
			value._for = forValue
		end

		if (silentValue == true) then
			value._trigger = nil
		-- else
		-- 	value._trigger = true
		end

		if (repeatValue ~= nil) then
			value._repeat = repeatValue
		end

		if (repeatIntervalValue ~= nil) then
			value._repeatInterval = repeatIntervalValue
		end

		return value
	end

	local latest, command, sValue

	-- get a reference to the latest entry in the commandArray so we can
	-- keep modifying it here.
	if (type(value) == 'table') then
		latest, command, sValue = domoticz.sendCommand(commandName, value)
	else
		latest, command, sValue = domoticz.sendCommand(commandName, constructCommand())
	end

	local function factory()

		local res = {}

		if (mode._for == true and forValue == nil) then
			res.forSec = _for(1)
			res.forMin = _for(60)
			res.forHour = _for(3600)
		end

		if (mode._repeat == true and repeatIntervalValue == nil) then
			res.repeatAfterSec = _repeatAfter(1)
			res.repeatAfterMin = _repeatAfter(60)
			res.repeatAfterHour = _repeatAfter(3600)
		end

		if (mode._checkState and checkValue == nil and currentState ~= nil) then
			res.checkFirst = _checkState
		end

		if (afterValue == nil and randomValue == nil) then
			if (mode._after == true) then
				res.afterSec = _after(1)
				res.afterMin = _after(60)
				res.afterHour = _after(3600)
			end

			if (mode._within == true) then
				res.withinSec = _within(1)
				res.withinMin = _within(60)
				res.withinHour = _within(3600)
			end
		
			if (mode._at == true) then
				res.at = _after(1)
				res.afterSec = _after(1)
				res.afterMin = _after(60)
				res.afterHour = _after(3600)
			end
		end

		if (mode._silent == true and silentValue == nil) then
			res.silent = _silent
		end

		res._latest = latest

		return res
	end

	local function updateCommand()
		if (type(value) == 'table') then
			latest[command] = constructCommandForTable()
		else
			latest[command] = constructCommand()
		end
	end

	_checkValue = function(value, msg)
		if (value == nil) then utils.log(msg, utils.LOG_ERROR) end
	end

	_after = function(factor)
		return function(value)
			_checkValue(value, "No value given for 'afterXXX' command")
			if tonumber(value) == nil then value = utils.stringToSeconds(value) end -- No number so called by 'at()' 
			afterValue = value * ( factor or 1 )
			updateCommand()
			return factory()
		end
	end

	_at = function(str)
		return function(str)
			_checkValue(str, "No value given for 'at' command")
			afterValue =  str

			updateCommand()

			return factory()
		end
	end

	_within = function(factor)
		return function(value)
			_checkValue(value, "No value given for 'withinXXX' command")
			randomValue = value * factor

			updateCommand()

			return factory()
		end
	end

	_for = function(factor)
		return function(value)
			_checkValue(value, "No value given for 'forXXX' command")
			forValue = value * factor
			updateCommand()
			return factory()
		end
	end

	_silent = function()
		silentValue = true;
		updateCommand()
		return factory()
	end

	_repeatAfter = function(factor)
		_checkValue(value, "No value given for 'repeatAfterXXX' command")
		return function(value, amount)

			if (amount == nil) then
				amount = 1
			end

			repeatIntervalValue = value * factor
			repeatValue = amount + 1 -- add one due to a bug in domoticz

			updateCommand()
			return factory()
		end
	end

	_checkState = function()
		checkValue = true;
		updateCommand()
		return factory()
	end

	return factory()

end

return TimedCommand
