--
-- manureTrailer
-- Specialization for manureTrailer
--
-- @author Felix "Outlaw" Sorge
-- @date  20/05/09
-- @web www.ls-modsource.de - www.ls-mods.de
--
-- Copyright (C) Outlaw, All Rights Reserved.
--


manureTrailer = {};

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

function manureTrailer:load(xmlFile)
	self.setTurnedOn = SpecializationUtil.callSpecializationsFunction("setTurnedOn");
	self.fertilizerInRange = SpecializationUtil.callSpecializationsFunction("fertilizerInRange");
	self.manureTanker = true;	
	self.literPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerSecond#value"), 1);
        
	self.chargeTypes = {};
	self.fillTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;
	local chargeTypes = getXMLString(xmlFile, "vehicle.chargeTypes#chargeTypes");
    if chargeTypes ~= nil then
		self.chargefillNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chargeTypes#fillNode"));
        local types = Utils.splitString(" ", chargeTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.chargeTypes[desc.index] = true;
            end;
        end;
    end;
	local workSound = getXMLString(xmlFile, "vehicle.workSound#file");
    if workSound ~= nil and workSound ~= "" then
        workSound = Utils.getFilename(workSound, self.baseDirectory); 
        self.workSound = createSample("workSound");
        self.workSoundEnabled = false;
        loadSample(self.workSound, workSound, false);
    end;
	self.keyType = InputBinding.getKeyNamesOfDigitalAction;
	self.keyName = "Taste";	
    
    self.inTrigger = false;
    self.steeringTrigger = manureTrailer.steeringTrigger;
    self.Trigger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.steeringTrigger#index2"));
    addTrigger(self.Trigger,"steeringTrigger",self);
end;

function manureTrailer:update(dt)	
    if self.inTrigger then                
        self.inRange = false; 
        local nearestDistance = 10.0;
        local px, py, pz = getWorldTranslation(self.chargefillNode);
        for i=1, table.getn(g_currentMission.attachables) do
            local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].rootNode);
            local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
            if distance < nearestDistance then
                local attachable = g_currentMission.attachables[i];		
                if attachable.fillTypes ~= nil then
                    for fruitType,v in pairs(attachable.fillTypes) do
                        if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode and attachable.setFillLevel ~= nil then	
                            if attachable.fillLevel ~= attachable.capacity  and self.fillLevel ~= 0  then
                                if self.turnOn then
                                    if attachable.fillLevel == attachable.capacity or self.filllevel == 0 then
                                        self:setTurnedOn(false)
                                        if self.workSoundEnabled then
                                            stopSample(self.workSound);
                                            self.workSoundEnabled = false;
                                        end;
                                    end;
                                    g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.manureTrailer_ON).. ": " ..g_i18n:getText("manureTrailer_2")); 
                                    if InputBinding.hasEvent(InputBinding.manureTrailer_ON) then
                                        self:setTurnedOn(not self.turnOn); 
                                        if self.workSoundEnabled then
                                            stopSample(self.workSound);
                                            self.workSoundEnabled = false;
                                        end;
                                    end;				
                                else
                                    g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.manureTrailer_ON).. ": " ..g_i18n:getText("manureTrailer_1")); 
                                    if InputBinding.hasEvent(InputBinding.manureTrailer_ON)  then
                                        self:setTurnedOn(not self.turnOn); 
                                        if not self.workSoundEnabled then
                                            playSample(self.workSound, 0, 1, 0);
                                            self.workSoundEnabled = true;   
                                        end; 
                                    end;
                                end;		
                            end;		
                        end; 
                    end;
                end;
            end;
        end;
    end;
end;

function manureTrailer:steeringTrigger(triggerId,otherId,onEnter,onLeave,onStay)
    if (onEnter) and (g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode) then
        self.inTrigger = true;
    elseif (onLeave) and (g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode) then
        self.inTrigger = false;
    end;
end;

function manureTrailer:updateTick(dt)	
    if self.isServer then   
        self.inRange = false; 
        local nearestDistance = 10.0;
        local px, py, pz = getWorldTranslation(self.chargefillNode);
        for i=1, table.getn(g_currentMission.attachables) do
            local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].rootNode);
            local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
            if distance < nearestDistance then
                local attachable = g_currentMission.attachables[i];		
                if attachable.fillTypes ~= nil then
                    for fruitType,v in pairs(attachable.fillTypes) do
                        if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode and attachable.setFillLevel ~= nil then	
                            if attachable.fillLevel == attachable.capacity  or self.filllevel == 0 then
                                self:setTurnedOn(false)
                                if self.workSoundEnabled then
                                    stopSample(self.workSound);
                                    self.workSoundEnabled = false;
                                end;
                            elseif attachable.fillLevel ~= attachable.capacity  and self.fillLevel ~= 0  then
                                if self.turnOn then
                                    self.inRange = true; 
                                    local deltaLevel = self.literPerSecond*dt/1000.0;
                                    deltaLevel = math.min(deltaLevel, attachable.capacity - attachable.fillLevel);
                                    self.fillLevel = self.fillLevel-deltaLevel;
                                    self:setFillLevel(self.fillLevel, self.currentFillType);
                                    attachable:setFillLevel(attachable.fillLevel + deltaLevel, self.currentFillType);	
                                end; 		
                            end;		
                        end; 
                    end;
                end;
            end;
        end;
        if not self.inRange and self.turnOn then
            self:setTurnedOn(not self.turnOn);
        end;
    end;
end;

function manureTrailer:setTurnedOn(turned_on, noEventSend)
    if noEventSend ~= true then
		ManureTrailerEvent.sendEvent(self, turned_on);
	end;
	self.turnOn = turned_on;
end

function manureTrailer:fertilizerInRange(dt)
end;

function manureTrailer:delete()
    removeTrigger(self.Trigger);
end;

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

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

function manureTrailer:draw()
end;

function manureTrailer:onAttach()
end; 	

function manureTrailer:onDetach()
end;


ManureTrailerEvent = {};
ManureTrailerEvent_mt = Class(ManureTrailerEvent, Event);

InitEventClass(ManureTrailerEvent, "ManureTrailerEvent");

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

function ManureTrailerEvent:new(vehicle, turned_on)
    self.vehicle = vehicle;
    self.turned_on = turned_on
    return self;
end;

function ManureTrailerEvent:readStream(streamId, connection) 
    local id = streamReadInt32(streamId);
	self.vehicle = networkGetObject(id);
    self.turned_on = streamReadBool(streamId);
    self:run(connection); 
end;

function ManureTrailerEvent:writeStream(streamId, connection)   
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
    streamWriteBool(streamId, self.turned_on );     
end;

function ManureTrailerEvent:run(connection)  
    self.vehicle:setTurnedOn(self.turned_on, true);
	if not connection:getIsServer() then  
		g_server:broadcastEvent(ManureTrailerEvent:new(self.vehicle, self.turned_on), nil, connection, self.object);
	end;
end;

function ManureTrailerEvent.sendEvent(vehicle, turned_on, noEventSend) 
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then 
			g_server:broadcastEvent(ManureTrailerEvent:new(vehicle, turned_on), nil, nil, vehicle);
		else 
			g_client:getServerConnection():sendEvent(ManureTrailerEvent:new(vehicle, turned_on));			
		end;
	end;
end;