
---xyzspain 2014




WrapperRoundBale = {};

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

function WrapperRoundBale:load(xmlFile)




	
	 

-- Specialization for wrapper mod
--
-- @author  JoXXer
-- @date  2011/01/09
	 
	 -- Wickler
-- Specialization zum automatischen wickeln
--
-- @author  teiger
-- @date  14/10/2011

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


	self.setBalesVisibility = SpecializationUtil.callSpecializationsFunction("setBalesVisibility");
	self.setResetActiveBale = SpecializationUtil.callSpecializationsFunction("setResetActiveBale");
	self.createBale = SpecializationUtil.callSpecializationsFunction("createBale");
	self.dropBale = SpecializationUtil.callSpecializationsFunction("dropBale");


	

	
	-- Static Bales --
	self.numStaticBales = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.staticBales#count"), 0);	
	self.staticBales = {};
	for i=1, self.numStaticBales do
        local baleNamei = string.format("vehicle.staticBales.staticBale" .. "%d", i);
        self.staticBales[i] = Utils.indexToObject(self.components, getXMLString(xmlFile, baleNamei .. "#index"));
    end;
	
	
	
	-- Bale wrappingTable attacher --
	self.searchTableBales = WrapperRoundBale.searchTableBales;
	self.attachTableObjects = WrapperRoundBale.attachTableObjects;
	self.detachTableObjects = WrapperRoundBale.detachTableObjects;
	
	
	self.isBaleInTableRange = WrapperRoundBale.isBaleInTableRange;
	self.tablePlace = {};
	self.tablePlace.node1 = Utils.indexToObject(self.components, getXMLString(xmlFile,"vehicle.Wrappingtable#castPoint1"));		
	self.tablePlace.node2 = Utils.indexToObject(self.components, getXMLString(xmlFile,"vehicle.Wrappingtable#castPoint2"));
	self.tablePlace.attacherNode = Utils.indexToObject(self.components, Utils.getNoNil(getXMLString(xmlFile,"vehicle.Wrappingtable#attacherNode"),"0>16|0"));
	self.tablePlace.highOffset = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.Wrappingtable#highOffset"),10);	
	self.AttachedTableObjects = {};
	
	self.allowTableAttachment = true;
	self.balesOnTableAttached = false;
	self.baleCanBeWrapped = false;
	
	-- Animations --
	
	self.WrappingAnimation = getXMLString(xmlFile, "vehicle.WrappingTableWrapping#animationName");
	
	
	
	
	
	self.isUnloading = false;
	self.isWrapping = false;
		self.isReadyToUnload = false;
	 self.isReadyToLoad  = false;
	self.isBaleVisible = false;
	self.resetActiveBale = false;
	self.baleActive = 1;
	self.usedFruitType = 0;
	
	self.baleInRange = {};
	
	--create bale-stuff--
   self.baleTypes = {};
   local i = 0;
   while true do
       local key = string.format("vehicle.baleTypes.baleType(%d)", i);
       local t = getXMLString(xmlFile, key.."#fruitType");
       local filename = getXMLString(xmlFile, key.."#filename");
       if t==nil or filename==nil then
           break;
       end;
	   
	   local filenameFoil2 = Utils.getNoNil(getXMLString(xmlFile, key.."#filenameFoil2"),filename);

       local entry = {};
       entry.filename = filename;
	   entry.filenameFoil2 = filenameFoil2;
      
			
	   self.baleTypes[t] = entry;

	   if self.defaultBaleType == nil then
		   self.defaultBaleType = entry;
	   end;
       i = i +1;
   end;
   if self.defaultBaleType == nil then
       self.baleTypes = nil;
   end;


   self.bales = {};
   
   self.baleAnimRoot = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleAnimation#node")), "0>16|0");

   
   ------------------------------------attach bale in range error---------------------
   
	self.hayBale = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.hayBale#index"));	
	
	setVisibility(self.hayBale, false);

	self.strawBale = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.strawBale#index"));
	 
	setVisibility(self.strawBale, false);

	self.select=false;
	self.roll_left_up = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roll_left_up#index"));
	self.roll_left_down = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roll_left_down#index"));
	self.roll_right_up = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roll_right_up#index"));
	self.roll_right_down = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roll_right_down#index"));
	
	
	
	
	
	
	
	
end;

function WrapperRoundBale:delete()
	
	
end;



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

function WrapperRoundBale:keyEvent(unicode, sym, modifier, isDown)

end;



function WrapperRoundBale:getSaveAttributesAndNodes(nodeIdent)

end;

function WrapperRoundBale:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	
end;

function WrapperRoundBale:update(dt)
if self:getIsActiveForInput() then
	if InputBinding.isPressed(InputBinding.KUHN_SW_4004_1) then
			self:setAnimationTime(1, self.animationParts[1].currentPosition+(self.animationParts[1].offSet*(dt/10)));
		end;
		
		if InputBinding.isPressed(InputBinding.KUHN_SW_4004_2) then
			self:setAnimationTime(1, self.animationParts[1].currentPosition-(self.animationParts[1].offSet*(dt/10)));
		end;
		if self.animationParts[1].clipEndTime then
		self.isReadyToLoad =true;
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("KUHN_SW_4004_2")), InputBinding.KUHN_SW_4004_2);
				else
		self.isReadyToLoad =false;		
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("KUHN_SW_4004_1")), InputBinding.KUHN_SW_4004_1);
		end;
	
			
	
		
			
end;
	
		if self.isReadyToLoad  then
		
		
				self:searchTableBales();
				if self.baleCanBeWrapped then
				
					self.isWrapping = true;
					self:searchTableBales();
					self:setWrapping(true);
				end;
			end;
	
	
	
	
	
	
	
	
	
	-----------------------------------------
	
	
end;


	
function WrapperRoundBale:updateTick(dt)

	
	
	
	if self:getRealAnimationTime(self.WrappingAnimation)>= 29000 and self.isWrapping then

		
		self.isWrapping = false;
		
		
		self:setBalesVisibility(not self.isBaleVisible);
		 self:setResetActiveBale(not self.resetActiveBale);
		if self.baleTypes ~= nil then
			-- create bale
			--renderText(0.1, 0.16, 0.03," create bale ");
			self:createBale(self.usedFruitType);
			if g_server ~= nil then
				g_server:broadcastEvent(CreateBaleEvent:new(self, self.usedFruitType, 0), nil, nil, self);
			else
				g_client:getServerConnection():sendEvent(CreateBaleEvent:new(self, self.usedFruitType, 0));
			end;
		end;
		
	end;
	
	
		if table.getn(self.bales) > 0 then
			self:dropBale(1);
			if g_client ~= nil then
				g_client:getServerConnection():sendEvent(DropBaleEvent:new(self, 1, 0));
				self:setAnimationTime(1, 0);		
			end;
		end;
	
	
	if self.isWrapping then
	
		self.isReadyToUnload = false;
		
			if self:getRealAnimationTime(self.WrappingAnimation) > 0 and self:getRealAnimationTime(self.WrappingAnimation) <= 25000 then
			
				self:setAnimationTime(4, 1);
				
			end;
			if self:getRealAnimationTime(self.WrappingAnimation) > 0 and self:getRealAnimationTime(self.WrappingAnimation) <= 27500 then
			
				self:setAnimationTime(2, 1);
			
			end;	
		
		if self:getRealAnimationTime(self.WrappingAnimation) >= 1026 and getVisibility(self.staticBales[1]) == false and self.baleActive == 1 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 2500 and getVisibility(self.staticBales[2]) == false and self.baleActive == 2 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 5000 and getVisibility(self.staticBales[3]) == false and self.baleActive == 3 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 7500 and getVisibility(self.staticBales[4]) == false and  self.baleActive == 4 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 10000 and getVisibility(self.staticBales[5]) == false and  self.baleActive == 5 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 12500 and getVisibility(self.staticBales[6]) == false and self.baleActive == 6 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 15000 and getVisibility(self.staticBales[7]) == false and  self.baleActive == 7 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 17500 and getVisibility(self.staticBales[8]) == false and self.baleActive == 8 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 20000 and getVisibility(self.staticBales[9]) == false and self.baleActive == 9 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 22500 and getVisibility(self.staticBales[10]) == false and self.baleActive == 10 then
			self:setBalesVisibility(not self.isBaleVisible);
		elseif self:getRealAnimationTime(self.WrappingAnimation) >= 25000 and getVisibility(self.staticBales[11]) == false and self.baleActive == 11 then
			self:setBalesVisibility(not self.isBaleVisible);
				self:setAnimationTime(4, 0);
		
		end;
		
		--here starts new code for rotation
		
		local aTime = self:getRealAnimationTime(self.WrappingAnimation);
		
		if aTime < 25000 and aTime > 5000 then
			local baleRot = (aTime-5000)/20000/2.2*2*math.pi
		
			setRotation(self.hayBale,0,0,baleRot)
			setRotation(self.strawBale,0,0,baleRot)
			setRotation(self.roll_left_up,0,0,-(baleRot))
			setRotation(self.roll_left_down,0,0,-(baleRot))
			setRotation(self.roll_right_up,0,0,-(baleRot))
			setRotation(self.roll_right_down,0,0,-(baleRot))
			
			
			for k,bale in pairs(self.staticBales) do
				local rot = (aTime%2500-2500)/2500/22*2*math.pi
				setRotation(bale,0,math.pi/2,rot)
			end	
		end;
		
		--end of rotation
		
		if self:getRealAnimationTime(self.WrappingAnimation) >= 27500 then	
			
			self:setAnimationTime(2, 0);
				
		end;
		
			 self.select = true;
					 if self.usedFruitType == Fillable.FILLTYPE_DRYGRASS_WINDROW or self.usedFruitType == Fillable.FILLTYPE_GRASS_WINDROW then
						self.select = false;
					end
							
							if  self.select then
									setVisibility(self.strawBale, true);
									setVisibility(self.hayBale, false);
							else
								setVisibility(self.hayBale, true);
								setVisibility(self.strawBale, false);
							end; 
	else
	
	
	setVisibility(self.hayBale, false);
	setVisibility(self.strawBale, false);
	end;
	
end;
---tableattachings--
function WrapperRoundBale:isBaleInTableRange(node1,node2,Yoffset,Bale)
	local Xmax, Ymax, Zmax = getWorldTranslation(node1);
		  Xmax, Ymax, Zmax = worldToLocal(self.tablePlace.attacherNode,Xmax, Ymax, Zmax);
		  
	local Xmin, Ymin, Zmin = getWorldTranslation(node2);	
		  Xmin, Ymin, Zmin = worldToLocal(self.tablePlace.attacherNode,Xmin, Ymin, Zmin);
	
	local Xt, Yt, Zt = getWorldTranslation(Bale);
		  Xt, Yt, Zt = worldToLocal(self.tablePlace.attacherNode,Xt, Yt, Zt);
		
	if (Xt < math.max(Xmax,Xmin) and Xt > math.min(Xmax,Xmin)) and (Zt < math.max(Zmax,Zmin) and Zt > math.min(Zmax,Zmin)) and (Yt<= ((Ymax+Ymin)/2)+Yoffset and Yt>= (Ymax+Ymin)/2) then
		return true;
		
	else
		return false;
	end;
end;

function WrapperRoundBale:searchTableBales()
	for index,item in pairs(g_currentMission.itemsToSave) do
		if item.item:isa(Bale) then 
			if item.item.isAttached == nil then
				local isInRange = self:isBaleInTableRange(self.tablePlace.node1,self.tablePlace.node2,self.tablePlace.highOffset,item.item.nodeId);
				if isInRange and self.isWrapping  then
					local baleObject = item.item;
					if baleObject ~= nil and baleObject:isa(Bale) then
						self.usedFruitType = baleObject.fillType;
						self.usedFillLevel = baleObject.fillLevel;
						 baleObject:delete();
					end;
					self.baleCanBeWrapped = false;
				elseif isInRange   then
					self.baleCanBeWrapped = isInRange;
					self.baleInRange = item.item;
				
					
				elseif not isInRange and self.baleInRange == item.item then
					self.baleCanBeWrapped = isInRange;
					self.baleInTable = isInRange;
					self.baleInRange = nil;
				end;
			end;
		end;
	end;
end;
function WrapperRoundBale:attachTableObjects(object,baleT)
	local attachedobject = {};
	attachedobject.object = object;
	if self.isServer then
		attachedobject.AT = createTransformGroup("AT");
		link(self.tablePlace.attacherNode,attachedobject.AT);
		
		attachedobject.objectMass = getMass(object);
		setMass(object,attachedobject.objectMass*0.01);
		
		--self:tableOrientJoint(object,attachedobject.AT);

		local constr = JointConstructor:new();					
		constr:setActors(self.tablePlace.attacherNode, object);
		constr:setJointTransforms(attachedobject.AT,  object);
		for i=1, 3 do
			constr:setTranslationLimit(i-1, true, 0, 0);
			constr:setRotationLimit(i-1,0,0);
		end;
		attachedobject.JointIndex = constr:finalize();
		
		if baleT ~= nil then
			attachedobject.baleT = baleT;
			baleT.isAttached = true;
			--renderText(0.1, 0.16, 0.03," baleT.isAttached = true  ");
		end;
	end;

	table.insert(self.AttachedTableObjects, attachedobject);
	return true;
end;

function WrapperRoundBale:detachTableObjects()
	if self.isServer then
		for k,v in pairs(self.AttachedTableObjects) do
			removeJoint(v.JointIndex);
			delete(v.AT);
			v.JointIndex = nil;
			setMass(v.object,v.objectMass);
			if v.baleT ~= nil then
				v.baleT.isAttached = nil;
			end;
		end;
	end;
		--renderText(0.1, 0.18, 0.03," self.balesOnTableAttached = false  ");
	self.AttachedTableObjects = nil;
	self.AttachedTableObjects = {};
	self.balesOnTableAttached = false;
end;
function WrapperRoundBale:setBalesVisibility(baleVisibility, noEventSend)
	if baleVisibility ~= self.isBaleVisible then
		if noEventSend == nil or noEventSend == false then
			if g_server ~= nil then
				g_server:broadcastEvent(SetBalesEvent:new(self, baleVisibility), nil, nil, self);
			else
				g_client:getServerConnection():sendEvent(SetBalesEvent:new(self, baleVisibility));
			end;
		end;
		self.isBaleVisibile = baleVisibility;
		if self.baleActive ~= 12 then
			setVisibility(self.staticBales[self.baleActive], baleVisibility);
		end;
		if self.baleActive ~= 1 then
			setVisibility(self.staticBales[self.baleActive-1], not baleVisibility);
		end;
		---print(string.format("Should set bale" .. "%d" .. " visible in setBalesVisibility", self.baleActive));
		self.baleActive = self.baleActive+1;
	end;
end;



function WrapperRoundBale:draw()

		
end;


function WrapperRoundBale:setWrapping(isWrapping,noEventSend)
	SetWrappingEvent.sendEvent(self, isWrapping, noEventSend);
	-- Play wrapping animation --
	if self.WrappingAnimation ~= nil and self.playAnimation ~= nil then
		self:playAnimation(self.WrappingAnimation, 1, nil, true);
	
		
	end;
end;
function WrapperRoundBale:createBale(usedFruitType)
	
	
	
	usedFruitType =	Fillable.fillTypeIntToName[usedFruitType] --windrow fix
	
    local baleType = self.baleTypes[usedFruitType];
    if baleType == nil then
        baleType = self.defaultBaleType;
    end;
	
	local filename = baleType.filename;
	if self.secondFoilColor ~= nil then
		if self.secondFoilColor then
			filename = baleType.filenameFoil2;
		end;
	end;
    local baleRoot = Utils.loadSharedI3DFile(filename, self.baseDirectory);

    local baleId = getChildAt(baleRoot, 0);
    setRigidBodyType(baleId, "None");
	link(self.baleAnimRoot, baleId);
    delete(baleRoot);

    local bale = {};
    bale.id = baleId;
    bale.time = 0;
    bale.fillType = usedFruitType;
	bale.fruitType = usedFruitType;
    bale.filename = Utils.getFilename(filename, self.baseDirectory);
    bale.lastX, bale.lastY, bale.lastZ = getWorldTranslation(bale.id);
    table.insert(self.bales, bale);
    local i = table.getn(self.bales);
	---print("Bale should be created");
end;
function WrapperRoundBale:dropBale(baleIndex)
    local bale = self.bales[baleIndex];
		if bale ~= nil then
		--local deltaRealTime = (self.time - self.baleLastPositionTime)/1000;
		local x,y,z = getWorldTranslation(bale.id);
		local rx,ry,rz = getWorldRotation(bale.id);
		link(getRootNode(), bale.id);

		if self.isServer then
			local baleObject = Bale:new(self.isServer, self.isClient);
			baleObject:load(bale.filename, x,y,z,rx,ry,rz);
			
			if self.usedFruitType == Fillable.FILLTYPE_WHEAT_WINDROW or self.usedFruitType == Fillable.FILLTYPE_BARLEY_WINDROW then
				baleObject.fillType = self.usedFruitType;
				baleObject.fruitType = self.usedFruitType;
				baleObject.fillLevel = self.usedFillLevel*1.2;
			
			else
				baleObject.fillType = Fillable.FILLTYPE_SILAGE;
				baleObject.fruitType = Fillable.FILLTYPE_SILAGE;					
				baleObject.fillLevel = self.usedFillLevel;
			end;
			baleObject:register();

			-- local lx, ly, lz = bale.lastX, bale.lastY, bale.lastZ;
			-- setLinearVelocity(baleObject.nodeId, (x-lx)/deltaRealTime, (y-ly)/deltaRealTime, (z-lz)/deltaRealTime);
		end;
		delete(bale.id);
		table.remove(self.bales, baleIndex);
	end;
end;
function WrapperRoundBale:setResetActiveBale(activeBaleReset, noEventSend)
	SetActiveBaleEvent.sendEvent(self, activeBaleReset, noEventSend);
	if activeBaleReset then
		self.baleActive = 1;
	end;
end;

function WrapperRoundBale:readStream(streamId, connection)
    
	self:setWrapping(streamReadBool(streamId), true);

	
	self:setBalesVisibility(streamReadBool(streamId), true);
	self:setResetActiveBale(streamReadBool(streamId), true);
local numBales = streamReadInt16(streamId);
	for i=1, numBales do
		local fruitType = streamReadInt8(streamId);
		self:createBale(fruitType);
	end;
end;

function WrapperRoundBale:writeStream(streamId, connection)
   
	streamWriteBool(streamId, self.isWrapping);


	streamWriteBool(streamId, self.isBaleVisible);
	streamWriteBool(streamId, self.resetActiveBale);
	
	streamWriteInt16(streamId, table.getn(self.bales));
	for i=1, table.getn(self.bales) do
		local bale = self.bales[i];
		streamWriteInt8(streamId, bale.fruitType);
	end;
end;
