

BZP15_2 = {};

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

function BZP15_2:load(xmlFile)
	self.aiTerrainDetailChannel1 = g_currentMission.ploughChannel; 
	self.aiTerrainDetailChannel2 = g_currentMission.cultivatorChannel;		

	local MiddlePartXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.MiddlePart#index"));
    if MiddlePartXNode ~= nil then
        self.MiddlePart = {};
        self.MiddlePart.node = MiddlePartXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.MiddlePart#minRot"));
        self.MiddlePart.minRot = {};
        self.MiddlePart.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.MiddlePart.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.MiddlePart.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.MiddlePart#maxRot"));
        self.MiddlePart.maxRot = {};
        self.MiddlePart.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.MiddlePart.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.MiddlePart.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.MiddlePart.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.MiddlePart#rotTime"), 2)*1000;
        self.MiddlePart.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.MiddlePart#touchRotLimit"), 10));
    end;	

	local LeftJointXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.LeftJoint#index"));
    if LeftJointXNode ~= nil then
        self.LeftJoint = {};
        self.LeftJoint.node = LeftJointXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.LeftJoint#minRot"));
        self.LeftJoint.minRot = {};
        self.LeftJoint.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.LeftJoint.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.LeftJoint.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.LeftJoint#maxRot"));
        self.LeftJoint.maxRot = {};
        self.LeftJoint.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.LeftJoint.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.LeftJoint.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.LeftJoint.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.LeftJoint#rotTime"), 2)*1000;
        self.LeftJoint.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.LeftJoint#touchRotLimit"), 10));
    end;
	local RightJointXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.RightJoint#index"));
    if RightJointXNode ~= nil then
        self.RightJoint = {};
        self.RightJoint.node = RightJointXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.RightJoint#minRot"));
        self.RightJoint.minRot = {};
        self.RightJoint.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.RightJoint.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.RightJoint.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.RightJoint#maxRot"));
        self.RightJoint.maxRot = {};
        self.RightJoint.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.RightJoint.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.RightJoint.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.RightJoint.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.RightJoint#rotTime"), 2)*1000;
        self.RightJoint.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.RightJoint#touchRotLimit"), 10));
    end;	

	local ZJointXNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.ZJoint#index"));
    if ZJointXNode ~= nil then
        self.ZJoint = {};
        self.ZJoint.node = ZJointXNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.ZJoint#minRot"));
        self.ZJoint.minRot = {};
        self.ZJoint.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.ZJoint.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.ZJoint.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.ZJoint#maxRot"));
        self.ZJoint.maxRot = {};
        self.ZJoint.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.ZJoint.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.ZJoint.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.ZJoint.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.ZJoint#rotTime"), 2)*1000;
        self.ZJoint.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.ZJoint#touchRotLimit"), 10));
    end;
	
	local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);	
	self.hydraulics = {};	
	for i=1, hydraulicsCount do
		local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);		
		self.hydraulics[i] = {};		
		self.hydraulics[i].node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
		self.hydraulics[i].punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
		self.hydraulics[i].translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
		self.hydraulics[i].fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));	
		if self.hydraulics[i].punch ~= nil then
			local ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
			local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);
			self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		end;
		self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
	end;

	self.numRollers = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.Rollers#count"), 0);	
    self.Rollers = {};
    for i=1, self.numRollers do
        local Rollersnamei = string.format("vehicle.Rollers.Roller" .. "%d", i);
        self.Rollers[i] = Utils.indexToObject(self.components, getXMLString(xmlFile, Rollersnamei .. "#index"));
    end;
	
	local SupportAttacherNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.SupportAttacher#index"));
    if SupportAttacherNode ~= nil then
        self.SupportAttacher = {};
        self.SupportAttacher.node = SupportAttacherNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.SupportAttacher#minTrans"));
        self.SupportAttacher.minTrans = {};
        self.SupportAttacher.minTrans[1] = Utils.getNoNil(x, 0);
        self.SupportAttacher.minTrans[2] = Utils.getNoNil(y, 0);
        self.SupportAttacher.minTrans[3] = Utils.getNoNil(z, 0);

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.SupportAttacher#maxTrans"));
        self.SupportAttacher.maxTrans = {};
        self.SupportAttacher.maxTrans[1] = Utils.getNoNil(x, 0);
        self.SupportAttacher.maxTrans[2] = Utils.getNoNil(y, 0);
        self.SupportAttacher.maxTrans[3] = Utils.getNoNil(z, 0);

        self.SupportAttacher.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.SupportAttacher#transTime"), 2)*1000;
        self.SupportAttacher.touchTransLimit = Utils.getNoNil(getXMLString(xmlFile, "vehicle.SupportAttacher#touchTransLimit"), 10);
    end;	
	local SupportFrameNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.SupportFrame#index"));
    if SupportFrameNode ~= nil then
        self.SupportFrame = {};
        self.SupportFrame.node = SupportFrameNode;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.SupportFrame#minRot"));
        self.SupportFrame.minRot = {};
        self.SupportFrame.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.SupportFrame.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.SupportFrame.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.SupportFrame#maxRot"));
        self.SupportFrame.maxRot = {};
        self.SupportFrame.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.SupportFrame.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.SupportFrame.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.SupportFrame.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.SupportFrame#rotTime"), 2)*1000;
        self.SupportFrame.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.SupportFrame#touchRotLimit"), 10));
    end;
	-- Sounds --
	local cultivatorSound = getXMLString(xmlFile, "vehicle.cultivatorSound#file");
    if cultivatorSound ~= nil and cultivatorSound ~= "" then
        cultivatorSound = Utils.getFilename(cultivatorSound, self.baseDirectory);
        self.cultivatorSound = createSample("cultivatorSound");
        loadSample(self.cultivatorSound, cultivatorSound, false);
        self.cultivatorSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cultivatorSound#pitchOffset"), 0);
        self.cultivatorSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cultivatorSound#volume"), 1.5);
        self.cultivatorSoundEnabled = false;
    end;

	self.LeftDetector = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.LeftPartDetector#index"));
	self.RightDetector = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.RightPartDetector#index"));
	self.LeftPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.LeftPart#index"));
	self.RightPart = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.RightPart#index"));
	
	self.CarrierIsDown = false;
	self.SupportAttacherMin = true;
	self.SupportFrameMin = true;
	self.ZFrame = true;	
end;

function BZP15_2:delete()
    if self.cultivatorSound ~= nil then
        delete(self.cultivatorSound);
    end;
end;

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

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

function BZP15_2:update(dt)
    if self.attacherVehicle then	
		if self.isActive then		

			if InputBinding.isPressed(InputBinding.CARRIERWORKMODEON) then
				self.MiddlePartMax = true;												
			else
				self.MiddlePartMax = false;				
			end;
			if InputBinding.isPressed(InputBinding.CARRIERWORKMODEOFF) then
				self.MiddlePartMin = true;				
			else
				self.MiddlePartMin = false;			
			end;
			
			local doRotate = self.MiddlePartMax or self.MiddlePartMin 
			if self.MiddlePart ~= nil and doRotate then
				local x, y, z = getRotation(self.MiddlePart.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.MiddlePart.maxRot, self.MiddlePart.minRot, 3, self.MiddlePart.rotTime, dt, not self.MiddlePartMax);
				setRotation(self.MiddlePart.node,unpack(newRot));
			end;		

			local x, y, z = getRotation(self.MiddlePart.node);
			local maxRot = self.MiddlePart.maxRot;
			local eps = self.MiddlePart.touchRotLimit;
			if  (math.abs(x-maxRot[1]) < eps) then
				self.LeftJointMax = true;
				self.RightJointMax = true;
				self.LeftJointMin = false;
				self.RightJointMin = false;
				setJointRotationLimit(self.componentJoints[2].jointIndex, 1, true, math.rad(-50), math.rad(60));
				setJointRotationLimit(self.componentJoints[3].jointIndex, 1, true, math.rad(-60), math.rad(50));			
			end;
			
			if  (math.abs(x-maxRot[1]) < math.rad(15)) then
				self.CarrierIsDown = true;
			else
				self.CarrierIsDown = false;
			end;
			if  self.ZFrame then
				self.ZJointMax = false;
				self.ZJointMin = true;							
				setJointRotationLimit(self.componentJoints[1].jointIndex, 0, true, math.rad(-25), math.rad(25));			
				else
				self.ZJointMax = true;
				self.ZJointMin = false;						
				setJointRotationLimit(self.componentJoints[1].jointIndex, 0, true, math.rad(-20), math.rad(20));				
			end;
			
			setJointFrame(self.componentJoints[1].jointIndex, 1,self.componentJoints[1].jointNode);	

			local doRotate = self.ZJointMax or self.ZJointMin
			if self.ZJoint ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[1].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.ZJoint.maxRot, self.ZJoint.minRot, 3, self.ZJoint.rotTime, dt, not self.ZJointMax);
				setRotation(self.componentJoints[1].jointNode,unpack(newRot));
			end;
			
			local doRotate = self.RightJointMax or self.RightJointMin or not self.RightJointMax
			if self.RightJoint ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[2].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.RightJoint.maxRot, self.RightJoint.minRot, 3, self.RightJoint.rotTime, dt, not self.RightJointMax);
				setRotation(self.componentJoints[2].jointNode,unpack(newRot));
			end;			
			local doRotate = self.LeftJointMax or self.LeftJointMin or not self.LeftJointMax
			if self.LeftJoint ~= nil and doRotate then
				local x, y, z = getRotation(self.componentJoints[3].jointNode);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.LeftJoint.maxRot, self.LeftJoint.minRot, 3, self.LeftJoint.rotTime, dt, not self.LeftJointMax);
				setRotation(self.componentJoints[3].jointNode,unpack(newRot));
			end;				

	
		local nearestDistance = 1; 
		local px, py, pz = getWorldTranslation(self.LeftDetector); 
		local vx, vy, vz = getWorldTranslation(self.LeftPart);
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);	
		if distance < nearestDistance then
			self.LeftJointMin = true;
			self.LeftJointMax = false;
		end;
		local x, y, z = getRotation(self.componentJoints[3].jointNode);
		local minRot = self.LeftJoint.minRot;
		local eps = self.LeftJoint.touchRotLimit;
		if  (math.abs(y-minRot[2]) < eps) then
			setJointRotationLimit(self.componentJoints[3].jointIndex, 1, true, math.rad(-0), math.rad(0));
		end;		
		
	
		local qx, qy, qz = getWorldTranslation(self.RightDetector); 
		local ux, uy, uz = getWorldTranslation(self.RightPart);
		local distance2 = Utils.vector3Length(qx-ux, qy-uy, qz-uz);	
		if distance2 < nearestDistance then
			self.RightJointMin = true;
			self.RightJointMax = false;
			self.CrochetsMax = false;
			self.CrochetsMin = true;
		end;
		local x, y, z = getRotation(self.componentJoints[2].jointNode);
		local minRot = self.RightJoint.minRot;
		local eps = self.RightJoint.touchRotLimit;
		if  (math.abs(y-minRot[2]) < eps) then
			setJointRotationLimit(self.componentJoints[2].jointIndex, 1, true, math.rad(-0), math.rad(0));
		end;		

			setJointFrame(self.componentJoints[2].jointIndex, 1,self.componentJoints[2].jointNode);
			setJointFrame(self.componentJoints[3].jointIndex, 1,self.componentJoints[3].jointNode);	
		

		
			for i=1, table.getn(self.hydraulics) do
				local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
				local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
				local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);
			
				setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
				local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
				if self.hydraulics[i].doScale then
					local xScale, yScale, zScale = getScale(self.hydraulics[i].punch);
					local newScale = yScale * (distance / self.hydraulics[i].punchDistance);
					setScale(self.hydraulics[i].punch, 1, 1, newScale);
				else
					if self.hydraulics[i].punch ~= nil then
						setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
					else
						setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
					end;
				end;
			end;
			

			if self.CarrierIsDown then
				for i=1, self.numRollers do
					local Roller = self.Rollers[i];
					rotate(Roller, 2.5 * self.lastSpeedReal * self.movingDirection * dt ,0,0);
				end;
				if self.cultivatorSound ~= nil and not self.cultivatorSoundEnabled and self:getIsActiveForSound() then
					if self.lastSpeed*3600 > 1 then
						playSample(self.cultivatorSound, 0, self.cultivatorSoundVolume, 0);
						setSamplePitch(self.cultivatorSound, self.cultivatorSoundPitchOffset);
						self.cultivatorSoundEnabled = true;
					end;
				end;
			else
				if self.cultivatorSoundEnabled then
					stopSample(self.cultivatorSound);
					self.cultivatorSoundEnabled = false;
				end;				
			end;
			if self.cultivatorSoundEnabled then
				if self.lastSpeed*3600 < 1 then
					stopSample(self.cultivatorSound);
					self.cultivatorSoundEnabled = false;
				end;
			end;			
			if InputBinding.hasEvent(InputBinding.CARRIERSUPPORT)  then
				self.SupportAttacherMax = not self.SupportAttacherMax;
				self.SupportFrameMax = not self.SupportFrameMax;
			end;			
			
			local doTranslate = self.SupportAttacherMax or self.SupportAttacherMin or not self.SupportAttacherMax
			if self.SupportAttacher ~= nil and doTranslate then	
				local x, y, z = getTranslation(self.SupportAttacher.node);
				local trans = {x,y,z};
				local newTrans = Utils.getMovedLimitedValues(trans, self.SupportAttacher.maxTrans, self.SupportAttacher.minTrans, 3, self.SupportAttacher.transTime, dt, not self.SupportAttacherMax);
				setTranslation(self.SupportAttacher.node, unpack(newTrans));
			end;
			local doRotate = self.SupportFrameMax or self.SupportFrameMin or not self.SupportFrameMax
			if self.SupportFrame ~= nil and doRotate then	
				local x, y, z = getRotation(self.SupportFrame.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.SupportFrame.maxRot, self.SupportFrame.minRot, 3, self.SupportFrame.rotTime, dt, not self.SupportFrameMax);
				setRotation(self.SupportFrame.node, unpack(newRot));
			end;
			setJointFrame(self.componentJoints[4].jointIndex, 1,self.componentJoints[4].jointNode);			
		end;
	end;	
end;

function BZP15_2:draw()
	g_currentMission:addExtraPrintText(string.format("Open/Close BZP-15_2  %s/%s:", InputBinding.getKeyNamesOfDigitalAction(InputBinding.CARRIERWORKMODEOFF), InputBinding.getKeyNamesOfDigitalAction(InputBinding.CARRIERWORKMODEON)));
    g_currentMission:addExtraPrintText(string.format("Support Open/Close %s", InputBinding.getKeyNamesOfDigitalAction(InputBinding.CARRIERSUPPORT)));		
end;

function BZP15_2:onDetach()

end;

function BZP15_2:onAttach()
end; 
function BZP15_2:onLeave()

end;

function BZP15_2:onActivate()
end;

function BZP15_2:onDeactivate()

end;

function BZP15_2:CarrierWorkingTime(diffTime)

end; 



