--
-- HorschPronto6AS
-- Specialization for HorschPronto6AS
--
-- @author Felix "Outlaw" Sorge
-- @date  26/12/09
-- @web www.ls-modsource.de - www.ls-mods.de
--
-- Copyright (C) Outlaw, All Rights Reserved.
-- Multiplayer Ready Hummel - modhoster.de

--source("dataS/scripts/vehicles/specializations/SowingMachineAreaEvent.lua");

HorschPronto6AS = {};

Vehicle.registerJointType("horschImplement");

function HorschPronto6AS.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Trailer, specializations);
end;

function HorschPronto6AS:load(xmlFile)
	self.setStateEvent= SpecializationUtil.callSpecializationsFunction("setStateEvent");
	self.setJointRotLimit = SpecializationUtil.callSpecializationsFunction("setJointRotLimit");
	
	self.arm2 = {};
	self.arm2.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherJoint#index"));
	self.arm2.currentRotLimit = {0};
	
	
	self.seedPerSqm = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.seedPerSqm#value"), 1);
	self.horschAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.attacherJoint#index"));
	
	self.firstDo = {};
	self.arm = {};
	
	self.Done = {};
	self.Go = {};
	self.Speed = {};
	self.CheckDone = {};
	
	self.turnOn = false;
	self.Go.spurlinks = false;
	self.Go.spurrechts = false;
	self.Go.trsp = false;
	
	self.Done.spurlinks = false;
	self.Done.spurrechts = false;
	self.Done.trsp = false;
	
	self.CheckDone.trsp = false;
	self.CheckDone.down = false;
	
	self.markWheel = false;
	
	
	self.realUpdateSteeringAxle = HorschPronto6AS.empty;
	self.realToolHasGroundContact = false;
end;

function HorschPronto6AS:empty()
end;

function HorschPronto6AS:readStream(streamId, connection)  
	self.turnOn = streamReadBool(streamId);
	self.markWheel = streamReadBool(streamId);
	
 	self.Speed.trsp = streamReadFloat32(streamId);
	self.Go.trsp = streamReadBool(streamId);
	self.Done.trsp = streamReadBool(streamId);
	
	self.Speed.spurlinks = streamReadFloat32(streamId);
	self.Go.spurlinks = streamReadBool(streamId);
	self.Done.spurlinks = streamReadBool(streamId);
	
	self.Speed.spurrechts = streamReadFloat32(streamId);
	self.Go.spurrechts = streamReadBool(streamId);
	self.Done.spurrechts = streamReadBool(streamId);
	
	
end;

function HorschPronto6AS:writeStream(streamId, connection)
	streamWriteBool(streamId, self.turnOn);
    streamWriteBool(streamId, self.markWheel);
	
	streamWriteFloat32(streamId, self.Speed.trsp)
	streamWriteBool(streamId, self.Go.trsp);   
	streamWriteBool(streamId, self.Done.trsp);
	
	streamWriteFloat32(streamId, self.Speed.spurlinks)
	streamWriteBool(streamId, self.Go.spurlinks);   
	streamWriteBool(streamId, self.Done.spurlinks);
	
	streamWriteFloat32(streamId, self.Speed.spurrechts)
	streamWriteBool(streamId, self.Go.spurrechts);   
	streamWriteBool(streamId, self.Done.spurrechts);
end;



function HorschPronto6AS:update(dt)

	if self.isClient then
		--manage back lights
		local doBackLight = false;
		local rootAttacherVehicle = self:getRootAttacherVehicle();
		if rootAttacherVehicle ~= nil then
			if rootAttacherVehicle.lightsState~= nil then
				if rootAttacherVehicle.lightsState > 0 then
					doBackLight = true;					
				end;
			end;
		end;
		
		for _,light in pairs(self.lights) do
			setVisibility(light.realLight,doBackLight)
		end;		
	end;

	if self.attacherVehicle then
		self.realToolHasGroundContact = false;	
		if InputBinding.hasEvent(InputBinding.HorschPronto6AS_spurlinks) and self.attacherVehicle:getIsActiveForInput() then			
			self:setStateEvent("Speed", "spurlinks", 2.8)
			self:setStateEvent("Go", "spurlinks", not self.Go.spurlinks)
			self:setStateEvent("Done", "spurlinks", true)
		end; 
		
		if InputBinding.hasEvent(InputBinding.HorschPronto6AS_spurchange) and self.attacherVehicle:getIsActiveForInput() and (self.Go.spurlinks or self.Go.spurrechts) then
			self:setStateEvent("Speed", "spurlinks", 2.8)
			self:setStateEvent("Speed", "spurrechts", 2.8)
			
			if self.Go.spurlinks then
				self:setStateEvent("Go", "spurlinks", false)
				self:setStateEvent("Done", "spurlinks", true)
				self:setStateEvent("Go", "spurrechts", true)
				self:setStateEvent("Done", "spurrechts", true)
			else
				self:setStateEvent("Go", "spurlinks", true)
				self:setStateEvent("Done", "spurlinks", true)
				self:setStateEvent("Go", "spurrechts", false)
				self:setStateEvent("Done", "spurrechts", true)
			end; 
		end; 
		
		if InputBinding.hasEvent(InputBinding.HorschPronto6AS_spurrechts) and self.attacherVehicle:getIsActiveForInput() then
			self:setStateEvent("Speed", "spurrechts", 2.8)
			self:setStateEvent("Go", "spurrechts", not self.Go.spurrechts)
			self:setStateEvent("Done", "spurrechts", true)
		end; 
	
		--if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2)  and self.attacherVehicle:getIsActiveForInput() and not self.attacherVehicle.Go.down and not self.attacherVehicle.CheckDone.down and not self.attacherVehicle.Done.down and not self.attacherVehicle.turnOn then
		if not self.attacherVehicle.Go.down and not self.attacherVehicle.CheckDone.down and not self.attacherVehicle.Done.down and not self.attacherVehicle.turnOn then
			if self.Go.trsp ~= self.attacherVehicle.Go.trsp then
				self:setStateEvent("Speed", "trsp", 1.0)			
				self:setStateEvent("Go", "trsp", not self.Go.trsp)
				self:setStateEvent("Done", "trsp", true)
				self:setStateEvent("Speed", "spurlinks", 2.8)
				self:setStateEvent("Speed", "spurrechts", 2.8)
				self:setStateEvent("Go", "spurlinks", false)
				self:setStateEvent("Done", "spurlinks", true)
				self:setStateEvent("Go", "spurrechts", false)
				self:setStateEvent("Done", "spurrechts", true)
			end;
		end; 
	
		-- if InputBinding.hasEvent(InputBinding.HorschPronto6AS_on)  and self.attacherVehicle:getIsActiveForInput() and self.CheckDone.trsp and self.Go.trsp then
			-- self:setStateEvent("turnOn", false, not self.turnOn)		
		-- end; 
		
		if InputBinding.hasEvent(InputBinding.HorschPronto6AS_markWheel)  and self.attacherVehicle:getIsActiveForInput() and self.CheckDone.trsp and self.Go.trsp then
			self:setStateEvent("markWheel", false, not self.markWheel)	
		end; 
					
		if self.attacherVehicle:getIsActiveForInput() and InputBinding.hasEvent(InputBinding.HorschPronto6AS_spurup) then
			self:setStateEvent("Go", "spurlinks", false)
			self:setStateEvent("Done", "spurlinks", true)
			self:setStateEvent("Go", "spurrechts", false)
			self:setStateEvent("Done", "spurrechts", true)
			self:setStateEvent("Speed", "spurlinks", 2.8)
			self:setStateEvent("Speed", "spurrechts", 2.8)
		end; 		
		
		
		if self.CheckDone.trsp then
			if self.attacherVehicle.Go.down and not self.attacherVehicle.Done.down and self.attacherVehicle.CheckDone.down  then
			
					local x,y,z = getWorldTranslation(self.cuttingAreas[1].start);
					local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[1].width);
					local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[1].height);
					
					--insert angle
					local dx,dy,dz = localDirectionToWorld(self.rootNode, 0, 0, 1);
 
                    local angleRad = Utils.getYRotationFromDirection(dx, dz)
					local fruitType = FruitUtil.fillTypeToFruitType[self.attacherVehicle.currentFillType]
                    local desc = FruitUtil.fruitIndexToDesc[fruitType];
                    if desc ~= nil and desc.directionSnapAngle ~= 0 then
                        angleRad = math.floor(angleRad / desc.directionSnapAngle + 0.5) * desc.directionSnapAngle;
                    end
 
                    local angle = Utils.convertToDensityMapAngle(angleRad, g_currentMission.terrainDetailAngleMaxValue);
					--end angle
			
				if self.Go.spurlinks and not self.Done.spurlinks and self.CheckDone.spurlinks then
					local x,y,z = getWorldTranslation(self.cuttingAreas[4].start);
					local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[4].width);
					local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[4].height);
					local xg,yg,zg = getWorldTranslation(self.cuttingAreas[7].start);
					local x1g,y1g,z1g = getWorldTranslation(self.cuttingAreas[7].width);
					local x2g,y2g,z2g = getWorldTranslation(self.cuttingAreas[7].height);
					local cultivator = Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.cultivatorChannel, xg, zg, x1g, z1g, x2g, z2g);
					if cultivator ~= 0 then
						Utils.updatePloughArea(x, z, x1, z1, x2, z2,false,false,angle);
					else
						Utils.updateCultivatorArea(x, z, x1, z1, x2, z2,false,false,angle);	
					end; 
					self.realToolHasGroundContact = true;
				end;
				
				if self.Go.spurrechts and not self.Done.spurrechts and self.CheckDone.spurrechts then
					local x,y,z = getWorldTranslation(self.cuttingAreas[5].start);
					local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[5].width);
					local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[5].height);
					local xg,yg,zg = getWorldTranslation(self.cuttingAreas[6].start);
					local x1g,y1g,z1g = getWorldTranslation(self.cuttingAreas[6].width);
					local x2g,y2g,z2g = getWorldTranslation(self.cuttingAreas[6].height);
					local cultivator = Utils.getDensity(g_currentMission.terrainDetailId, g_currentMission.cultivatorChannel, xg, zg, x1g, z1g, x2g, z2g);
					if cultivator ~= 0 then
						Utils.updatePloughArea(x, z, x1, z1, x2, z2,false,false,angle);
					else
						Utils.updateCultivatorArea(x, z, x1, z1, x2, z2,false,false,angle);	
					end; 
					self.realToolHasGroundContact = true;
				end;
				
				if self.attacherVehicle.turnOn  and self.attacherVehicle.fillLevel ~= 0 then
					
	
					
					local fruitType = FruitUtil.fillTypeToFruitType[self.attacherVehicle.currentFillType]
					local area, densityAreaI = Utils.updateSowingArea(fruitType, x, z, x1, z1, x2, z2,angle,false);
					self.realToolHasGroundContact = true;
					
					--local area = 1000;
					--local area, detailArea = SowingMachineAreaEvent.runLocally(self.cuttingAreas[1], self.attacherVehicle.currentFillType, 0, true)
					
					
					
					
					local fruitDesc = FruitUtil.fruitIndexToDesc[fruitType];
					local pixelToSqm = g_currentMission:getFruitPixelsToSqm(); -- 8192px are mapped to 2048m
					local sqm = area*pixelToSqm;
					local ha = sqm/10000;
					local usage = Utils.getNoNil(fruitDesc.seedUsagePerSqm,0.2)*sqm;
					local deltaLevel = usage;
					
					
					-- local difficultyMultiplier = math.max(3 * (3 - g_currentMission.missionStats.difficulty), 1);
					-- local deltaLevel = FruitUtil.fruitIndexToDesc[fruitType].literPerSqm * difficultyMultiplier * usage * self.seedPerSqm;					
					self.attacherVehicle:setFillLevel(self.attacherVehicle.fillLevel-deltaLevel, self.attacherVehicle.currentFillType);			
					g_currentMission.missionStats.seedUsageTotal = g_currentMission.missionStats.seedUsageTotal + usage;
					g_currentMission.missionStats.seedUsageSession = g_currentMission.missionStats.seedUsageSession + usage;
					g_currentMission.missionStats.hectaresSeededTotal = g_currentMission.missionStats.hectaresSeededTotal + ha;
					g_currentMission.missionStats.hectaresSeededSession = g_currentMission.missionStats.hectaresSeededSession + ha;
					-- local seedPrice = fruitDesc.seedPricePerLiter*usage;
					-- g_currentMission.missionStats.expensesTotal = g_currentMission.missionStats.expensesTotal + seedPrice;
					-- g_currentMission.missionStats.expensesSession = g_currentMission.missionStats.expensesSession + seedPrice;
					-- g_currentMission.missionStats.money = g_currentMission.missionStats.money - seedPrice;		 
					-- g_currentMission.missionStats.seedingDurationTotal = g_currentMission.missionStats.seedingDurationTotal + dt/(1000*60);
					-- g_currentMission.missionStats.seedingDurationSession = g_currentMission.missionStats.seedingDurationSession + dt/(1000*60);
				end; 	
				
					
				if self.markWheel then
					local x,y,z = getWorldTranslation(self.cuttingAreas[2].start);
					local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[2].width);
					local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[2].height);		
					Utils.updateCultivatorArea(x, z, x1, z1, x2, z2,false,false,angle);					
					local x,y,z = getWorldTranslation(self.cuttingAreas[3].start);
					local x1,y1,z1 = getWorldTranslation(self.cuttingAreas[3].width);
					local x2,y2,z2 = getWorldTranslation(self.cuttingAreas[3].height);
					Utils.updateCultivatorArea(x, z, x1, z1, x2, z2,false,false,angle);					
				end;

					
            end;
					
			
			x, y, z = getRotation(self.arm2.node);
			rot = {x,y,z};	
			local newRotLimit = {0,0,0};
			local rotDown = {30};
			local rotUp = {0};
			newRotLimit = Utils.getMovedLimitedValues(self.arm2.currentRotLimit, rotDown, rotUp, 1, 1000 * 2, dt, not self.attacherVehicle.Go.down);
			if math.abs(newRotLimit[1] - self.arm2.currentRotLimit[1]) > 0.001 then
				setJointRotationLimit(self.attacherVehicle.horschImplement.ObjectIndex, 0, true, Utils.degToRad(-newRotLimit[1]), Utils.degToRad(newRotLimit[1]));
			end;
			self.arm2.currentRotLimit = newRotLimit;	
			
			
			
			if not self.attacherVehicle.Go.down then
				self:onBrake(); 
			end;
		end;
					
						
					
		if self.Go.trsp then
			self.attacherVehicle.blockDetach = true; 
		elseif not self.Go.trsp and not self.Done.trsp and not self.CheckDone.trsp then
			self.attacherVehicle.blockDetach = false; 
		end; 
				
		if self.attacherVehicle.lightsActive then
			self:setLightsVisibility(true); 
		else
			self:setLightsVisibility(false); 
		end;
				
		if self.Go.spurlinks ~= nil and self.Done.spurlinks ~= false then
			self:anim("spurlinks", false); 
		end; 
		
		if self.Go.spurrechts ~= nil and self.Done.spurrechts ~= false then
			self:anim("spurrechts", false); 
		end; 
		
		
		if self.attacherVehicle.Go.down then

			self:setJointRotLimit(self.componentJoints[3],20, 0, 1000, not self.Go.spurlinks, 2,dt);	
			self:setJointRotLimit(self.componentJoints[5],20, 0, 1000, not self.Go.spurrechts, 2,dt);
				
		end; 	
		
		
		--draw start
		if self.attacherVehicle:getIsActiveForInput() then
		
			if self.markWheel and self.Go.trsp and self.CheckDone.trsp and not self.Done.trsp then
				g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_4"), InputBinding.HorschPronto6AS_markWheel); 
			elseif not self.markWheel and self.Go.trsp and self.CheckDone.trsp and not self.Done.trsp then
				g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_3"), InputBinding.HorschPronto6AS_markWheel); 
			end; 

	
			if self.Go.trsp and self.CheckDone.trsp and not self.Done.trsp then
		
				if self.Go.spurlinks then
					g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_6"), InputBinding.HorschPronto6AS_spurlinks); 
				else
					g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_5"), InputBinding.HorschPronto6AS_spurlinks); 
				end; 
			
			
				if self.Go.spurrechts then
					g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_8"), InputBinding.HorschPronto6AS_spurrechts); 
				else
					g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_7"), InputBinding.HorschPronto6AS_spurrechts); 
				end; 
			
				g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_9"), InputBinding.HorschPronto6AS_spurup); 
			
				if self.Go.spurrechts or self.Go.spurlinks then
					g_currentMission:addHelpButtonText(g_i18n:getText("HorschPronto6AS_10"), InputBinding.HorschPronto6AS_spurchange); 
				end; 
			end;
			
		end; 
		--draw end
		
	-- end active	
	end;
	
		
	local joint = self.componentJoints[3];
	setJointFrame(joint.jointIndex, 0,joint.jointNode);
	local joint = self.componentJoints[4];
	setJointFrame(joint.jointIndex, 0,joint.jointNode);
	local joint = self.componentJoints[5];
	setJointFrame(joint.jointIndex, 0,joint.jointNode);
	local joint = self.componentJoints[6];
	setJointFrame(joint.jointIndex, 0,joint.jointNode);
	
	
	if self.Done.trsp then
		local joint = self.componentJoints[1];
		setJointFrame(joint.jointIndex, 0,joint.jointNode);
		local joint = self.componentJoints[2];
		setJointFrame(joint.jointIndex, 0,joint.jointNode);
	end;	


	if self.Go.trsp ~= nil and self.Done.trsp ~= false then
		self:anim("trsp", false); 
	end; 
	

end;

function HorschPronto6AS:delete()
	if self.attacherVehicle then
		self.attacherVehicle.horschImplement = {}; 
	end; 
end;


function HorschPronto6AS:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	--if not resetVehicles then
	--	local trsp = getXMLBool(xmlFile, key.."#trsp");
	--	if trsp then
	--		self.Go.trsp = not self.Go.trsp; 
	--		self.Done.trsp = true; 
	--		self.Speed.trsp = 100.0;
	--	end; 
	--end; 
    return BaseMission.VEHICLE_LOAD_OK;
end;

function HorschPronto6AS:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'trsp="'..tostring(self.CheckDone.trsp)..'"'; 
	return attributes, nil;
end;

function HorschPronto6AS:setJointRotLimit(nodei, up, down, speed, value, axle, dt)
	if not self.firstDo[nodei] then
		self.firstDo[nodei] = true;
		self.arm[nodei] = {0}; 
	end; 
	x, y, z = getRotation(nodei);
	rot = {x,y,z};	
	newRotLimit = {}; 
	newRotLimit[nodei] = {0,0,0};
	newRotLimit[nodei] = Utils.getMovedLimitedValues(self.arm[nodei], {down}, {up}, 1, speed * 2, dt, value);
	if math.abs(newRotLimit[nodei][1] - self.arm[nodei][1]) > 0.001 then
		local joint = nodei;
		setJointRotationLimit(joint.jointIndex, axle, true, Utils.degToRad(-newRotLimit[nodei][1]), Utils.degToRad(newRotLimit[nodei][1]));
	end;
	self.arm[nodei] = newRotLimit[nodei];			
end; 

function HorschPronto6AS:onDetach()
end;

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

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

function HorschPronto6AS:onAttach()
end; 	

function HorschPronto6AS:draw()		
end;



function HorschPronto6AS:setStateEvent(level1, level2, value, noEventSend)
	
    if value== true then
      value = "true"
    elseif value==false then
      value = "false"
    elseif value ~= "true" and value ~= "false" then
      value = string.format("%f", value)
    end
	
	if level2== true then
      level2 = "true"
    elseif level2==false then
      level2 = "false"
    end
	
	HorschPronto6ASEvent.sendEvent(self, level1, level2, value, noEventSend);
    	
	if value== "true" then
      value = true
    elseif value=="false" then
      value = false
    elseif value ~= true and value ~= false then
      value = value * 1.0
    end
	
	if level2 == "false" then
	  self[level1] = value;
	else
      self[level1][level2] = value;
	end
end;


HorschPronto6ASEvent = {};
HorschPronto6ASEvent_mt = Class(HorschPronto6ASEvent, Event);

InitEventClass(HorschPronto6ASEvent, "HorschPronto6ASEvent");

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

function HorschPronto6ASEvent:new(object, level1, level2, value) 
    self.object = object;
    self.level1 = level1;
    self.level2 = level2;
    self.value = value;

    return self;
end;

function HorschPronto6ASEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.level1 = streamReadString(streamId);
    self.level2 = streamReadString(streamId);
    self.value = streamReadString(streamId);
    self.object = networkGetObject(id);
    self:run(connection);
end;

function HorschPronto6ASEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
    streamWriteString(streamId, self.level1 );
    streamWriteString(streamId, self.level2 );
    streamWriteString(streamId, self.value );
end;

function HorschPronto6ASEvent:run(connection)
    self.object:setStateEvent(self.level1, self.level2, self.value, true);
    if not connection:getIsServer() then  
      g_server:broadcastEvent(HorschPronto6ASEvent:new(self.object, self.level1, self.level2, self.value), nil, connection, self.object);
    end;
end;

function HorschPronto6ASEvent.sendEvent(object, level1, level2, value, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then 
			g_server:broadcastEvent(HorschPronto6ASEvent:new(object, level1, level2, value), nil, nil, object);
		else
			g_client:getServerConnection():sendEvent(HorschPronto6ASEvent:new(object, level1, level2, value));
		end;
	end;
end;