--env-m4.lua
if S.trains == nil then S.trains = {} end
if S.d == nil then S.d = {} end
if S.datetime == nil then S.datetime = "" end
if S.stop_display == nil then S.stop_display = false end

F.print = function (str) if F.debug then print("".. (str or "nil") ) end end
F.isempty = function (s) return s == nil or s == "" end
F.get_rc_safe = function() return get_rc() or "" end
F.get_line_safe = function() return get_line() or "" end
F.get_train_length_safe = function() return train_length() or 0 end
F.avg = function(t)
  local sum = 0
  local count = 0
  for k,v in pairs(t) do
    if type(v) == "number" then
      sum = sum + v
      count = count + 1
    end
  end
  return (sum / count)
end

if event.init then
  F.debug = true
  F.printAllTrainsInfo = true
  F.max_displays = 4
  F.print("Initialized")
end

F.does_train_have_rc = function(wanted_rc)
  local rc = F.get_rc_safe()
  if rc:match(wanted_rc) then return true end
end

--old splitter and cpl for demo
function F.cpllooparound(ln)
  if not (event.train) then
    return
  end
	if not (F.get_line_safe() == ln) then return end

	if "ENGINE" == F.get_rc_safe() then
		atc_send("CplS0WRSM")
		set_rc("")
		return
	end

	split_at_index(F.get_train_length_safe()-1,"A0S0") --Stopping the wagons is handled here by SO
	set_rc("ENGINE")
	atc_send("A1")

end

--new ones
function F.split_looparound(ln)
  if not (event.train) then return end
  if not (F.get_line_safe() == ln) then return end

  split_at_index(F.get_train_length_safe()-1,"A0S0OC") --Stopping the wagons is handled here by SO
  set_rc("ENGINE")
  atc_send("A1")

end

function F.split_looparound_left(ln)
  if not (event.train) then return end
  if not (F.get_line_safe() == ln) then return end

  split_at_index(F.get_train_length_safe()-1,"A0S0OL") --Stopping the wagons is handled here by SO
  set_rc("ENGINE")
  atc_send("A1")

end
function F.split_looparound_right(ln)
  if not (event.train) then return end
  if not (F.get_line_safe() == ln) then return end

  split_at_index(F.get_train_length_safe()-1,"A0S0OR") --Stopping the wagons is handled here by SO
  set_rc("ENGINE")
  atc_send("A1")

end

function F.cpl_looparound(ln)
  if not (event.train) then return end
  if not (F.get_line_safe() == ln) then return end

  if "ENGINE" == F.get_rc_safe() then
    atc_send("CplS0WD2RS4")
    set_rc("")
    return
  end

end
--end of new cpl functions

--[[  Utility Functions
]]--
F.indicator = function(indicator,set)
	if set ~= nil then
		if type(set) == string then
			setstate(indicator,set)
		else
			setstate(indicator,(set and "on") or "off")
		end
	end
	return (getstate(indicator) == "on") or false
end

F.get_rc_safe = function()
	return get_rc() or ""
end

F.has_rc = function(query,rc_list) -- query = string, single entry
	if not atc_id then return false end
	if rc_list == "" or query == nil or query=="" then return false end
	if not rc_list then rc_list = F.get_rc_safe() end
	for word in rc_list:gmatch("[^%s]+") do
		if word == query then return true end
	end
	-- print(F.get_rc_safe())
	return false
end

F.has_rc_match = function(query,rc_list) -- query = pattern string, single entry
	if not atc_id then return false end
	if rc_list == "" or query == nil or query=="" then return false end
	if not rc_list then rc_list = F.get_rc_safe() end

	local rc = {}
	for v in rc_list:gmatch("("..query..")") do
		table.insert(rc,v)
	end

	if rc[1] == true then
		return true, rc
	else
		return nil
	end
end

F.add_rc = function(rc_list) -- rc_list = string or table, eg: {"rc1","rc2"} OR "rc1 rc2"
	if not atc_id then return false end
	if type(rc_list) == "table" then
		rc_list = table.concat(rc_list," ")
	end
	set_rc(F.get_rc_safe().." "..rc_list)
	-- print(F.get_rc_safe())
	return true
end

F.remove_rc = function(rc_list,arrow_mode) -- rc_list = string eg: "rc1 rc2 rc3" OR table eg: {"rc1","rc2","rc3"}
	-- Arrow Modes:
	-- true: with arrow direction
	-- false: against arrow direction
	-- nil: ignores arrow direction

	if not atc_id then return false end
	if not rc_list then return false end

	if (arrow_mode == nil) or (atc_arrow == arrow_mode) then
		-- prep rc_list to useable format
		local rc_remove = {}
		if type(rc_list) == "string" then
			for word in rc_list:gmatch("[^%s]+") do
				rc_remove[word] = true
			end
		elseif type(rc_list) == "table" then
			for _,word in pairs(rc_list) do
				rc_remove[word] = true
			end
		end

		-- remove codes from train's rc
		local rc = F.get_rc_safe()
		local reinsert = {}
		for token in rc:gmatch("[^%s]+") do
			if not rc_remove[token] then
				table.insert(reinsert,token)
			end
		end
		-- insert new string to train's rc
		set_rc(table.concat(reinsert," "))
	end
	-- print(F.get_rc_safe())
	return reinsert
end

F.remove_rc_match = function(rc_list) -- rc_list = pattern string, single entry, eg: "rc_%d+"
	if not atc_id then return false end
	if not rc_list then return false end
	local rm = {}
	for v in F.get_rc_safe():gmatch("("..rc_list..")") do
		table.insert(rm,v)
	end
	F.remove_rc(rm)
	-- print(F.get_rc_safe())
	return rm
end

F.yard_road_count = function(yard,section_id,monitoring_light)
	if not S.yards[yard][section_id] then S.yards[yard][section_id] = {['car_count'] = 0} end

	local car_count = S.yards[yard][section_id].car_count

	if event.train then
		if atc_arrow then --arrow points into section, add to length
			car_count = car_count + train_length()
		else -- subtract from
			car_count = car_count - train_length()
		end

		if car_count > 0 then -- light = on
			setstate(monitoring_light,"on")
		else
			car_count = 0
			setstate(monitoring_light,"off")
		end

		S.yards[yard][section_id].car_count = car_count
	end
end