--
-- WelgerAP730
--
-- author  Mythos
-- date  05/01/2012
-- www.ARM-team.gr
-- Copyright (C) ARM Team, All Rights Reserved.

AP730wc = {};

function AP730wc.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Fillable, specializations);
end;

function AP730wc:load(xmlFile)

	-- Functions
	self.getIsAreaActive = Utils.overwrittenFunction(self.getIsAreaActive, AP730wc.getIsAreaActive);
	self.extraAnim = SpecializationUtil.callSpecializationsFunction("extraAnim");
	self.baleCounter = SpecializationUtil.callSpecializationsFunction("baleCounter");
	self.MPCode= SpecializationUtil.callSpecializationsFunction("MPCode");
	self.TimeSet= SpecializationUtil.callSpecializationsFunction("TimeSet");
	self.DroppBale= SpecializationUtil.callSpecializationsFunction("DroppBale");
	self.UnloadAP730= SpecializationUtil.callSpecializationsFunction("UnloadAP730");
	self.EmptyAP730= SpecializationUtil.callSpecializationsFunction("EmptyAP730");
	
	-- Animations
	self.workAnim = getXMLString(xmlFile, "vehicle.chuteWM#animationName");
	self.transportAnim = getXMLString(xmlFile, "vehicle.chuteTM#animationName");
	self.pickUpAnim = getXMLString(xmlFile, "vehicle.pickUp#animationName");
	self.attacherArm = getXMLString(xmlFile, "vehicle.attacherArm#animationName");

	-- Indexs
	self.roller = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.roller#index"));
	self.pto = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.pto#index"));
	self.transportChain = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.tChain#index"));
	self.workChain = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.wChain#index"));
	self.wcChain = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.wcChain#index"));
	
	
	-- Particles
	self.dustParticles = {};
	local i = 0;
    while true do
        local key = string.format("vehicle.dustPS.pS(%d)", i);
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.. "#index"));
		if node == nil then
			break;
		end; 
        Utils.loadParticleSystem(xmlFile, self.dustParticles, key, node, false, nil, self.baseDirectory)		
		i = i +1;		
    end;
	
	self.wheatParticleSystems = {};
	local i=0;
	while true do
		local key = string.format("vehicle.wheatParticleSystems.wheatParticleSystem(%d)", i);
		local node = getXMLString(xmlFile, key.. "#node");
		if node == nil then
			break;
		end;
		node = Utils.indexToObject(self.components, node);
		if node ~= nil then
			local psFile = getXMLString(xmlFile, key.. "#file");
			local wheatParticleSystem = {};
			wheatParticleSystem.particleSystem = {};
			StaticParticleSystem.loadParticleSystem(xmlFile, wheatParticleSystem.particleSystem, key, self.components, false, nil, self.baseDirectory);
			table.insert(self.wheatParticleSystems, wheatParticleSystem);
		end;
		i = i+1;
	end;
	
	self.grassParticleSystems = {};
	local i=0;
	while true do
		local key = string.format("vehicle.grassParticleSystems.grassParticleSystem(%d)", i);
		local node = getXMLString(xmlFile, key.. "#node");
		if node == nil then
			break;
		end;
		node = Utils.indexToObject(self.components, node);
		if node ~= nil then
			local psFile = getXMLString(xmlFile, key.. "#file");
			local grassParticleSystem = {};
			grassParticleSystem.particleSystem = {};
			StaticParticleSystem.loadParticleSystem(xmlFile, grassParticleSystem.particleSystem, key, self.components, false, nil, self.baseDirectory);
			table.insert(self.grassParticleSystems, grassParticleSystem);
		end;
		i = i+1;
	end;
	
	self.dryGrassParticleSystems = {};
	local i=0;
	while true do
		local key = string.format("vehicle.dryGrassParticleSystems.dryGrassParticleSystem(%d)", i);
		local node = getXMLString(xmlFile, key.. "#node");
		if node == nil then
			break;
		end;
		node = Utils.indexToObject(self.components, node);
		if node ~= nil then
			local psFile = getXMLString(xmlFile, key.. "#file");
			local dryGrassParticleSystem = {};
			dryGrassParticleSystem.particleSystem = {};
			StaticParticleSystem.loadParticleSystem(xmlFile, dryGrassParticleSystem.particleSystem, key, self.components, false, nil, self.baseDirectory);
			table.insert(self.dryGrassParticleSystems, dryGrassParticleSystem);
		end;
		i = i+1;
	end;
	
	-- Booleans
	self.workPos = false;
	self.wanimEnded = true;
	self.tanimEnded = true;
	self.pickUpPos = false;
	self.widthPos = false;
	self.previousLevel = 0;

	self.HUD = false;
	self.unloadBales = false;
	self.emptyBaler = false;
	self.allowTransport = true;
	
	-- HUD
	self.file = Utils.getFilename("counter.png", self.baseDirectory);
	self.HUDx = 0.435;
    self.HUDy = 1-0.330;
    self.HUDWidth = 0.320;
    self.HUDHeight = 0.320;
	
	self.cX = 0.47;
    self.cY = 0.945;
	self.tX = 0.57;
    self.tY = 0.945;
	self.APCurrentwc0 = 0;
	self.APTotalwc0 = 0;
    
	self.APHUD = Overlay:new("APHUD", self.file, self.HUDx, self.HUDy, self.HUDWidth, self.HUDHeight);

	-- extraAnimations
	self.extraChar = {};
	local i = 0;
    while true do
        local key = string.format("vehicle.extraAnimations.extraAnimation(%d)", i);
		local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.. "#index"));
		if node == nil then
			break;
		end;
        self.extraChar[i+1] = node;
		i = i +1;
    end;
	self.extraClip = {};
	local i = 0;
    while true do
        local key = string.format("vehicle.extraAnimations.extraAnimation(%d)", i);
		local node = getXMLString(xmlFile, key.. "#animationClip");
		if node == nil then
			break;
		end;
        self.extraClip[i+1] = node;
		i = i +1;
    end;
	
end;

function AP730wc:delete()
	Utils.deleteParticleSystem(self.dustParticles);
	for k, wheatParticleSystem in pairs(self.wheatParticleSystems) do
		Utils.setEmittingState(wheatParticleSystem.particleSystem, false);
	end;
	for k, grassParticleSystem in pairs(self.grassParticleSystems) do
		Utils.setEmittingState(grassParticleSystem.particleSystem, false);
	end;
	for k, dryGrassParticleSystem in pairs(self.dryGrassParticleSystems) do
		Utils.setEmittingState(dryGrassParticleSystem.particleSystem, false);
	end;
end;

function AP730wc:onDetach()
	Utils.setEmittingState(self.dustParticles, false);
	self:MPCode(4, false);
end;

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

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

function AP730wc:update(dt)

	if self:getIsActiveForInput() and self:getIsActive() then
		
		if self.allowTransport and self.wanimEnded and self.tanimEnded and not self.emptyBaler and not self.unloadBales then
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
				self:MPCode(1, not self.workPos);
			end;
		end;
		
		if not self.allowTransport and not self.isTurnedOn and self.workPos and not self.emptyBaler and not self.unloadBales and self.wanimEnded and self.tanimEnded then
			if InputBinding.hasEvent(InputBinding.ALLOW_TRANSPORT) then
				self.unloadBales = true;
			end;
		end;
		
		
		if table.getn(self.bales) ~=0 and not self.isTurnedOn and self.workPos and not self.emptyBaler and not self.unloadBales and self.wanimEnded and self.tanimEnded then
			if InputBinding.hasEvent(InputBinding.EMPTY_BALER) then
				self.emptyBaler = true;
			end;
		end;
		
		if InputBinding.hasEvent(InputBinding.COUNTER) then
			self.HUD = not self.HUD;
		end;
		
		if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then
			self:MPCode(3, not self.widthPos);
		end;
		
		if self.workPos and self.wanimEnded then
			if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
				self:MPCode(2, not self.pickUpPos);
			end;
		end;
		
		if self.activeAnimations[self.workAnim] ~= nil then
			self.wanimEnded = false;
			self.animTime = self:getRealAnimationTime(self.workAnim);
			if self.animTime > 1900 then
				self:MPCode(5, true);
			end;
			if self.animTime > 2900 then
				self:MPCode(6);
			end;
		else
			self.wanimEnded = true;
		end;
		
		if self.activeAnimations[self.transportAnim] ~= nil then
			self.tanimEnded = false;
			self.animTime = self:getRealAnimationTime(self.transportAnim);
			if self.animTime > 2900 then
				self:MPCode(5, false);
			end;
		else
			self.tanimEnded = true;
		end;

		if not self.emptyBaler then
			if table.getn(self.bales) ~=0 then
				for i,v in pairs(self.bales) do
					if v.time >0.220 then
						self.allowTransport = false;
						break;
					else
						self.allowTransport = true;
						self.unloadBales = false;
					end;
				end;
			else
				self.allowTransport = true;
				self.unloadBales = false;
			end;
		end;
		
	end;
	self:extraAnim();

end;

function AP730wc:updateTick(dt)
	if self:getIsActive() then
		if self.isTurnedOn then
			rotate(self.roller, dt*-0.005, 0, 0);
			rotate(self.pto, 0, 0, dt*-0.02);
		end;
		if self.previousLevel ~= self.fillLevel then
			Utils.setEmittingState(self.dustParticles, true);
			self.previousLevel = self.fillLevel;
			self:MPCode(4, true);
		else
			Utils.setEmittingState(self.dustParticles, false);
			self:MPCode(4, false);
		end;
		
		if self.unloadBales then
			self:UnloadAP730(self.unloadBales);
		end;
		
		if self.emptyBaler then
			self:EmptyAP730(self.emptyBaler);
		end;
		
		for i, v in pairs(self.componentJoints) do
			setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
		end;
		
	end;

end;

function AP730wc:MPCode(mode, state, noEventSend)
	AP730Event.sendEvent(self, mode, state, noEventSend);

--______________________________________________________________________________
if mode == 1 then
--_________________________________ WORK MODE __________________________________
	if state then
		self:playAnimation(self.workAnim, 1, nil, true);
		self.workPos = true;
		setVisibility(self.transportChain, false);
	else
		self:playAnimation(self.transportAnim, 1, nil, true);
		self.workPos = false;
		setVisibility(self.workChain, false);
		setVisibility(self.wcChain, false);
		self.allowTransport = true;
		if self.pickUpPos then
			self:playAnimation(self.pickUpAnim, -1, nil, true);
			self.pickUpPos = false;
		end;
	end;
--______________________________________________________________________________
elseif mode == 2 then
--_________________________________ PICKUP MODE __________________________________
	if state then
		self:playAnimation(self.pickUpAnim, 1, nil, true);
		self.pickUpPos = true;
	else
		self:playAnimation(self.pickUpAnim, -1, nil, true);
		self.pickUpPos = false;
	end;
--______________________________________________________________________________
elseif mode == 3 then
--_________________________________ ATTACHER MODE __________________________________
	if state then
		self:playAnimation(self.attacherArm, 1, nil, true);
		self.widthPos = true;
	else
		self:playAnimation(self.attacherArm, -1, nil, true);
		self.widthPos = false;
	end;
--______________________________________________________________________________
elseif mode == 4 then
--_________________________________ PARTICLES __________________________________
	if state then
		if FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_WHEAT or FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_BARLEY
		or FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_OAT or FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_RYE
		or FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_TRITICALE then
			for k, wheatParticleSystem in pairs(self.wheatParticleSystems) do
				Utils.setEmittingState(wheatParticleSystem.particleSystem, true);
			end;
		elseif FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_GRASS then
			for k, grassParticleSystem in pairs(self.grassParticleSystems) do
				Utils.setEmittingState(grassParticleSystem.particleSystem, true);
			end;
		elseif FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_DRYGRASS or FruitUtil.fillTypeToFruitType[self.currentFillType] == FruitUtil.FRUITTYPE_GREENWHEAT then
			for k, dryGrassParticleSystem in pairs(self.dryGrassParticleSystems) do
				Utils.setEmittingState(dryGrassParticleSystem.particleSystem, true);
			end;
		end;
	else
		for k, wheatParticleSystem in pairs(self.wheatParticleSystems) do
			Utils.setEmittingState(wheatParticleSystem.particleSystem, false);
		end;
		for k, grassParticleSystem in pairs(self.grassParticleSystems) do
			Utils.setEmittingState(grassParticleSystem.particleSystem, false);
		end;
		for k, dryGrassParticleSystem in pairs(self.dryGrassParticleSystems) do
			Utils.setEmittingState(dryGrassParticleSystem.particleSystem, false);
		end;
	end;
--______________________________________________________________________________
elseif mode == 5 then
--_________________________________ CHAIN MODE __________________________________
	if state then
		setVisibility(self.workChain, true);
	else
		setVisibility(self.transportChain, true);
	end;
--______________________________________________________________________________
elseif mode == 6 then
--_________________________________ CHAIN MODE __________________________________
	setVisibility(self.wcChain, true);
--______________________________________________________________________________
end;

end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:draw()

	if self.allowTransport and self.wanimEnded and self.tanimEnded and not self.emptyBaler and not self.unloadBales then
		if not self.workPos then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("WORKMODE"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA2);
		else
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("TRANSPORTMODE"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA2);
		end;
	end;
		
	if not self.allowTransport and not self.isTurnedOn and self.workPos and not self.emptyBaler and not self.unloadBales and self.wanimEnded and self.tanimEnded then
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("UNLOAD_BALES"), self.typeDesc), InputBinding.ALLOW_TRANSPORT);
	end;
	
	if table.getn(self.bales) ~=0 and not self.isTurnedOn and self.workPos and not self.emptyBaler and not self.unloadBales and self.wanimEnded and self.tanimEnded then
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("EMPTY_BALER"), self.typeDesc), InputBinding.EMPTY_BALER);
	end;	


	if self.workPos and self.wanimEnded then
		if not self.pickUpPos then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("PICKUP_DOWN"), self.typeDesc), InputBinding.LOWER_IMPLEMENT);
		else
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("PICKUP_UP"), self.typeDesc), InputBinding.LOWER_IMPLEMENT);
		end;
	end;
		
	if self.HUD then
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("HUD_OFF"), self.typeDesc), InputBinding.COUNTER);
	else
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("HUD_ON"), self.typeDesc), InputBinding.COUNTER);
	end;
	
	if self.widthPos then
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("TRANSPORT_WIDTH"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA3);
	else
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("WORK_WIDTH"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA3);
	end;

	
	if self.HUD then
		self.APHUD:render();
		setTextBold(true);
		setTextColor(0, 0, 0, 1.0);
		renderText(self.cX, self.cY, 0.020, "Today: ".. string.format(self.APCurrentwc0));
		renderText(self.tX, self.tY, 0.020, "Total: ".. string.format(self.APTotalwc0));
	end;
	
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:UnloadAP730(mode, noEventSend)
	UnloadAP730Event.sendEvent(self, mode, noEventSend);

		for i,v in pairs(self.bales) do
			if v.time >0.220 then
				self.TimeSet(self, i, v.time + 0.005, noEventSend);
			end;
		end;
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc.TimeSet(self, i, baleTime, noEventSend)
	TimeSetEvent.sendEvent(self, i, baleTime, noEventSend);

	if self.baleAnimCurve ~= nil then
		local bale = self.bales[i];
		if bale ~= nil then
			bale.time = baleTime;
			local v = self.baleAnimCurve:get(bale.time);
			setTranslation(bale.id, v[1], v[2], v[3]);
			setRotation(bale.id, v[4], v[5], v[6]);
			if bale.time >= 1 then
				self.DroppBale(self, i);
				self.APCurrentwc0 = self.APCurrentwc0 +1;
				self.APTotalwc0 = self.APTotalwc0 +1;
			end;
		end;
	end;

end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc.DroppBale(self, baleIndex)
	local bale = self.bales[baleIndex];
	local x,y,z = getWorldTranslation(bale.id);
	local rx,ry,rz = getWorldRotation(bale.id);
	local baleObject = Bale:new(self.isServer, self.isClient);
	baleObject:load(bale.filename, x,y,z,rx,ry,rz);
	baleObject:register();
	local lx, ly, lz = bale.lastX, bale.lastY, bale.lastZ;
	setLinearVelocity(baleObject.nodeId, (x-lx)/1, (y-ly)/1, (z-lz)/1);
	delete(bale.id);
	table.remove(self.bales, baleIndex);
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:EmptyAP730(mode, noEventSend)
	EmptyAP730Event.sendEvent(self, mode, noEventSend);
	
	for i=1, 7 do
		local v = self.bales[i];
		if v~=nil then
			self.TimeSet(self, i, v.time + 0.005, noEventSend);
		end;
	end;
	
	if table.getn(self.bales) ==0 then
		self.emptyBaler = false;
		self.fillLevel = 0;
		self.previousLevel = 0;
	end;

end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:extraAnim()

	if self.isTurnedOn then
		local i=1;
		while true do
			local charId = getAnimCharacterSet(self.extraChar[i]);
			if charId == nil then
				break;
			end;
			local clipIndex = getAnimClipIndex(charId, self.extraClip[i]);
			assignAnimTrackClip(charId , 0, clipIndex);
			setAnimTrackLoopState(charId, 0, false);
			setAnimTrackSpeedScale(charId, 0, 5);
			enableAnimTrack(charId, 0);
			if getAnimTrackTime(charId, 0) >= getAnimClipDuration(charId, clipIndex) then
				setAnimTrackTime(charId, 0, 0, true);
			end;
			i = i +1;
		end;
	else
		disableAnimTrack(charId, 0);
	end;

end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:getIsAreaActive()
	return self.pickUpPos;
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		self.APTotalwc0 = Utils.getNoNil(getXMLInt(xmlFile, key.."#totalBales"),0);
		self.pickUpPos = Utils.getNoNil(getXMLBool(xmlFile, key.."#pickUp"),false);
		self:MPCode(2, self.pickUpPos);
		self.workPos = Utils.getNoNil(getXMLBool(xmlFile, key.."#workPos"),false);
		self:MPCode(1, self.workPos);
		setVisibility(self.workChain, self.workPos);
		setVisibility(self.transportChain, not self.workPos);
		self.unloadBales = Utils.getNoNil(getXMLBool(xmlFile, key.."#unloadBales"),false);
		self.allowTransport = Utils.getNoNil(getXMLBool(xmlFile, key.."#allowTransport"),true);
		self.emptyBaler = Utils.getNoNil(getXMLBool(xmlFile, key.."#emptyBaler"),false);
	end;
	
	for i, v in pairs(self.componentJoints) do
		setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
	end;
	
	return BaseMission.VEHICLE_LOAD_OK;
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'totalBales="'..tostring(self.APTotalwc0)..
	'" pickUp="'..tostring(self.pickUpPos)..
	'" workPos="'..tostring(self.workPos)..
	'" unloadBales="'..tostring(self.unloadBales)..
	'" allowTransport="'..tostring(self.allowTransport)..
	'" emptyBaler="'..tostring(self.emptyBaler)..'"';
	local nodes = nil;
	
	return attributes,nodes;
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:readStream(streamId, connection)
	self.APCurrentwc0 = streamReadInt32(streamId);
	self.APTotalwc0 = streamReadInt32(streamId);
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:writeStream(streamId, connection)
	streamWriteInt32(streamId, self.APCurrentwc0);
	streamWriteInt32(streamId, self.APTotalwc0);
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc:validateAttacherJoint(implement, jointDesc, dt)
    return true;
end;

--________________________________________________________________________________________________________________________________________________________
function AP730wc.baleCounter(self, baleIndex)
	if self.APCurrentwc0 ~= nil and self.APTotalwc0 ~= nil then
		self.APCurrentwc0 = self.APCurrentwc0 +1;
		self.APTotalwc0 = self.APTotalwc0 +1;
	end;
end;

Baler.dropBale = Utils.appendedFunction(Baler.dropBale, AP730wc.baleCounter);