--
-- multipleAttacherJoints
-- Specialization class for multiple attacher joints
--
-- @author  PeterJ - euroDZN 
-- @date  06/06/2013
--
  
multipleAttacherJoints = {};
 
function multipleAttacherJoints.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;
 
function multipleAttacherJoints:load(xmlFile)

  	self.toggleAttacherJoint = SpecializationUtil.callSpecializationsFunction("toggleAttacherJoint");

	self.attacherJointMode = 1;

	self.multipleAttachers = {};
	local i=0;
	while true do
		local basename = string.format("vehicle.attacherJoint.multipleAttacher(%d)",i);
		local multipleJoints = {};
		multipleJoints.index = Utils.indexToObject(self.components, getXMLString(xmlFile, basename.."#index"));
		if multipleJoints.index == nil then
			break;
		end;
		local jointTypeStr = getXMLString(xmlFile, basename.. "#jointType");
		local jointType;
		if jointTypeStr ~= nil then
			jointType = Vehicle.jointTypeNameToInt[jointTypeStr];
			if jointType == nil then
				print("Warning: invalid jointType " .. jointTypeStr);
			end;
		end;
		if jointType == nil then
			jointType = Vehicle.JOINTTYPE_IMPLEMENT;
		end;
		multipleJoints.jointType = jointType;
		multipleJoints.frame = Utils.indexToObject(self.components, getXMLString(xmlFile, basename.."#frame"));
		local displayType = getXMLString(xmlFile, basename.."#displayType");
		if displayType == nil then
			displayType = jointTypeStr;
		end;
		multipleJoints.displayType = displayType;
		multipleJoints.loaderSchemaOverlay = Utils.getNoNil(getXMLBool(xmlFile, basename.."#loaderSchemaOverlay"),true);
		table.insert(self.multipleAttachers, multipleJoints);
		i=i+1;
	end;
	
	self.multipleAttachersCount = table.getn(self.multipleAttachers);
	
	if self.multipleAttachersCount > 0 then
		self.defaultSchemaOverlay = self.schemaOverlay;
		
		local schemaOverlayFile = getXMLString(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#file");
		if schemaOverlayFile ~= nil then
			schemaOverlayFile = Utils.getFilename(schemaOverlayFile, self.baseDirectory);
			local width = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#width"), 1) * g_currentMission.vehicleSchemaOverlayScaleX;
			local height = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#height"), 1) * g_currentMission.vehicleSchemaOverlayScaleY;
			local invisibleBorderRight = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#invisibleBorderRight"), 0.05);
			local invisibleBorderLeft = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#invisibleBorderLeft"), 0.05);
			local x, y = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#attacherJointPosition"));
			local baseX, baseY = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#basePosition"));
			if baseX == nil then
				baseX = x;
			end;
			if baseY == nil then
				baseY = y;
			end;
			if x ~= nil and y ~= nil then
				local overlay = Overlay:new("", schemaOverlayFile, 0,0, width, height);
				local schemaOverlayFileSelected = getXMLString(xmlFile, "vehicle.schemaOverlay.extraSchemaOverlay#fileSelected");
				local overlaySelected = overlay;
				if schemaOverlayFileSelected ~= nil then
					schemaOverlayFileSelected = Utils.getFilename(schemaOverlayFileSelected, self.baseDirectory);
					overlaySelected = Overlay:new("", schemaOverlayFileSelected, 0,0, width, height);
				end;
				self.extraSchemaOverlay = {overlay=overlay, overlaySelected=overlaySelected, x=x, y=y, baseX=baseX, baseY=baseY, invisibleBorderRight=invisibleBorderRight,invisibleBorderLeft=invisibleBorderLeft};
			end;
		end;
		if not self.multipleAttachers[self.attacherJointMode].loaderSchemaOverlay then 
			self.schemaOverlay = self.extraSchemaOverlay;
		end;
	end;
	
	self.implementIsMounted = false;
end;
  
function multipleAttacherJoints:delete()
end;

function multipleAttacherJoints:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		local attacherJointMode = getXMLInt(xmlFile, key.."#attacherJointMode");
		if attacherJointMode ~= nil then
			if attacherJointMode > self.multipleAttachersCount then
				attacherJointMode = 1;
			end;
			self:toggleAttacherJoint(attacherJointMode);
		end;
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function multipleAttacherJoints:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'attacherJointMode="'..tonumber(self.attacherJointMode)..'"';
	return attributes, nil;
end;

function multipleAttacherJoints:readStream(streamId, connection)
	self:toggleAttacherJoint(streamReadInt8(streamId), true);
end;
  
function multipleAttacherJoints:writeStream(streamId, connection)
	streamWriteInt8(streamId, self.attacherJointMode);
end;
  
function multipleAttacherJoints:mouseEvent(posX, posY, isDown, isUp, button)
end;
 
function multipleAttacherJoints:keyEvent(unicode, sym, modifier, isDown)
end;
  
function multipleAttacherJoints:update(dt)

	if not self:getIsActive() then
		if self.playerInRange and not self.implementIsMounted then
			g_currentMission:addHelpButtonText(g_i18n:getText(self.multipleAttachers[self.attacherJointMode].displayType), InputBinding.IMPLEMENT_EXTRA2);
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
				local jointMode = self.attacherJointMode + 1;
				if jointMode > self.multipleAttachersCount then
					jointMode = 1;
				end;
				self:toggleAttacherJoint(math.abs(jointMode));
			end;
		end;
	end;

end;
  
function multipleAttacherJoints:updateTick(dt)

	if g_currentMission.player ~= nil then
		local nearestDistance = 1.5;
		local x1,y1,z1 = getWorldTranslation(self.multipleAttachers[1].index);
		local x3,y3,z3 = getWorldTranslation(g_currentMission.player.rootNode);
		local distance = Utils.vector3Length(x1-x3,y1-y3,z1-z3);
		if distance < nearestDistance then
			self.playerInRange = true;
		else
			self.playerInRange = false; 
		end;
	end;
end;

function multipleAttacherJoints:draw()
end;
 
function multipleAttacherJoints:toggleAttacherJoint(jointMode, noEventSend)
	MultipleAttacherEvent.sendEvent(self, jointMode, noEventSend);

	for i=1, table.getn(self.multipleAttachers) do
		if i ~= jointMode then
			setVisibility(self.multipleAttachers[i].frame, false);
		else
			self.attacherJoint.node = self.multipleAttachers[jointMode].index;
			self.attacherJoint.jointType = self.multipleAttachers[jointMode].jointType;
			setVisibility(self.multipleAttachers[jointMode].frame, true);
			if self.multipleAttachers[jointMode].loaderSchemaOverlay then
				self.schemaOverlay = self.defaultSchemaOverlay;
			else
				self.schemaOverlay = self.extraSchemaOverlay;
			end;
		end;
	end;
	self.attacherJointMode = jointMode;
end;


function multipleAttacherJoints:onAttach(attacherVehicle)
	self.implementIsMounted = true;
end;

function multipleAttacherJoints:onDetach()
	self.implementIsMounted = false;
end;

MultipleAttacherEvent = {};
MultipleAttacherEvent_mt = Class(MultipleAttacherEvent, Event);

InitEventClass(MultipleAttacherEvent, "MultipleAttacherEvent");

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

function MultipleAttacherEvent:new(vehicle, attacherJointMode)
    local self = MultipleAttacherEvent:emptyNew()
    self.vehicle = vehicle;
	self.attacherJointMode = attacherJointMode;
    return self;
end;

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

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

function MultipleAttacherEvent:run(connection)
	if self.vehicle ~= nil then
		self.vehicle:toggleAttacherJoint(self.attacherJointMode, true);
	end;
	if not connection:getIsServer() then
		g_server:broadcastEvent(MultipleAttacherEvent:new(self.vehicle, self.attacherJointMode), nil, connection, self.vehicle);
	end;
end;

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