
placeableWash = {}
local placeableWash_mt = Class(placeableWash, Placeable)

InitObjectClass(placeableWash, "placeableWash")

function placeableWash:new(isServer, isClient)
    self = Placeable:new(isServer, isClient, placeableWash_mt)
	self.vtriggernode=nil
	self.ptriggernode=nil
	self.washPerSecond=0.1
	self.vehiclesInTrigger = {};
	self.washAnim = {};	
	self.washactive = false
	
    self.placeableWashDirtyFlag = self:getNextDirtyFlag();
    return self
end

function placeableWash:delete()

    removeTrigger(self.vtriggernode)
    removeTrigger(self.ptriggernode)	
    g_effectManager:deleteEffects(self.effects)
    unregisterObjectClassName(self)
    placeableWash:superClass().delete(self)
end

function placeableWash:load(xmlFilename, x,y,z, rx,ry,rz, initRandom)
    if not placeableWash:superClass().load(self, xmlFilename, x,y,z, rx,ry,rz, initRandom) then
        return false
    end

    local xmlFile = loadXMLFile("placeableWash", xmlFilename)
	
	local vtriggerId = I3DUtil.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.wash#vtriggernode"))
    if vtriggerId ~= nil then
        self.vtriggernode = vtriggerId
        addTrigger(self.vtriggernode, "triggerCallbackWash", self)
		
		self.vtriggerId=vtriggerId;
			self.washAnim.speedScale = 1;
			self.washAnim.animCharSet = 0;
			local rootNode = I3DUtil.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.wash#animationnode"))--getChildAt(vtriggerId, 0);
			self.washAnim.animCharSet = getAnimCharacterSet(rootNode);
			if self.washAnim.animCharSet ~= 0 then
				local clipSource = getXMLString(xmlFile, "placeable.wash#animationname") 
				if clipSource ~= nil then
					self.washAnim.clip = getAnimClipIndex(self.washAnim.animCharSet, clipSource);
					if self.washAnim.clip ~= nil then
						if self.washAnim.clip >= 0 then
							assignAnimTrackClip(self.washAnim.animCharSet, 0, self.washAnim.clip);
							setAnimTrackLoopState(self.washAnim.animCharSet, 0, false);
							setAnimTrackSpeedScale(self.washAnim.animCharSet, 0, self.washAnim.speedScale);
							self.washAnim.animDuration = getAnimClipDuration(self.washAnim.animCharSet, self.washAnim.clip);
							self.washPerSecond = 1000/self.washAnim.animDuration*1.2
						else
							print("placeableWash clip for objectIndex "..tostring(rootNode).." is < 0");
						end;
					else
						print("placeableWash no AnimationClip named "..tostring(clipSource).." can be found for objectIndex "..tostring(rootNode).."");
					end;
				else
					print("placeableWash no AnimationClip assigned for objectIndex "..tostring(rootNode).."");
				end;
			else
				print("placeableWash no animation assigned for objectIndex "..tostring(rootNode).."");
			end;
			self.washAnim.isEnabled = false;
			self.washAnim.trackTime = 0;
		
		
	end
	
	local ptriggerId = I3DUtil.indexToObject(self.nodeId, getXMLString(xmlFile, "placeable.wash#ptriggernode"))
    if ptriggerId ~= nil then
        self.ptriggernode = ptriggerId
        addTrigger(self.ptriggernode, "triggerCallbackPlayer", self)
	end
	self.effects = g_effectManager:loadEffect(xmlFile, "placeable.wash.effects", self.nodeId, self)
    g_effectManager:setFillType(self.effects, FillType.WATER)
	
    delete(xmlFile)

    registerObjectClassName(self, "placeableWash")
    return true
end

function placeableWash:finalizePlacement()
    placeableWash:superClass().finalizePlacement(self)

end

function placeableWash:onSell()
    placeableWash:superClass().onSell(self)
end

function placeableWash:addRemoveInputsAutoopen()
	 	
		if self.eventId == nil and not self.washactive then
				local _, eventId = g_inputBinding:registerActionEvent(InputAction.START_WASH, self, self.onActivateplaceableWash, false, true, false, true);
				self.eventId = eventId;
		elseif self.eventId ~= nil then
			g_inputBinding:removeActionEvent(self.eventId);
			self.eventId = nil;
		end;
	
end;

function placeableWash:update(dt)
	if self.washAnim.isEnabled then
		self.washAnim.trackTime = self.washAnim.trackTime + dt * self.washAnim.speedScale;
		if self.washAnim.trackTime > 3000 and self.washAnim.trackTime < 4000 and not self.effectactive then		
			self:setIsWashing(self.washactive, false, false)
			self.effectactive = true
		elseif self.washAnim.trackTime > self.washAnim.animDuration-3000 and self.effectactive then
			self:setIsWashing(false, true, true)			
			self.effectactive = false
		end
		
		if self.washAnim.trackTime > self.washAnim.animDuration then
			self.washAnim.trackTime = 0;
			setAnimTrackTime(self.washAnim.animCharSet, self.washAnim.clip, self.washAnim.trackTime, true);
			disableAnimTrack(self.washAnim.animCharSet, self.washAnim.clip);
			self.washAnim.isEnabled = false;
			self.washactive = false			
		end;
		if self.isServer then
			if table.getn(self.vehiclesInTrigger) > 0 and self.washactive then
				for _,otherId in pairs(self.vehiclesInTrigger) do
					local vehicle = g_currentMission.nodeToObject[otherId];
					local removeDirt = self.washPerSecond/1000* dt;
					if vehicle ~= nil then
						if vehicle.spec_washable ~= nil then					
							local washvehicle = vehicle.spec_washable.washableNodes
								if washvehicle ~= nil then
									for _, nodeData in ipairs(washvehicle) do
										dirtamount = vehicle:getNodeDirtAmount(nodeData)								
										if dirtamount >0.01 then
											vehicle:setNodeDirtAmount(nodeData, vehicle:getNodeDirtAmount(nodeData) - removeDirt, force)
										elseif dirtamount >0.001 then
											vehicle:setNodeDirtAmount(nodeData, 0, force)
										end
									end
								end
						end		
					end
				end;
			end;
		end
		self:raiseActive()
	end;	
end

function placeableWash:setIsWashing(doWashing, force, noEventSend)
    if self.doWashing ~= doWashing then
        if doWashing then
            g_effectManager:setFillType(self.effects, FillType.WATER)
            g_effectManager:startEffects(self.effects)
        else
            if force then
                g_effectManager:resetEffects(self.effects)
            else
                g_effectManager:stopEffects(self.effects)
            end
        end
        self.doWashing = doWashing
    end
end

function placeableWash:onActivateplaceableWash()
	if not self.washactive then
		self:startwash()
	end		
end;

function placeableWash:startwash(noEventSend)

		self.washactive = true			
		self.effectactive = false
		enableAnimTrack(self.washAnim.animCharSet, self.washAnim.clip);
		self:addRemoveInputsAutoopen()
		self.washAnim.isEnabled = true;
		self:raiseActive()

		if noEventSend == nil or noEventSend == false then
			local washactive = self.washactive
			if g_server ~= nil then
				g_server:broadcastEvent(placeableWashEvent:new(self, washactive), nil, nil, self)
			else
				g_client:getServerConnection():sendEvent(placeableWashEvent:new(self, washactive))
			end
		end
end

function placeableWash:triggerCallbackWash(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)


		if onEnter then
			local vehicle = g_currentMission.nodeToObject[otherShapeId];
			if vehicle ~= nil then
				local existvec = false
				if table.getn(self.vehiclesInTrigger) > 0 then
					for x, y in pairs(self.vehiclesInTrigger) do
						if y == otherShapeId then
							
							existvec =true
						end;
					end;
				end;
				if not existvec then
					table.insert(self.vehiclesInTrigger, otherShapeId);
				end
			end
		elseif onLeave then
			if table.getn(self.vehiclesInTrigger) > 0 then
				for x, y in pairs(self.vehiclesInTrigger) do
					if y == otherShapeId then
						table.remove(self.vehiclesInTrigger,x);
					end;
				end;
			end;
		end; 
end;

function placeableWash:triggerCallbackPlayer(triggerId, otherId, onEnter, onLeave, onStay)
	if g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode then
		self:addRemoveInputsAutoopen()
	end;
end;

placeableWashEvent = {}
placeableWashEvent_mt = Class(placeableWashEvent, Event)

InitEventClass(placeableWashEvent, "placeableWashEvent")

function placeableWashEvent:emptyNew()
	local self = Event:new(placeableWashEvent_mt)
	return self
end

function placeableWashEvent:new(object, washactive)
	local self = placeableWashEvent:emptyNew()
	self.object = object
	self.washactive = washactive

	return self
end

function placeableWashEvent:readStream(streamId, connection)
	self.object = NetworkUtil.readNodeObject(streamId)
	self.washactive = streamReadBool(streamId)

	self:run(connection)
end

function placeableWashEvent:writeStream(streamId, connection)
	NetworkUtil.writeNodeObject(streamId, self.object)
	streamWriteBool(streamId, self.washactive)
end

function placeableWashEvent:run(connection)	
	self.object:startwash(true)

	if not connection:getIsServer() then
		g_server:broadcastEvent(placeableWashEvent:new(self.object, self.object.washactive), nil, connection, self.object)
	end
end
