--
-- BuyabletwinWheight
-- Specialization for Buyable Twin Wheels
--
-- @author  	Manuel Leithner (SFM-Modding)
-- @version 	v2.0
-- @date  		15/10/10
-- @history:	v1.0 - Initial version
--				v2.0 - added network support, changed update to updateTick
-- @ Ago-Systemtech   -fix for wheight rear mount--- 01/10/2012---(TIF )
---
BuyabletwinWheight = {};

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

function BuyabletwinWheight:load(xmlFile)

	self.twinWheightTriggerCallback = BuyabletwinWheight.twinWheightTriggerCallback;
	self.wheelDelete = BuyabletwinWheight.wheelDelete;
	self.assembleWheels = SpecializationUtil.callSpecializationsFunction("assembleWheels");
	self.disassembleWheels = SpecializationUtil.callSpecializationsFunction("disassembleWheels");

	self.checkString = Utils.getNoNil(getXMLString(xmlFile, "vehicle.twinWheight#checkString"), "standart");
	self.usingTrigger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.twinWheight#activationTrigger"));
	
	
	addTrigger(self.usingTrigger, "twinWheightTriggerCallback", self);
    self.deleteListenerId = addDeleteListener(self.usingTrigger, "wheelDelete", self);
	
	self.belts = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.twinWheight#belts"));
	
    self.buyableWheels = {};
    local i = 0;
    while true do
        local wheelnamei = string.format("vehicle.twinWheight.wheel(%d)", i);
        local wheel = {};
        local wheelIndex = getXMLInt(xmlFile, wheelnamei .. "#wheelIndex");
        if wheelIndex == nil then
            break;
        end;
		
		wheel.wheelIndex = wheelIndex;
		wheel.node = Utils.indexToObject(self.components, getXMLString(xmlFile, wheelnamei .. "#node"));
		wheel.collision = Utils.indexToObject(self.components, getXMLString(xmlFile, wheelnamei .. "#collision"));
		-- collision bug fix: on initial wheel assembling no collision is set
		setRigidBodyType(wheel.collision, "Kinematic");
		setRigidBodyType(wheel.collision, "NoRigidBody");
		wheel.savePosition = Utils.indexToObject(self.components, getXMLString(xmlFile, wheelnamei .. "#savePosition"));
		table.insert(self.buyableWheels, wheel);
		i = i + 1;
	end;

	self.loadedCoords = nil;
	self.twinWheightUser = nil;
end;

function BuyabletwinWheight:delete()
	if self.twinWheightUser ~= nil then
		self.twinWheightUser:onDisassembling(true);
		for _,twinWheight in pairs(self.buyableWheels) do
			delete(twinWheight.node);
			delete(twinWheight.collision);
		end;
		self.buyableWheels = {};
	end;
    removeTrigger(self.usingTrigger);
end;

function BuyabletwinWheight:wheelDelete()
    removeDeleteListener(self.usingTrigger, self.deleteListenerId);
end;

function BuyabletwinWheight:readStream(streamId, connection)
	local id = streamReadInt32(streamId);
	if id ~= -1 then
		local twinWheightUser = networkGetObject(id);
		if twinWheightUser ~= nil then
			self:assembleWheels(twinWheightUser, true);
		end;
	end;
end;

function BuyabletwinWheight:writeStream(streamId, connection)
	local idToWrite = -1;
	if self.twinWheightUser ~= nil then
		idToWrite = networkGetObjectId(self.twinWheightUser);
	end;
	streamWriteInt32(streamId, idToWrite);
end;

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

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

function BuyabletwinWheight:update(dt)
end;

function BuyabletwinWheight:updateTick(dt)

	-- try to load saved twinWheight
	if self.loadedCoords ~= nil then
		for k,steerable in pairs(g_currentMission.steerables) do
			local a,b,c = getWorldTranslation(steerable.rootNode);
			local distance = Utils.vector3Length(self.loadedCoords.x-a, self.loadedCoords.y-b, self.loadedCoords.z-c);
			if distance < 0.15 then				
				self:assembleWheels(steerable);
				break;
			end;
		end;
		self.loadedCoords = nil;
	end;
end;

function BuyabletwinWheight:draw()	
end;

function BuyabletwinWheight:twinWheightTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
	local vehicle = g_currentMission.controlledVehicle;
	if vehicle ~= nil then
		if onEnter then		
			if vehicle.rootNode == otherId then
				if vehicle.buyabletwinWheight ~= nil then
					if vehicle.buyabletwinWheight.checkString == self.checkString then
						if self.twinWheightUser ~= nil then
							if self.twinWheightUser == vehicle then
								vehicle.buyabletwinWheight.wheelsInRange = self;
							end;
						else
							vehicle.buyabletwinWheight.wheelsInRange = self;
						end;
					end;
				end;
			end;
		elseif onLeave then		
			if otherId == vehicle.rootNode then
				if vehicle.buyabletwinWheight ~= nil then
					vehicle.buyabletwinWheight.wheelsInRange = nil;
				end;
			end;
		end;
	end;
end;

function BuyabletwinWheight:assembleWheels(vehicle, noEventSend)
	BuyabletwinWheightAttachEvent.sendEvent(self, vehicle, noEventSend);

	if self.belts ~= nil then
		setVisibility(self.belts, false);
	end;
	if self.twinWheightUser == nil then
		if vehicle.buyabletwinWheight ~= nil then
			self.twinWheightUser = vehicle;	
			-- for k,wheel in pairs(vehicle.wheels) do
				for l,twinWheight in pairs(self.buyableWheels) do 
					if l == 1 then
						unlink(twinWheight.node);
						unlink(twinWheight.collision);
						link(vehicle.wheels[3].driveNode, twinWheight.node);
						link(getParent(vehicle.wheels[3].repr), twinWheight.collision);
						local x,y,z = getWorldTranslation(vehicle.wheels[3].driveNode);
						x,y,z = worldToLocal(getParent(twinWheight.collision), x,y,z);
						setTranslation(twinWheight.collision,x,y,z);
						--setRigidBodyType(twinWheight.collision, "Kinematic");
					elseif l == 2 then
						unlink(twinWheight.node);
						unlink(twinWheight.collision);
						link(vehicle.wheels[4].driveNode, twinWheight.node);
						link(getParent(vehicle.wheels[4].repr), twinWheight.collision);
						local x,y,z = getWorldTranslation(vehicle.wheels[4].driveNode);
						x,y,z = worldToLocal(getParent(twinWheight.collision), x,y,z);
						setTranslation(twinWheight.collision,x,y,z);
						--setRigidBodyType(twinWheight.collision, "Kinematic");
					end;
				end;
			-- end;	
			self.twinWheightUser:onAssembling(self);
		end;
	end;
end;

function BuyabletwinWheight:disassembleWheels(noEventSend)
	BuyabletwinWheightDetachEvent.sendEvent(self, noEventSend);

	self.twinWheightUser:onDisassembling();

	if self.belts ~= nil then
		setVisibility(self.belts, true);
	end;
	
	for k,wheel in pairs(self.buyableWheels) do
		setRigidBodyType(wheel.collision, "NoRigidBody");
		unlink(wheel.collision);
		unlink(wheel.node);
		setRotation(wheel.collision, 0,0,0);
		setTranslation(wheel.collision, 0,0,0);
		link(wheel.savePosition, wheel.collision);
		link(wheel.collision, wheel.node);
	end;	
	self.twinWheightUser = nil;	
end;


function BuyabletwinWheight:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)

	if not resetVehicles then
		local valueStr = getXMLString(xmlFile, key.."#attacherCoords");		
		if valueStr ~= nil then
			local x,y,z = Utils.getVectorFromString(valueStr);
			self.loadedCoords = {x = x,y = y,z = z};			
		end;
	end; 

    return BaseMission.VEHICLE_LOAD_OK;
end;

function BuyabletwinWheight:getSaveAttributesAndNodes(nodeIdent)	
    local attributes = nil;
	
	if self.twinWheightUser ~= nil then
		local x,y,z = getWorldTranslation(self.twinWheightUser.rootNode);
		attributes = 'attacherCoords="'.. x .. " " .. y .. " " .. z ..'"';
	end;
	
    return attributes, nil;
end;




