--
-- InteractiveControl v2.0
-- Specialization for an interactive control
--
-- SFM-Modding
-- @author:  	Manuel Leithner
-- @date:		17/10/10
-- @version:	v2.0
-- @history:	v1.0 - initial implementation
--				v2.0 - convert to LS2011 and some bugfixes
--

InteractiveControl = {};

function InteractiveControl.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Steerable, specializations);
end;

function InteractiveControl:load(xmlFile)

	source(Utils.getFilename("specializations/InteractiveComponentInterface.lua", self.baseDirectory));

	self.doActionOnObject = SpecializationUtil.callSpecializationsFunction("doActionOnObject");
	self.setPanelOverlay = SpecializationUtil.callSpecializationsFunction("setPanelOverlay");

	self.interactiveObjects = {};	
	
	self.indoorCamIndex = 2;
	self.outdoorCamIndex = 1;
	
	self.lastMouseXPos = 0;
	self.lastMouseYPos = 0;					

	self.panelOverlay = nil;
	self.foundInteractiveObject = nil;
	self.isMouseActive = false;
end;

function InteractiveControl:delete()
	for _,v in pairs(self.interactiveObjects) do
		v:delete();
	end;
end;

function InteractiveControl:readStream(streamId, connection)
	local icCount = streamReadInt8(streamId);
	for i=1, icCount do
		local isOpen = streamReadBool(streamId);
		if isOpen then
			self.interactiveObjects[i]:doAction();
		end;		
	end;
end;

function InteractiveControl:writeStream(streamId, connection)
	streamWriteInt8(streamId, table.getn(self.interactiveObjects));
	for k,v in pairs(self.interactiveObjects) do
		streamWriteBool(streamId, v.isOpen);
	end;
end;

function InteractiveControl:mouseEvent(posX, posY, isDown, isUp, button)	

	self.lastMouseXPos = posX;
	self.lastMouseYPos = posY;

	if isDown then
		if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_LEFT) and self.foundInteractiveObject ~= nil then			
			self:doActionOnObject(self.foundInteractiveObject);					
		end;
		local currentCam = self.cameras[self.camIndex];
		if currentCam.allowTranslation then
			if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_WHEEL_UP) then
				currentCam:zoomSmoothly(-0.75);
			elseif Input.isMouseButtonPressed(Input.MOUSE_BUTTON_WHEEL_DOWN) then
				currentCam:zoomSmoothly(0.75);
			end;
		end;	
	end;
	
	for _,v in pairs(self.interactiveObjects) do
		v:mouseEvent(posX, posY, isDown, isUp, button);
	end;
	
	if self.isMouseActive then
		self.mouseButton = MouseControlsVehicle.BUTTON_NONE;
	end;
end;

function InteractiveControl:keyEvent(unicode, sym, modifier, isDown)
	for _,v in pairs(self.interactiveObjects) do
		v:keyEvent(unicode, sym, modifier, isDown);
	end;
end;

function InteractiveControl:update(dt)
	if self:getIsActive() then	
		
		if self:getIsActiveForInput() then
			if InputBinding.hasEvent(InputBinding.INTERACTIVE_CONTROL_SWITCH) then
				self.isMouseActive = not self.isMouseActive;
				g_mouseControlsHelp.active = not self.isMouseActive;
				
				if not self.isMouseActive then
					InputBinding.setShowMouseCursor(false);
					self.cameras[self.camIndex].isActivated = true;
				end;
				
				for _,v in pairs(self.interactiveObjects) do
					v:setVisible(self.isMouseActive);
				end;
			end;
			if self.isMouseActive then
				local currentCam = self.cameras[self.camIndex];
				
				self.mouseDirectionY = 0;
				self.mouseDirectionX = 0;
				
				if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_RIGHT) and self:getIsActiveForInput() then
					InputBinding.wrapMousePositionEnabled = true;		
					currentCam.rotX = currentCam.rotX + InputBinding.mouseMovementY;
					currentCam.rotY = currentCam.rotY - InputBinding.mouseMovementX;

					self.cameras[self.indoorCamIndex].isActivated = self.camIndex == self.indoorCamIndex;
					self.cameras[self.outdoorCamIndex].isActivated = self.camIndex == self.outdoorCamIndex;
					setShowMouseCursor(false);
				else
					self.cameras[self.indoorCamIndex].isActivated = self.camIndex ~= self.indoorCamIndex;
					self.cameras[self.outdoorCamIndex].isActivated = self.camIndex ~= self.outdoorCamIndex;
					InputBinding.setShowMouseCursor(true);
				end;
			else
				self.foundInteractiveObject = nil;
			end;
		else
			self.foundInteractiveObject = nil;
		end;
	end;	
end;


function InteractiveControl:updateTick(dt)
	if self:getIsActive() then
		self.foundInteractiveObject = nil;
		for k,v in pairs(self.interactiveObjects) do
			v:update(dt);
			if self.isMouseActive then
				v:onExit(dt);
				if self.camIndex == self.indoorCamIndex then
					local worldX,worldY,worldZ = getWorldTranslation(v.mark);
					local x,y,z = project(worldX,worldY,worldZ);
					if z <= 1 then	
						if self.lastMouseXPos > (x-v.size/2) and self.lastMouseXPos < (x+v.size/2) then
							if self.lastMouseYPos > (y-v.size/2) and self.lastMouseYPos < (y+v.size/2) then
								local isOverlapped = false;
								
								if self.panelOverlay ~= nil then								
									local overlay = self.panelOverlay.mainBackground;
									isOverlapped = checkOverlayOverlap(self.lastMouseXPos, self.lastMouseYPos, overlay);
								end;
								
								if not isOverlapped then
									v:onEnter(dt);
									self.foundInteractiveObject = k;
									break;
								end;
							end;
						end;
					end;
				end;
			end;
		end;
	end;
end;


function InteractiveControl:doActionOnObject(id, noEventSend)
	InteractiveControlEvent.sendEvent(self, id, noEventSend);	
	self.interactiveObjects[id]:doAction();	
end;

function InteractiveControl:draw()	
	if self.isMouseActive then
		for _,v in pairs(self.interactiveObjects) do
			v:draw();
		end;
		g_currentMission:addHelpButtonText(g_i18n:getText("InteractiveControl_Off"), InputBinding.INTERACTIVE_CONTROL_SWITCH);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("InteractiveControl_On"), InputBinding.INTERACTIVE_CONTROL_SWITCH);
	end;
end;

function InteractiveControl:onLeave()
	self.cameras[self.indoorCamIndex].isActivated = true;
	g_mouseControlsHelp.active = true;
	if g_gui.currentGui == nil then
		InputBinding.setShowMouseCursor(false);
	end;
end;


function InteractiveControl:setPanelOverlay(panel)
	
	if self.panelOverlay ~= nil then
		if self.panelOverlay.setActive ~= nil then
			self.panelOverlay:setActive(false);
		end;
	end;
	self.panelOverlay = panel;

	if panel ~= nil then
		if panel.setActive ~= nil then
			panel:setActive(true);
		end;
	end;
end;