--
-- changeableParts
-- Specialization for changeableParts
--
-- @author  	Stefan Maurus
-- @version 	v1.0
-- @date  		08.04.2014
--
--notes
--[[
<!--modDesc stuff-->
	<specialization name="changeableParts" className="changeableParts" filename="changeableParts.lua" />
	
	<specialization name="changeableParts"/>	
			
    <inputBindings>	
		<input name="CHANGEABLEPARTS_CHANGESELECTION"  category="VEHICLE" key1="KEY_x" key2="" button="" device="0" mouse="" />	
		<input name="CHANGEABLEPARTS_BUYSELECTION"  category="VEHICLE" key1="KEY_o" key2="" button="" device="0" mouse="" />			
    </inputBindings>

    <l10n>	
		<text name="CHANGEABLEPARTS_INFO"> <!--'%s' will be replaced with the name of the current selected part and '%d' with the price of this part-->
            <en>Selected part: %s price: %d</en>
            <de>Ausgewähltes Teil: %s Preis: %d</de>
        </text>	
		<text name="CHANGEABLEPARTS_BUYSELECTION">
            <en>Buy selected part</en>
            <de>Ausgewähltes Teil kaufen</de>
        </text>	
		<text name="CHANGEABLEPARTS_CHANGESELECTION">
            <en>Change selected part</en>
            <de>Auswahl ändern</de>
        </text>	
		
		<!--just examples // same name which is in the xml-->
		<text name="PART1">
            <en>Part 1</en>
            <de>Teil 1</de>
        </text>		
		<text name="PART2">
            <en>Part 2</en>
            <de>Teil 2</de>
        </text>				
	</l10n>	
	
<!--xml stuff-->

	<changeableParts changeRef="0>2|0" nearestDistanceToPerson="3" onlyAvailableAtDealer="true"> <!--'changeRef' is the reference point for buying // 'nearestDistanceToPerson' is the distance you can go off the point to buy (Example: The distance from person to the point has to be under 3 to buy) -->
		<part price="2000" i18n_name="PART1"> <!--i18n_name is the name for the text in the modDesc --> <!--you can add more parts and nodes, its infinity-->
			<node index="0>2|0|0" />
			<node index="0>2|0|1" />
		</part>
		<part price="1233" i18n_name="PART2">
			<node index="0>2|1|0" />
			<node index="0>2|1|1" />
		</part>
	</changeableParts>	
]]

changeableParts = {};

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

function changeableParts:load(xmlFile)
	self.setPartState = SpecializationUtil.callSpecializationsFunction("setPartState");
	self.currentPart = 1;
	self.currentSelected = 1;
	
	self.changeRef = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.changeableParts#changeRef"));
	self.nearestDistanceToPerson = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.changeableParts#nearestDistanceToPerson"), 3);
	self.onlyAvailableAtDealer = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.changeableParts#onlyAvailableAtDealer"), false);
	
	local i = 0;
	self.changeableParts = {};
	while true do
        local key = string.format("vehicle.changeableParts.part(%d)", i);
		if not hasXMLProperty(xmlFile, key) then
			break;
		end;
		
		local price = Utils.getNoNil(getXMLFloat(xmlFile, key.."#price"), 1000);
		local i18n_name = getXMLString(xmlFile, key.."#i18n_name");
		local number = i+1;
		
		local j = 0;
		local node = {};
		while true do
			local stepKey = key..string.format(".node(%d)", j);
			if not hasXMLProperty(xmlFile, stepKey) then
				break;
			end;
			local index = Utils.indexToObject(self.components, getXMLString(xmlFile, stepKey.."#index"));
			if i >= 1 then
				setVisibility(index, false);
			end;
			table.insert(node, {index=index});
			j = j + 1;
		end;

		table.insert(self.changeableParts, {node=node,price=price,i18n_name=i18n_name,number=number});
		i = i + 1;
		self.numberOfParts = i;
	end;

end;

function changeableParts:delete()
end;

function changeableParts:readStream(streamId, connection)
	self:setPartState(streamReadInt8(streamId), true);
end;

function changeableParts:writeStream(streamId, connection) 
	streamWriteInt8(streamId, self.currentPart);
end;

function changeableParts:setPartState(int, noEventSend)
	self.currentPart = int;
	for _, part in pairs(self.changeableParts) do
		for _, node in pairs(part.node) do
			if part.number == int then
				setVisibility(node.index, true);
			else
				setVisibility(node.index, false);
			end;
		end;
	end;
	SetPartStateEvent.sendEvent(self, int, noEventSend);
end;

function changeableParts:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	self:setPartState(Utils.getNoNil(getXMLFloat(xmlFile, key .. "#currentPart"), 1));

	return BaseMission.VEHICLE_LOAD_OK;
end;
 
function changeableParts:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'currentPart="'..self.currentPart..'"';
	return attributes, nil;
end;

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

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

function changeableParts:update(dt)
	if g_currentMission.player ~= nil then
		local nearestDistanceToDealer = 100;			
		local x1,y1,z1 = getWorldTranslation(self.changeRef);
		local x2,y2,z2 = getWorldTranslation(g_currentMission.player.rootNode);		
		local currentDistanceToPerson = Utils.vector3Length(x1-x2,y1-y2,z1-z2);	
		local currentDistanceToDealer = Utils.vector3Length(g_currentMission.storeSpawnPlaces[1].startX-x2,g_currentMission.storeSpawnPlaces[1].startY-y2,g_currentMission.storeSpawnPlaces[1].startZ-z2);	
		if not self.onlyAvailableAtDealer then
			distance2 = 0;
		end;
		if currentDistanceToPerson < self.nearestDistanceToPerson and currentDistanceToDealer < nearestDistanceToDealer then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("CHANGEABLEPARTS_BUYSELECTION")), InputBinding.CHANGEABLEPARTS_BUYSELECTION);	
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("CHANGEABLEPARTS_CHANGESELECTION")), InputBinding.CHANGEABLEPARTS_CHANGESELECTION);			
			g_currentMission:addExtraPrintText(string.format(g_i18n:getText("CHANGEABLEPARTS_INFO"), g_i18n:getText(self.changeableParts[self.currentSelected].i18n_name), self.changeableParts[self.currentSelected].price));	
			if InputBinding.hasEvent(InputBinding.CHANGEABLEPARTS_CHANGESELECTION) then
				self.currentSelected = self.currentSelected+1;
				if self.currentSelected > self.numberOfParts then
					self.currentSelected = 1;
				end;
			end;
			if InputBinding.hasEvent(InputBinding.CHANGEABLEPARTS_BUYSELECTION) then
				if self.currentSelected ~= self.currentPart then
					self:setPartState(self.currentSelected);
					g_currentMission:addSharedMoney(-self.changeableParts[self.currentSelected].price);	
				end;
			end;
		end;
	end;
end;

function changeableParts:updateTick(dt)
end;

function changeableParts:draw()
end;

function changeableParts:onAttach()
end;

function changeableParts:onDetach()	
end; 

----Event----

SetPartStateEvent = {};
SetPartStateEvent_mt = Class(SetPartStateEvent, Event);

InitEventClass(SetPartStateEvent, "SetPartStateEvent");

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

function SetPartStateEvent:new(vehicle, currentPart)
    local self = SetPartStateEvent:emptyNew()
    self.vehicle = vehicle;
	self.currentPart = currentPart;
    return self;
end;

function SetPartStateEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.currentPart = streamReadInt8(streamId);
	self.vehicle:setPartState(self.currentPart, true);
	
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetPartStateEvent:new(self.vehicle, self.currentPart), nil, connection, self.vehicle);
    end;
end;

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

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