--
-- InteractiveControlPanel
-- Specialization for InteractiveControlPanel
--
-- @author:  	Manuel Leithner
-- @date:		20/10/10
-- @version:	v2.0
-- @history:	v1.0 - initial implementation
--				v2.0 - Converted to LS2011
--

InteractiveControlPanel = InteractiveControlBase.newSpecialization();

function InteractiveControlPanel.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;

function InteractiveControlPanel:load(xmlFile)

--source(Utils.getFilename("InteractiveComponentInterface.lua", self.baseDirectory));
	
	self.detachPosition = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.controlPanel#detachPosition"));
	self.controlPanel = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.controlPanel#index"));
	if self.detachPosition == nil then
		self.detachPosition = getParent( self.controlPanel )
	end
	
	self.attacherVehicleCopy = nil;
	
	self.infoBar = {};
	self.infoBar.posX = 0.4;
	self.infoBar.posY = 0.9359;
	
	self.infoBar.width = 0.3156;
	self.infoBar.hud = Overlay:new("icInfobar", Utils.getFilename("shared/interactiveControl_info.dds", self.baseDirectory), self.infoBar.posX, self.infoBar.posY, self.infoBar.width, 0.0526);
	
	self.interactiveObjects = {};			
	self.isControlingActive = false

	self.isDetachAllowed = Utils.overwrittenFunction(self.isDetachAllowed, InteractiveControlPanel.isDetachAllowed)
	
end;

function InteractiveControlPanel:postLoad(xmlFile)
	setVisibility( self.controlPanel, false )
end

function InteractiveControlPanel:update(dt)
	if self:getIsActive() and not ( self.isControlingActive ) then	
		for k,v in pairs(self.interactiveObjects) do
			if      self.isClient 
					and self:getIsActiveForInput(false) 
					and not self:hasInputConflictWithSelection() 
					and InteractiveControlBase.hasInputEvent( v.id ) then
				if v.isLocalOnly == nil or not v.isLocalOnly then
					InteractiveControlPanelEvent.sendEvent(self, k, noEventSend);	
				end;
				v:doAction()
			end
			v:update(dt);
		end
	end
end

function InteractiveControlPanel:draw()	
	if self:getIsActive() and not ( self.isControlingActive ) then	
		for _,v in pairs(self.interactiveObjects) do
			if v.showHelp and InputBinding[v.id] ~= nil then
				local text=""
				if v.isOpen then
					text = string.format(v.offMessage, v.name);
				else
					text = string.format(v.onMessage, v.name);
				end;
				g_currentMission:addHelpButtonText(text, InputBinding[v.id]);
			end;
		
			v:draw();
		end;
	end;
end;


function InteractiveControlPanel:onAttach(attacherVehicle)
	self.attacherVehicleCopy = attacherVehicle;
	if type( self.attacherVehicleCopy.controlPanels ) == "table" then
		local wasSuccessful = InteractiveControlPanel.addControlPanel(self.attacherVehicleCopy, self);
		if wasSuccessful then
			setVisibility( self.controlPanel, true )
		end
	end;	
end;

function InteractiveControlPanel:isDetachAllowed( superFunc )
	if self.attacherVehicleCopy ~= nil and self.attacherVehicleCopy.isMouseActive then
		return false
	end
	
	if superFunc ~= nil then
		return superFunc(self)
	end

	return true
end

function InteractiveControlPanel:onDetach()
	if self.attacherVehicleCopy == nil then
		return
	end
	if type( self.attacherVehicleCopy.controlPanels ) == "table" then
		self.attacherVehicleCopy.isMouseActive = false
		local wasSuccessful = InteractiveControlPanel.removeControlPanel( self.attacherVehicleCopy, self);
	end;

	self.attacherVehicleCopy = nil;
	setVisibility( self.controlPanel, false )
end


function InteractiveControlPanel.addControlPanel( vehicle, object, position )	
	if object ~= nil then
		local controlPanelAttacher = nil;
		if position ~= nil and position < table.getn(vehicle.controlPanels) then
			if vehicle.controlPanels[position].loaded == nil then
				controlPanelAttacher = vehicle.controlPanels[position];
			end;
		else		
			for k,v in pairs(vehicle.controlPanels) do
				if v.loaded == nil then
					controlPanelAttacher = v;
					break;
				end;
			end;
		end;
		
		if controlPanelAttacher ~= nil and controlPanelAttacher.node ~= nil then
			-- link i3d-File
			unlink(object.controlPanel);
			link(controlPanelAttacher.node, object.controlPanel);
			controlPanelAttacher.loaded = object.controlPanel;
			controlPanelAttacher.implement = object;					
			if object.interactiveObjects ~= nil then
				for _,interactiveObject in pairs(object.interactiveObjects) do					
					table.insert(vehicle.interactiveObjects, interactiveObject);
				end
				object.isControlingActive = true;
			end;
			return true;
		end;				
	end;
	
	return false;
end;

function InteractiveControlPanel.removeControlPanel( vehicle, object )
	if object ~= nil then
		for k,v in pairs(vehicle.controlPanels) do
			if v.implement == object then
				if v.loaded ~= nil and v.loaded == object.controlPanel then
					-- unlink controlpanel
					unlink(object.controlPanel);
					link(object.detachPosition, object.controlPanel);
				end;
				v.loaded = nil;
				v.implement = nil;				
				
				if object.interactiveObjects ~= nil then
					for l,w in pairs(vehicle.interactiveObjects) do
						for _,interactiveObject in pairs(object.interactiveObjects) do					
							if w == interactiveObject then
								table.remove(vehicle.interactiveObjects, l);
								break;
							end
						end;
					end;
				end;			
				object.isControlingActive = false;			
				
				return true;
			end;
		end;
	end;
	
	return false;
end;

function InteractiveControlPanel:getSaveAttributesAndNodes(nodeIdent)
  local nodes = ""
	
	for _,v in pairs(self.interactiveObjects) do
		if v.vehicle == self and v.saveAttributes then
			local str = v:getSaveAttributes()
			if str ~= nil and str ~= "" then
				if nodes ~= "" then
					nodes = nodes .. "\n"
				end
				nodes = nodes .. nodeIdent .. "<interactiveComponent name=\"" .. v.id .. "\" ".. str .. " />"					
			end
		end
	end
	
	return "", nodes
end

function InteractiveControlPanel:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	local i=0
	while true do
		local xmlName = string.format(key..".interactiveComponent(%d)", i);	
		local id      = getXMLString(xmlFile, xmlName .. "#name")
		if id == nil then
			break
		end
		for _,v in pairs(self.interactiveObjects) do
			if v.id == id then
				if v.vehicle == self and v.saveAttributes then
					local tmp = v.playSound
					v.playSound = false
					v:setSaveAttributes(xmlFile, xmlName)
					v.playSound = tmp
				end
				break
			end
		end
		i = i + 1
	end

 return BaseMission.VEHICLE_LOAD_OK
end





InteractiveControlPanelEvent = {};
InteractiveControlPanelEvent_mt = Class(InteractiveControlPanelEvent, Event);

InitEventClass(InteractiveControlPanelEvent, "InteractiveControlPanelEvent");

function InteractiveControlPanelEvent:emptyNew()
    local self = Event:new(InteractiveControlPanelEvent_mt);
    return self;
end;

function InteractiveControlPanelEvent:new(vehicle, interactiveControlID)
    local self = InteractiveControlPanelEvent:emptyNew()
    self.vehicle = vehicle;
	self.interactiveControlID = interactiveControlID;
    return self;
end;

function InteractiveControlPanelEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.interactiveControlID = streamReadInt8(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function InteractiveControlPanelEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));	
	streamWriteInt8(streamId, self.interactiveControlID);
end;

function InteractiveControlPanelEvent:run(connection)
	self.vehicle.interactiveObjects[self.interactiveControlID]:doAction(true);	
	if not connection:getIsServer() then
		g_server:broadcastEvent(InteractiveControlPanelEvent:new(self.vehicle, self.interactiveControlID), nil, connection, self.vehicle);
	end;
end;

function InteractiveControlPanelEvent.sendEvent(vehicle, icObject, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(InteractiveControlPanelEvent:new(vehicle, icObject), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(InteractiveControlPanelEvent:new(vehicle, icObject));
		end;
	end;
end;

