--
-- Specialization to set Visibility of parts
--
--
-- @author:		Marcus Hedblom a.k.a Xentro (www.ls-uk.info)
-- @version:	v1.0
-- @date:		09/01/12
-- @history:	v1.0 - inital implementation
--[[

<CiderVisible>
	<!-- this sets the visibility of 2 nodes -->
	<part inputName="Name_of_button_in_moddesc" visible="false" positivel10n="positiveMeassage" negativl10n="negativMeassage" >
		<nodes index="0>1" />
		<nodes index="0>2" />
	</part>
	
	<!-- if you want one more part with different button and without 110n -->
	<part inputName="Name_of_button_in_moddesc2" visible="false" >
		<nodes index="0>3" />
	</part>
</CiderVisible>

]]--

CiderVis = {};

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

function CiderVis:load(xmlFile)
	print("CiderVis: load("..xmlFile..")");
	
	self.setCiderVis = SpecializationUtil.callSpecializationsFunction("setCiderVis");
	
	self.CiderVisible = {};
	local i=0;
	while true do
		local baseName = string.format("vehicle.CiderVisible.part(%d)", i);
		if not hasXMLProperty(xmlFile, baseName) then
			break;
        end;
		local entry = {};
		local inputName = getXMLString(xmlFile, baseName .. "#inputName");
		
		local positivel10n = getXMLString(xmlFile, baseName .. "#positivel10n");
		local negativl10n = getXMLString(xmlFile, baseName .. "#negativl10n");
		
		if InputBinding[inputName] == nil then
			print("Error: Can't find the InputBinding ("..tostring(inputName)..") for CiderVisible part number"..i);
			break;
		end;
		
		if g_i18n:hasText(positivel10n) and g_i18n:hasText(negativl10n) then
			entry.positivel10n = positivel10n;
			entry.negativl10n = negativl10n;
		end;
		
		entry.inputName = inputName;
		entry.visible = Utils.getNoNil(getXMLBool(xmlFile, baseName .. "#visible"),false);
		entry.allow = true;
		
		entry.nodes = {};
		local nodesI = 0;
		while true do
			local nodesName = baseName..string.format(".nodes(%d)", nodesI);
			if not hasXMLProperty(xmlFile, nodesName) then
				break;
			end;
			local node = Utils.indexToObject(self.components, getXMLString(xmlFile, nodesName.."#index"));
			if node ~= nil then
				setVisibility(node, entry.visible);
				
				local entry2 = {};
				entry2.node = node;
				table.insert(entry.nodes, entry2);
			end;
			nodesI = nodesI + 1;
		end; 
		table.insert(self.CiderVisible, entry);
		i = i+1;
	end;
end;

function CiderVis:delete()
end;

function CiderVis:readStream(streamId, connection)
	for k,v in ipairs(self.CiderVisible) do
		local state = streamReadBool(streamId);
		self:setCiderVis(k,state,true);
	end;
end;

function CiderVis:writeStream(streamId, connection)
	for k,v in ipairs(self.CiderVisible) do
		streamWriteBool(streamId, v.visible);
	end;
end;

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

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

function CiderVis:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then		
		local numVisible = getXMLInt(xmlFile, key.."#numVisible");
		if numVisible ~= nil then
			for i=1, numVisible do
				local bKey = key..string.format(".CiderVis(%d)", i-1);
				local state = Utils.getNoNil(getXMLBool(xmlFile, bKey.."#visible"),false);
				if state ~= nil then
					self:setCiderVis(i, state);
				end;
			end;
		end;
	end; 
	return BaseMission.VEHICLE_LOAD_OK;
end;

function CiderVis:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'numVisible="'..table.getn(self.CiderVisible)..'" ';
	local nodes = "";
	local numVisible = 0;
	for i=1, table.getn(self.CiderVisible) do
		local b = self.CiderVisible[i];
		if numVisible > 0 then
			nodes = nodes.."\n";
		end;
		nodes = nodes..nodeIdent..'<CiderVis visible="'..tostring(b.visible)..'" ';
		nodes = nodes..' />';
		numVisible = numVisible+1;
	end;
	
    return attributes, nodes;
end;

function CiderVis:update(dt)
    if self:getIsActive() then
		if self:getIsActiveForInput() then
			for k,v in ipairs(self.CiderVisible) do
				if v.allow then
					if InputBinding.hasEvent(InputBinding[v.inputName]) then
						self:setCiderVis(k, not v.visible); 
					end;
				end;
			end;
		end;
	end;
end;

function CiderVis:draw()
	if g_currentMission.showHelpText then
		for k,v in ipairs(self.CiderVisible) do
			if v.positivel10n ~= nil and v.negativl10n ~= nil then
				if v.visible then
					g_currentMission:addHelpButtonText(g_i18n:getText(v.negativl10n), InputBinding[v.inputName]);
				else
					g_currentMission:addHelpButtonText(g_i18n:getText(v.positivel10n), InputBinding[v.inputName]);
				end;
			end;
		end;
	end;
end;

function CiderVis:setCiderVis(id, state, noEventSend)
	local v = self.CiderVisible[id];
	if v ~= nil and state ~= nil then
		v.visible = state;
		for k, part in ipairs(v.nodes) do
			setVisibility(part.node, state);
		end;
		setCiderVisEvent.sendEvent(self, id, state, noEventSend);
	end;
end;

-- Event --
setCiderVisEvent = {};
setCiderVisEvent_mt = Class(setCiderVisEvent, Event);
InitEventClass(setCiderVisEvent, "setCiderVisEvent");

function setCiderVisEvent:emptyNew()
    local self = Event:new(setCiderVisEvent_mt);
    self.className="setCiderVisEvent";
    return self;
end;

function setCiderVisEvent:new(object, id, state)
	local self = setCiderVisEvent:emptyNew()
	self.object = object;
	self.id = id;
	self.state = state;
	return self;
end;

function setCiderVisEvent:readStream(streamId, connection)
    self.object = networkGetObject(streamReadInt32(streamId));
	self.id  = streamReadInt8(streamId);
    self.state = streamReadBool(streamId);
    self:run(connection);
end;

function setCiderVisEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
	streamWriteInt8(streamId, self.id);
	streamWriteBool(streamId, self.state);
end;

function setCiderVisEvent:run(connection)
	self.object:setCiderVis(self.id,self.state, true);
	if not connection:getIsServer() then
		g_server:broadcastEvent(setCiderVisEvent:new(self.object, self.id, self.state), nil, connection, self.object);
	end;	
end;

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