----------------------------------------------------------------------------
--------------"The simplest design is the best design." --------------
----------------------------------------------------------------------------
----------------------------------------------------------------------------
-- Copyright (C)ViperGTS96--------------------------------------------
----------------------------------------------------------------------------

FillStationPig = {};

function FillStationPig:loadMap()
	g_currentMission.mudFillStations = {}
	g_currentMission.updateMudFillStations = false;
	g_currentMission.mudFillStationPigPosition = 1;
	g_currentMission.mudFillStationPigAnimIndex = 1;
	if FillStationPig.pigI3d == nil then
		local basepath = FillStationPig.dataPath;
		local filename = basepath.."/sow/pigSow.i3d";
		FillStationPig.pigI3d = loadI3DFile(filename, false, false, false);
		filename = basepath.."/animations/adult/pigAdultAnimations.i3d";
		FillStationPig.pigAnimations = loadI3DFile(filename, false, false, false);
	end;
end;

function FillStationPig:loadPig(station)
	station.pigModel = clone(FillStationPig.pigI3d, false,false,false);
	link(station.pigRootNode, station.pigModel);

	local animationInput = getChildAt(FillStationPig.pigAnimations,0);
	animationInput = getChildAt(animationInput,0);
	local animationOutput = getChildAt(station.pigModel,0);
	animationOutput = getChildAt(animationOutput,0);
	cloneAnimCharacterSet(animationInput, animationOutput);

	station.piganimSet = getAnimCharacterSet(animationOutput);
	local animIndex = 1;
	if g_currentMission:getIsServer() then
		local animIndex = math.floor(math.random(1,8));
		if animIndex == 8 then animIndex = math.floor(math.random(8,11)); end;
		FillStationPig:sendPigAnimEvent(animIndex);
		g_currentMission.mudFillStationPigAnimIndex = animIndex;
	end;
	animIndex = g_currentMission.mudFillStationPigAnimIndex;
	local animName = FillStationPig.animTable[animIndex];
	local animationClip = getAnimClipIndex(station.piganimSet, animName);
	clearAnimTrackClip(station.piganimSet, 0);
	assignAnimTrackClip(station.piganimSet, 0, animationClip);
	setAnimTrackLoopState(station.piganimSet, 0, true);
	enableAnimTrack(station.piganimSet, 0);

	FillStationPig:setPigPosition(station, animIndex);

	local soundSample = getChildAt(station.pigRootNode,1);
	setVisibility(soundSample, animIndex < 6);

	station.hasPigInstalled = true;
end;

function FillStationPig:loadStations()
	for _, stations in pairs(g_currentMission.storageSystem.placeableLoadingStations) do
		for _, placeable in pairs(stations) do
			if placeable.rootNodeName == "mudFillStation" then
				if placeable.isClient and placeable.isRegistered then
					table.insert(g_currentMission.mudFillStations, placeable);
				end;
			end;
		end;

		for i, mudFillStation in pairs(g_currentMission.mudFillStations) do
			if not entityExists(mudFillStation.rootNode) then
				table.remove(g_currentMission.mudFillStations, i);
				break;
			end;
			local node = getChildAt(mudFillStation.rootNode, 1);
			node = getChildAt(node, 2);
			if mudFillStation.hasPigInstalled == nil then
				mudFillStation.pigRootNode = node;
				FillStationPig:loadPig(mudFillStation);
			end;
		end;
	end;
end;

function FillStationPig:update(dt)
	if g_currentMission.updateMudFillStations then
		FillStationPig:loadStations();
		g_currentMission.updateMudFillStations = false;
	end;
end;

function FillStationPig:setPigPosition(station, animIndex)
	if g_currentMission:getIsServer() then
		local position = 1;
		if animIndex > 5 and animIndex < 8 then 
			position = math.floor(math.random(1,2));
			if position == 2 then position = 3; end;
		elseif animIndex > 7 then 
			position = math.floor(math.random(1,2));
		elseif animIndex == 1 then
			position = 4;
		elseif animIndex == 2 then
			position = 5;
		else
			position = math.floor(math.random(1,3));
		end;
		FillStationPig:sendPigPositionEvent(position);
		g_currentMission.mudFillStationPigPosition = position;
	end;
	local posData = FillStationPig.positions[g_currentMission.mudFillStationPigPosition];
	setTranslation(station.pigRootNode, posData[1],posData[2],posData[3]);
	setRotation(station.pigRootNode, math.rad(posData[4]),math.rad(posData[5]),math.rad(posData[6]));
end;

function FillStationPig:onHourChanged()
	for i, mudFillStation in pairs(g_currentMission.mudFillStations) do
			if not entityExists(mudFillStation.rootNode) then
				table.remove(g_currentMission.mudFillStations, i);
				break;
			end;
			if mudFillStation.hasPigInstalled ~= nil then
				local animIndex = 1;
				if g_currentMission:getIsServer() then
					animIndex = math.floor(math.random(1,8));
					if animIndex == 8 then animIndex = math.floor(math.random(8,11)); end;
					FillStationPig:sendPigAnimEvent(animIndex);
					g_currentMission.mudFillStationPigAnimIndex = animIndex;
				end;
				animIndex = g_currentMission.mudFillStationPigAnimIndex;
				local animName = FillStationPig.animTable[animIndex];
				local animationClip = getAnimClipIndex(mudFillStation.piganimSet, animName);
				clearAnimTrackClip(mudFillStation.piganimSet, 0);
				assignAnimTrackClip(mudFillStation.piganimSet, 0, animationClip);
				setAnimTrackLoopState(mudFillStation.piganimSet, 0, true);
				enableAnimTrack(mudFillStation.piganimSet, 0);

				FillStationPig:setPigPosition(mudFillStation, animIndex);
				
				local soundSample = getChildAt(mudFillStation.pigRootNode,1);
				setVisibility(soundSample, animIndex < 6);
			end;
		end;
end;

function FillStationPig:addLoadingStation(station, placeable)
	g_currentMission.updateMudFillStations = true;
end;

function FillStationPig:removeLoadingStation(station, placeable)
	g_currentMission.updateMudFillStations = true;
end;

FSBaseMission.onHourChanged = Utils.appendedFunction(FSBaseMission.onHourChanged, FillStationPig.onHourChanged);
StorageSystem.addLoadingStation = Utils.prependedFunction(StorageSystem.addLoadingStation, FillStationPig.addLoadingStation);
StorageSystem.removeLoadingStation = Utils.prependedFunction(StorageSystem.removeLoadingStation, FillStationPig.removeLoadingStation);

 function FillStationPig:sendPigPositionEvent(position, noEventSend)
	if g_currentMission.missionDynamicInfo.isMultiplayer then
		mudSystemSinkEvent.sendEvent(g_currentMission, math.floor(position), noEventSend);
		g_currentMission.mudFillStationPigPosition = position;
	end;
end;

 function FillStationPig:sendPigAnimEvent(animIndex, noEventSend)
	if g_currentMission.missionDynamicInfo.isMultiplayer then
		mudSystemSinkEvent.sendEvent(g_currentMission, math.floor(animIndex), noEventSend);
		g_currentMission.mudFillStationPigAnimIndex = animIndex;
	end;
end;

addModEventListener(FillStationPig);

FillStationPig.dataPath = getAppBasePath().."dataS/character/animals/domesticated/pig";
FillStationPig.animTable = {"chewSource", "drinkSource", "grazeSource", "idle1Source", "restSittingSource", "sleepBellyMSource", "restBellyMSource", "sleepSideLSource", "sleepSideRSource", "restSideLSource", "restSideRSource"};
FillStationPig.positions = {
--[[defaultPosition =]] {0.90200001, 0.483796, 1.95647001, 180, -8.18766022, -180},
--[[sleepSidePosition =]] {1.11600006, 0.50126231, 1.05164158, 180, 40.62670898, 179.99998474},
--[[alternatePosition =]] {-2.30699992, 0.91610157, -0.18771763, -180, 35.56135559, 179.99998474},
--[[pigEatPosition =]] {3.26300001, 0.41745642, -1.96647358, -172.99899292, 62.44859314, 179.99998474},
--[[pigDrinkPosition =]] {3.37199998, 0.38061273, -2.02116203, 179.29499817, 61.95691681, 170.84933472}
};


FillStationPigPositionEvent = {};
FillStationPigPositionEvent_mt = Class(FillStationPigPositionEvent, Event);
InitEventClass(FillStationPigPositionEvent,"FillStationPigPositionEvent");

function FillStationPigPositionEvent:emptyNew()
    local self = Event.new(FillStationPigPositionEvent_mt);
    self.className = "FillStationPigPositionEvent";
    return self;
end;
function FillStationPigPositionEvent:new(table,position)
	local self = FillStationPigPositionEvent.emptyNew()
    self.table = table;
    self.position = position;
    return self;
end;
function FillStationPigPositionEvent:readStream(streamId,connection)
    self.table = NetworkUtil.readNodeObject(streamId);
    self.position = streamReadInt16(streamId);
    self:run(connection);
end;
function FillStationPigPositionEvent:writeStream(streamId,connection)
    NetworkUtil.writeNodeObject(streamId,self.table);
    streamWriteInt16(streamId,self.position);
end;
function FillStationPigPositionEvent:run(connection)
	g_currentMission.mudFillStationPigPosition = self.position;
    if not connection:getIsServer() then
        g_server:broadcastEvent(FillStationPigPositionEvent:new(self.table,self.position),nil,connection,self.table);
    end;
end;
function FillStationPigPositionEvent.sendEvent(table,position,noEventSend)
    if noEventSend == nil or noEventSend == false then
        if g_server ~= nil then
            g_server:broadcastEvent(FillStationPigPositionEvent:new(table,position),nil,nil,table);
        else
            g_client:getServerConnection():sendEvent(FillStationPigPositionEvent:new(table,position));
        end;
    end;
end;

FillStationPigAnimEvent = {};
FillStationPigAnimEvent_mt = Class(FillStationPigAnimEvent, Event);
InitEventClass(FillStationPigAnimEvent,"FillStationPigAnimEvent");

function FillStationPigAnimEvent:emptyNew()
    local self = Event.new(FillStationPigAnimEvent_mt);
    self.className = "FillStationPigAnimEvent";
    return self;
end;
function FillStationPigAnimEvent:new(table,animIndex)
	local self = FillStationPigAnimEvent.emptyNew()
    self.table = table;
    self.animIndex = animIndex;
    return self;
end;
function FillStationPigAnimEvent:readStream(streamId,connection)
    self.table = NetworkUtil.readNodeObject(streamId);
    self.animIndex = streamReadInt16(streamId);
    self:run(connection);
end;
function FillStationPigAnimEvent:writeStream(streamId,connection)
    NetworkUtil.writeNodeObject(streamId,self.table);
    streamWriteInt16(streamId,self.animIndex);
end;
function FillStationPigAnimEvent:run(connection)
	g_currentMission.mudFillStationPigAnimIndex = self.animIndex;
    if not connection:getIsServer() then
        g_server:broadcastEvent(FillStationPigAnimEvent:new(self.table,self.animIndex),nil,connection,self.table);
    end;
end;
function FillStationPigAnimEvent.sendEvent(table,animIndex,noEventSend)
    if noEventSend == nil or noEventSend == false then
        if g_server ~= nil then
            g_server:broadcastEvent(FillStationPigAnimEvent:new(table,animIndex),nil,nil,table);
        else
            g_client:getServerConnection():sendEvent(FillStationPigAnimEvent:new(table,animIndex));
        end;
    end;
end;

function FillStationPig:onConnectionWriteUpdateStream(connection, maxPacketSize, networkDebug)
	if not connection:getIsServer() then
		streamWriteInt16(connection.streamId, g_currentMission.mudFillStationPigAnimIndex);
		streamWriteInt16(connection.streamId, g_currentMission.mudFillStationPigPosition);
	end;
end;

function FillStationPig:onConnectionReadUpdateStream(connection, networkDebug)
	if connection:getIsServer() then
		g_currentMission.mudFillStationPigAnimIndex = streamReadInt16(connection.streamId);
		g_currentMission.mudFillStationPigPosition = streamReadInt16(connection.streamId);
	end;
end;

FSBaseMission.onConnectionWriteUpdateStream = Utils.appendedFunction(FSBaseMission.onConnectionWriteUpdateStream, FillStationPig.onConnectionWriteUpdateStream);
FSBaseMission.onConnectionReadUpdateStream = Utils.appendedFunction(FSBaseMission.onConnectionReadUpdateStream, FillStationPig.onConnectionReadUpdateStream);