-- by modelleicher
-- www.schwabenmodding.bplaced.net


FahrM66T = {};

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

function FahrM66T:load(xmlFile)
	self.setWorkState = FahrM66T.setWorkState; -- self:setWorkState(state) -- state integer 0 = transport 1 = work 2 work with wide "deichsel"
	self.doRot = FahrM66T.doRot; -- self:doRot(index, rotX, rotY, rotZ, doRotJoint, jointNumber)
	
	self.kd = {}; -- Knickdeichsel (folding attacher)
	self.kd.jointNr = getXMLInt(xmlFile, "vehicle.FahrM66T#jointNummer");
	self.kd.maxRot = getXMLFloat(xmlFile, "vehicle.FahrM66T#maxRotNormal");
	self.kd.maxRot2 = getXMLFloat(xmlFile, "vehicle.FahrM66T#maxRotBreit");
	self.kd.minRot = getXMLFloat(xmlFile, "vehicle.FahrM66T#minRot");
	self.kd.curRot = self.kd.minRot;
	
	self.kd.state = 0; -- state integer 0 = transport 1 = work 2 work with wide "deichsel"
	self.kd.doMove = true;


	self.kk = {} -- Kornklappe (graintank lid)
	self.kk.minRot = getXMLFloat(xmlFile, "vehicle.FahrM66T.KorntankKlappe#minRot");
	self.kk.maxRot = getXMLFloat(xmlFile, "vehicle.FahrM66T.KorntankKlappe#maxRot");
	self.kk.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.FahrM66T.KorntankKlappe#index"));
	self.kk.state = false; -- false = closed, true  = open
	self.kk.doMove = true;
	self.kk.curRot = self.kk.minRot;
	
	self.doRotCheckAfterLoad = true;
end;

function FahrM66T:delete()
end;
function FahrM66T:mouseEvent(posX, posY, isDown, isUp, button)
end;
function FahrM66T:keyEvent(unicode, sym, modifier, isDown)
end;
function FahrM66T:readStream(streamId, connection)  
     self:setWorkState(streamReadInt32(streamId), true);  
end;
function FahrM66T:writeStream(streamId, connection)  
    streamWriteInt32(streamId, self.kd.state );  
end;
function FahrM66T:doRot(index, rotX, rotY, rotZ, doRotJoint, jointNumber)
	if doRotJoint == true then
		local jointNode = self.componentJoints[jointNumber].jointNode;
		local jointIndex = self.componentJoints[jointNumber].jointIndex;
		setRotation(jointNode, Utils.degToRad(rotX), Utils.degToRad(rotY), Utils.degToRad(rotZ));
		setJointFrame(jointIndex, 1, jointNode);		
	end;
	if index ~= nil then
		setRotation(index, Utils.degToRad(rotX), Utils.degToRad(rotY), Utils.degToRad(rotZ));
	end;
end;
function FahrM66T:setWorkState(state, noEventSend)
	setWorkStateEvent.sendEvent(self, state, noEventSend)
	if state == 0 then
		self.kd.state = 0;
		self.kd.doMove = true;
		self.kk.state = false;
		self.kk.doMove = true;
	elseif state == 1 then
		self.kd.state = 1;
		self.kd.doMove = true;
		self.kk.state = true;
		self.kk.doMove = true;
	elseif state == 2 then
		self.kd.state = 2;
		self.kd.doMove = true;
		self.kk.state = true;
		self.kk.doMove = true;	
	end;
end;
function FahrM66T:update(dt)
	if self.doCheckAfterLoad then
		self:doRot(nil, 0, self.kd.curRot, 0, true, self.kd.jointNr)
		self:doRot(self.kk.index, self.kk.curRot, 0, 0, false)
		self.doCheckAfterLoad = nil;

	end;

	-- keyevents
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.WorkTransport) then 
			if self.kd.state == 0 then
				self:setWorkState(1)
			else
				self:setWorkState(0)
			end;
		end;		
		if InputBinding.hasEvent(InputBinding.WideWorkmode) then 
			if self.kd.state == 0 or self.kd.state == 1 then
				self:setWorkState(2)
			else
				self:setWorkState(1)
			end;
		end;	
	end;

	if self:getIsActive() then	
		if self.kd.doMove then
			if self.kd.state == 0 then  -- goal = minRot
				if self.kd.minRot < self.kd.maxRot and self.kd.curRot > self.kd.minRot then
					self.kd.curRot = math.max(self.kd.curRot - dt*0.01, self.kd.minRot);
				elseif self.kd.minRot > self.kd.maxRot and self.kd.curRot < self.kd.minRot then
					self.kd.curRot = math.min(self.kd.curRot + dt*0.01, self.kd.minRot);
				end;
				if self.kd.curRot == self.kd.minRot then
					self.kd.doMove = false;
				end;
			elseif self.kd.state == 1 then -- goal = maxRot
				if self.kd.minRot < self.kd.maxRot then
					if self.kd.curRot < self.kd.maxRot then
						self.kd.curRot = math.min(self.kd.curRot + dt*0.01, self.kd.maxRot);
					elseif self.kd.curRot > self.kd.maxRot then
						self.kd.curRot = math.max(self.kd.curRot - dt*0.01, self.kd.maxRot);
					end;
				elseif self.kd.minRot > self.kd.maxRot then
					if self.kd.curRot > self.kd.maxRot then
						self.kd.curRot = math.max(self.kd.curRot - dt*0.01, self.kd.maxRot);
					elseif self.kd.curRot < self.kd.maxRot then
						self.kd.curRot = math.min(self.kd.curRot + dt*0.01, self.kd.maxRot);
					end;			
				end;
				if self.kd.curRot == self.kd.maxRot then
					self.kd.doMove = false;
				end;				
			elseif self.kd.state == 2 then -- goal = maxRot2
				if self.kd.minRot < self.kd.maxRot and self.kd.curRot < self.kd.maxRot2 then
					self.kd.curRot = math.min(self.kd.curRot + dt*0.01, self.kd.maxRot2);
				elseif self.kd.minRot > self.kd.maxRot and self.kd.curRot > self.kd.maxRot2 then
					self.kd.curRot = math.max(self.kd.curRot - dt*0.01, self.kd.maxRot2);
				end;
				if self.kd.curRot == self.kd.maxRot2 then
					self.kd.doMove = false;
				end;					
			end;
			self:doRot(nil, 0, self.kd.curRot, 0, true, self.kd.jointNr)		
		end;
		
		if self.kk.doMove then
			-- towards maxrot
			if self.kk.state then
				if self.kk.minRot < self.kk.maxRot and self.kk.curRot < self.kk.maxRot then -- pos
					self.kk.curRot = math.min(self.kk.curRot + dt*0.005, self.kk.maxRot);
				elseif self.kk.minRot > self.kk.maxRot and self.kk.curRot > self.kk.maxRot then
					self.kk.curRot = math.max(self.kk.curRot - dt*0.005, self.kk.minRot);
				else
					self.kk.doMove = false;
				end;
				-- towards minRot
			elseif not self.kk.state then
				if self.kk.minRot < self.kk.maxRot and self.kk.curRot > self.kk.minRot then
					self.kk.curRot = math.max(self.kk.curRot - dt*0.005, self.kk.minRot);
				elseif self.kk.minRot > self.kk.maxRot and self.kk.curRot < self.kk.minRot then
					self.kk.curRot = math.min(self.kk.curRot + dt*0.005, self.kk.minRot);
				else
					self.kk.doMove = false;
				end;
			end;
			self:doRot(self.kk.index, self.kk.curRot, 0, 0, false);
		end;
	end;
	

end;

function FahrM66T:draw()
	if self:getIsActiveForInput() then
		g_currentMission:addHelpButtonText(g_i18n:getText("WorkTransport"), InputBinding.WorkTransport);
		g_currentMission:addHelpButtonText(g_i18n:getText("WideWorkmode"), InputBinding.WideWorkmode);
	end;
end;


setWorkStateEvent = {};
setWorkStateEvent_mt = Class(setWorkStateEvent, Event);
InitEventClass(setWorkStateEvent, "setWorkStateEvent");

function setWorkStateEvent:emptyNew()  
    local self = Event:new(setWorkStateEvent_mt );
    self.className="setWorkStateEvent";
    return self;
end;
function setWorkStateEvent:new(vehicle, state) 
    self.vehicle = vehicle;
    self.state = state;
    return self;
end;
function setWorkStateEvent:readStream(streamId, connection)  
    local id = streamReadInt32(streamId); 
    self.state = streamReadInt32(streamId); 
    self.vehicle = networkGetObject(id); 
    self:run(connection);  
end;
function setWorkStateEvent:writeStream(streamId, connection)   
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));	
    streamWriteInt32(streamId, self.state );   
end;
function setWorkStateEvent:run(connection) 
    self.vehicle:setWorkState(self.state, true);
	if not connection:getIsServer() then  
		g_server:broadcastEvent(setWorkStateEvent:new(self.vehicle, self.state), nil, connection, self.object);
	end;
end;
function setWorkStateEvent.sendEvent(vehicle, state, noEventSend)  
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then   
			g_server:broadcastEvent(setWorkStateEvent:new(vehicle, state), nil, nil, vehicle);
		else 
			g_client:getServerConnection():sendEvent(setWorkStateEvent:new(vehicle, state));
		end;
	end;
end;
