--- Provides a logging of statistics in a running DCS Mission.
-- @script eStatHandler

Include.File( "Routines" )


--Handler table
local eStatHandler = {}
local _StatRunID

--Neccessary tables for string instead of integers
SETCoalition = 
{
	[1] = "red",
	[2] = "blue",
}

SETGroupCat = 
{
	[1] = "AIRPLANE",
	[2] = "HELICOPTER",
	[3] = "GROUND",
	[4] = "SHIP",
	[5] = "STRUCTURE",
}

SETWeaponCatName = 
{
   [0] = "SHELL",
   [1] = "MISSILE",
   [2] = "ROCKET",
   [3] = "BOMB",
 }
 
 wEvent = {
   "S_EVENT_SHOT",
   "S_EVENT_HIT",
   "S_EVENT_TAKEOFF",
   "S_EVENT_LAND",
   "S_EVENT_CRASH",
   "S_EVENT_EJECTION",
   "S_EVENT_REFUELING",
   "S_EVENT_DEAD",
   "S_EVENT_PILOT_DEAD",
   "S_EVENT_BASE_CAPTURED",
   "S_EVENT_MISSION_START",
   "S_EVENT_MISSION_END",
   "S_EVENT_TOOK_CONTROL",
   "S_EVENT_REFUELING_STOP",
   "S_EVENT_BIRTH",
   "S_EVENT_HUMAN_FAILURE",
   "S_EVENT_ENGINE_STARTUP",
   "S_EVENT_ENGINE_SHUTDOWN",
   "S_EVENT_PLAYER_ENTER_UNIT",
   "S_EVENT_PLAYER_LEAVE_UNIT",
   "S_EVENT_PLAYER_COMMENT",
   "S_EVENT_SHOOTING_START",
   "S_EVENT_SHOOTING_END",
   "S_EVENT_MAX",
 }
 
statEventsTable = {}


function SecondsToClock(sSeconds)
local nSeconds = sSeconds
	if nSeconds == 0 then
		--return nil;
		return "00:00:00";
	else
		nHours = string.format("%02.f", math.floor(nSeconds/3600));
		nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60)));
		nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60));
		return nHours..":"..nMins..":"..nSecs
	end
end


function eStatHandler:onEvent(e)
    local InitID_ = ""
	local InitName = ""
    local WorldEvent = wEvent[e.id]
    local InitCoa = ""
    local InitGroupCat = ""
    local InitType = ""
    local InitPlayer = ""
    local eWeaponCat = ""
    local eWeaponName = ""
    local TargID_ = ""
	local TargName = ""
    local TargType = ""
    local TargPlayer = ""
    local TargCoa = ""
    local TargGroupCat = ""

	if e.initiator and Object.getCategory(e.initiator) == Object.Category.UNIT then
	--Initiator variables
		local InitGroup = e.initiator:getGroup()
		InitID_ = e.initiator.id_
		if e.initiator:getName() then
			InitName = e.initiator:getName()
		end
		if InitGroup:getCoalition() then
			InitCoa = SETCoalition[InitGroup:getCoalition()]
		end
		if InitGroup:getCategory() then
			InitGroupCat = SETGroupCat[InitGroup:getCategory() + 1]
		end
        InitType = e.initiator:getTypeName()
		
		--Get initiator player name or AI if NIL
		if e.initiator:getPlayerName() == nil then
			InitPlayer = "AI"
		else
			InitPlayer = e.initiator:getPlayerName()
		end
	else
		if e.initiator then
			local InitGroup = e.initiator:getGroup()
			InitID_ = e.initiator.id_
			if e.initiator:getName() then
				InitName = e.initiator:getName()
			end
			InitCoa = SETCoalition[InitGroup:getCoalition()]
			InitGroupCat = SETGroupCat[InitGroup:getCategory() + 1]
			InitType = e.initiator:getTypeName()
			
			--Get initiator player name or AI if NIL
			if e.initiator:getPlayerName() == nil then
				InitPlayer = "AI"
			else
				InitPlayer = e.initiator:getPlayerName()
			end
		end
    end

	--Weapon variables	
	if e.weapon == nil then
		eWeaponCat = ""
		eWeaponName = ""
	else
		local eWeaponDesc = e.weapon:getDesc()
		eWeaponCat = SETWeaponCatName[eWeaponDesc.category]
		eWeaponName = eWeaponDesc.displayName
	end
	
	--Target variables	
	if e.target == nil then
	    TargID_ = ""
		TargName = ""
		TargType = ""
		TargPlayer = ""
		TargCoa = ""
        TargGroupCat = ""
	elseif Object.getCategory(e.target) == Object.Category.UNIT then
	    local TargGroup = e.target:getGroup()
	    TargID_ = e.target.id_
		if e.target:getName() then
			TargName = e.target:getName()
		end
		TargType = e.target:getTypeName()
		TargCoa = SETCoalition[TargGroup:getCoalition()]
		TargGroupCat = SETGroupCat[TargGroup:getCategory() + 1]
		
		--Get target player name or AI if NIL
		if not e.target:getPlayerName() then
			TargPlayer = "AI"
		else
			TargPlayer = e.target:getPlayerName()
		end
	else
		TargType = e.target:getTypeName()
		TargID_ = ""
		TargName = ""
		TargPlayer = ""
		TargCoa = ""
        TargGroupCat = ""
	end
	
	--write events to table
	statEventsTable[#statEventsTable + 1] = 
			{
				[1] = _StatRunID,
				[2] = SecondsToClock(timer.getTime()),
				[3] = WorldEvent,
				[4] = InitID_,
				[5] = InitName,
				[6] = InitCoa,
				[7] = InitGroupCat,
				[8] = InitType,
				[9] = InitPlayer,
				[10] = eWeaponCat,
				[11] = eWeaponName,
				[12] = TargID_,
				[13] = TargName,
				[14] = TargCoa,
				[15] = TargGroupCat,
				[16] = TargType,
				[17] = TargPlayer,
			}
	env.info( 'Event: ' .. _StatRunID .. '~ ' .. SecondsToClock(timer.getTime()) .. '~ ' .. WorldEvent .. '~ ' .. InitID_ .. '~ ' .. InitName .. '~ ' .. InitCoa .. '~ ' .. InitGroupCat .. '~ ' .. InitType .. '~ ' .. InitPlayer ..
	           '~ ' .. eWeaponCat .. '~ ' .. eWeaponName .. '~ ' .. TargID_ .. '~ ' .. TargName .. '~ ' .. TargCoa .. '~ ' .. TargGroupCat .. '~ ' .. TargType .. '~ ' .. TargPlayer )
end




do 

	local StatFile,err
	

	function StatOpen()
		local fdir = lfs.writedir() .. [[Logs\]] .. "Events_" .. os.date( "%Y-%m-%d_%H-%M-%S" ) .. ".csv"
		StatFile,err = io.open(fdir,"w+")
		if not StatFile then
			local errmsg = 'Error: No Logs folder found in the User\\Saved Games\\DCS\\Logs directory...' .. 'Save_stat . sample: C:\\Users\\youname\\Saved Games\\DCS\\Logs' 
			trigger.action.outText(errmsg, 10)
			return print(err)
		end
		StatFile:write("RunID~Time~Event~Initiator ID~Initiator Name~Initiator Coalition~Initiator Group Category~Initiator Type~Initiator Player~Weapon Category~Weapon Name~Target ID~Target Name~Target Coalition~Target Group Category~Target Type~Target Player\n")
		
		_StatRunID = os.date("%y-%m-%d_%H-%M-%S")
		routines.scheduleFunction( StatSave, { }, timer.getTime() + 1, 1)
	end

	function StatSave()
		--write statistic information to file
		for Index, eDetails in ipairs(statEventsTable) do
			for eInfoName, eInfoData in ipairs(eDetails) do
					StatFile:write(eInfoData.."~")
			end
			StatFile:write("\n")
		end
		statEventsTable = {}
	end
	
	function StatClose()
		StatFile:close()
	end

end

world.addEventHandler(eStatHandler)
StatOpen()

