-- author: rafftnix
-- date: 25.06.2015

RolePallet = {}

function RolePallet.prerequisitesPresent(specializations)
    return true;
end;

function RolePallet:load(xmlFile)
	self.setRoleVisibility = SpecializationUtil.callSpecializationsFunction("setRoleVisibility");
	self.playerTakeRole = SpecializationUtil.callSpecializationsFunction("playerTakeRole");
	self.playerRemoveRole = SpecializationUtil.callSpecializationsFunction("playerRemoveRole");
	self.playerTriggerCallback = RolePallet.playerTriggerCallback;
	
	self.playerInTrigger = false;
	self.playerTriggerNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roles#playerTrigger"));
	addTrigger(self.playerTriggerNode, "playerTriggerCallback", self);
	
	self.playerRolePos = Utils.getVectorNFromString(getXMLString(xmlFile, "vehicle.roles#playerRolePos"), 3);
	self.playerRoleRot = Utils.getRadiansFromString(getXMLString(xmlFile, "vehicle.roles#playerRoleRot"), 3);
	
	self.roleCloneNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roles#cloneNodeIndex"));
	self.roleLinkNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roles#roleLinkNode"));
	self.roleType = getXMLString(xmlFile, "vehicle.roles#type");
	
	self.roles = {}
	local num = 0;
	while true do
		local key = "vehicle.roles.role("..tostring(num)..")";
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		self.roles[num+1] = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
		num = num + 1;
	end;
end;

function RolePallet:delete()
	removeTrigger(self.playerTriggerNode);
end;

function RolePallet:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	local rolesActiveStr = getXMLString(xmlFile, key.."#rolesActive");
	local rolesActive = Utils.splitString(" ", rolesActiveStr);
	for a=1, table.getn(self.roles) do
		if rolesActive[a] == "1" then
			setVisibility(self.roles[a], true);
		else
			setVisibility(self.roles[a], false);
		end;
	end;
	
	return BaseMission.VEHICLE_LOAD_OK;
end;

function RolePallet:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'rolesActive="';
	for a=1, table.getn(self.roles) do
		if getVisibility(self.roles[a]) then
			attributes = attributes .. '1 ';
		else
			attributes = attributes .. '0 ';
		end;
	end;
	return attributes..'"', "";
end;

function RolePallet:writeStream(streamId, connection)
	if not connection:getIsServer() then -- we are the server
		for a=1, table.getn(self.roles) do
			 streamWriteBool(streamId, getVisibility(self.roles[a]));
		end;
	end;
end;

function RolePallet:readStream(streamId, connection)
	if connection:getIsServer() then -- we are the client
		for a=1, table.getn(self.roles) do
			setVisibility(self.roles[a], streamReadBool(streamId));
		end;
	end;
end;

function RolePallet:mouseEvent(posX, posY, isDown, isUp, button)
end;

function RolePallet:keyEvent(unicode, sym, modifier, isDown)
end;

function RolePallet:update(dt)
	if self.playerInTrigger then
		if not (g_gui.currentGui ~= nil or g_currentMission.isPlayerFrozen) then
			-- take role
			if g_currentMission.player.currentRoleMount == nil then
				local roleIndex;
				for a=1, table.getn(self.roles) do
					if getVisibility(self.roles[a]) then
						roleIndex = a;
						break;
					end;
				end;
				if roleIndex ~= nil then
					g_currentMission:addHelpButtonText(g_i18n:getText("takeRole"), InputBinding.IMPLEMENT_EXTRA2);
					if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
						self:playerTakeRole(g_currentMission.player);
						self:setRoleVisibility(roleIndex, false);
					end;
				end;
			else
				local roleIndex;
				for a=table.getn(self.roles), 1, -1 do
					if not getVisibility(self.roles[a]) then
						roleIndex = a;
						break;
					end;
				end;
				if roleIndex ~= nil then
					g_currentMission:addHelpButtonText(g_i18n:getText("putBackRole"), InputBinding.IMPLEMENT_EXTRA2);
					if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
						self:playerRemoveRole(g_currentMission.player);
						self:setRoleVisibility(roleIndex, true);
					end;
				end;
			end;
		end;
	end;
end;

function RolePallet:updateTick(dt)
	if self.isServer then
		local roleIndex;
		for a=1, table.getn(self.roles) do
			if getVisibility(self.roles[a]) then
				roleIndex = a;
				break;
			end;
		end;
		if roleIndex == nil then
			-- delete only if there is no player with role in hand
			for a=1, table.getn(g_currentMission.players) do
				if g_currentMission.players[a].currentRoleMount == nil then
					g_currentMission.vehiclesToDelete[self] = self;
				end;
			end;
		end;
	end;
end;

function RolePallet:draw()
  
end;

function RolePallet:playerTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
	if g_currentMission.player ~= nil then
		if otherId == g_currentMission.player.rootNode then
			if onEnter then
				self.playerInTrigger = true;
			end;
			if onLeave then
				self.playerInTrigger = false;
			end;
		end;
	end;
end;

function RolePallet:playerTakeRole(player, noEventSend)
	if player ~= nil and player.currentRoleMount == nil then
		local nodeId = clone(self.roleCloneNode, true, false, false);
		link(player.toolsRootNode, nodeId);
		setVisibility(nodeId, true);
		player.currentRoleMount = self;
		player.currentRoleType = self.roleType;
		player.currentRoleNodeId = nodeId;
		setTranslation(nodeId, unpack(self.playerRolePos));
		setRotation(nodeId, unpack(self.playerRoleRot));
	end;

	if not noEventSend then
		PlayerTakeRoleEvent.sendEvent(self, player, true, noEventSend);
	end;
end;

function RolePallet:playerRemoveRole(player, noEventSend) 
	if player ~= nil and player.currentRoleMount == self then
		unlink(player.currentRoleNodeId);
		player.currentRoleMount = nil;
		player.currentRoleType = nil;
		delete(player.currentRoleNodeId);
		player.currentRoleNodeId = nil;
		
		if not noEventSend then
			PlayerTakeRoleEvent.sendEvent(self, player, false, noEventSend);
		end;
	end;
end;

function RolePallet:setRoleVisibility(index, visibility, noEventSend)
	if self.roles[index] ~= nil then
		setVisibility(self.roles[index], visibility);
	else
		print("RolePallet ERROR: index does not exist: "..tostring(index));
		printCallstack();
	end;
	
	if not noEventSend then
		SetRoleVisibilityEvent.sendEvent(self, index, visibility, noEventSend)
	end;
end;