--
-- manualPipe Specialization for Combines
-- This Specialization lets you choose if you want to unload or not. It also enables the beaconlights a 80%.
--
-- @author  Knagsted
-- @date  16/07/10
-- @edit and almost completely rewritten  Michi77 FS13 ready, bugfixes
-- @date  27/08/13
-- @date  27/08/13 MP-Ready
--


manualPipe = {};

function manualPipe.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Combine, specializations);
end;

function manualPipe:load(savegame)

    self.setPipeRaycastDistance = SpecializationUtil.callSpecializationsFunction("setPipeRaycastDistance");
    self.setManualUnloading = SpecializationUtil.callSpecializationsFunction("setManualUnloading");
    self.myPipe = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.myPipe#index"));
    self.pipeMaxX = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#maxRotX"), 10);
    self.pipeMaxY = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#maxRotY"), -90);
    self.pipeRotationSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#pipeRotationSpeed"), 0.0006);
    self.pipeFlapLid = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeFlapLid#index"));
    
    self.pipeOutLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeOutLight#index"));
    self.showPipeOutLight = false;

    self.pipeOnLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipeOnLight#index"));
    self.showPipeOnLight = false;
    
    self.tankFullLight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.tankFullLight#index"));
    self.showTankFullLight = false;
    
    --Sounds
    UnloadSoundFile = Utils.getFilename("Sounds/unload.wav", self.baseDirectory);
    self.UnloadSoundId = createSample("unload");
    loadSample(self.UnloadSoundId, UnloadSoundFile, false);
    self.UnloadPlaying = false;
    self.UnloadSoundOffset = getSampleDuration(self.UnloadSoundId);
    
    GrainTankFullSoundFile = Utils.getFilename("Sounds/actionSound.wav", self.baseDirectory);
    self.GrainTankFullSoundId = createSample("actionSound");
    loadSample(self.GrainTankFullSoundId, GrainTankFullSoundFile, false);
    self.GrainTankFullPlaying = false;
    self.GrainTankFullSoundOffset = getSampleDuration(self.GrainTankFullSoundId);
    self.playGrainTankFull = false;
    
    self.manualUnloading = false;
    self.wasThreshing = false;
    self.pipeRaycastDistance = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#raycastDistance"));
    self.pipeRaycastDistanceOrig = self.pipeRaycastDistance;
    self.pipeRaycastDistance = 0.1;
    -- {}
    self.beacon = false;
end;

function manualPipe:delete()
    if self.UnloadPlaying ~= nil then
        stopSample(self.UnloadSoundId);
    end;
    
    if self.GrainTankFullPlaying ~= nil then
        stopSample(self.GrainTankFullSoundId);
    end;
end;

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

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

function manualPipe:readStream(streamId, connection)
     local manualUnloading = streamReadBool(streamId)
     self:setManualUnloading(manualUnloading, true);
end;

function manualPipe:writeStream(streamId, connection)   
    streamWriteBool(streamId, self.manualUnloading);
end;

function manualPipe:update(dt)
    if self.isEntered then
        if self.pipeOpen and self.getIsPipeUnloadingAllowed then
            if not self.isAIThreshing and self.pipeOpen and self.fillLevel > 0 then
                if self:getIsActive() and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() and InputBinding.hasEvent(InputBinding.LACTIVATE_UNLOADING) then
                    self:setManualUnloading()
                    if self.UnloadSoundId ~= nil then
                        playSample(self.UnloadSoundId, 1, 0.7, 0);
                    end;
                end;
            end;
        end;
        
        if self.fillLevel >= self.capacity * 0.8 then
            if not self.GrainTankFullPlaying then
                self.playGrainTankFull = true;
            elseif not self.wasThreshing and self.isThreshing then
                self.GrainTankFullPlaying = false;
                self.playGrainTankFull = true;
            end;
            self.showTankFullLight = true;
        else
            self.GrainTankFullPlaying = false;
            self.playGrainTankFull = false;
            self.showTankFullLight = false;
        end;
    end;
    if self.isAIThreshing and not self.manualUnloading then
        self:setManualUnloading()
    end;
    
    if self.isEntered then
        local trailer, trailerDistance = self:findTrailerToUnload(self.currentFillType);
        if trailer == nil and self.manualUnloading then
            self:setManualUnloading()
        end;
    end;
    
    if self.fillLevel > self.capacity * 0.8 and not self.beaconLightsActive then
        self.beacon = true
        self:setBeaconLightsVisibility(true);
    end;
    if self.fillLevel < self.capacity * 0.8 and self.beacon then
        self:setBeaconLightsVisibility(false);
        self.beacon = false
    end;
    
    if self.tankFullLight ~= nil then
        setVisibility(self.tankFullLight, self.showTankFullLight);
    end;
    
    if self.playGrainTankFull then
        if self.GrainTankFullSoundId ~= nil and not self.GrainTankFullPlaying then
            playSample(self.GrainTankFullSoundId, 1, 0.9, 0);
            self.GrainTankFullPlaying = true;
            self.playGrainTankFull = false;
        end;
    end;
    
    if self.manualUnloading then
        self.showPipeOnLight = true;
    else
        self.showPipeOnLight = false;
    end;
    if self.pipeOnLight ~= nil then
        setVisibility(self.pipeOnLight, self.showPipeOnLight);
    end;
    
--[[    if self.manualUnloading then
        self.pipeRaycastDistance = pipeDistance;
    end--]]
    if not self.manualUnloading then
        self.pipeRaycastDistance = 0.1;
    end


    if not self.isAIThreshing then
        if self.pipeOpen then
            if self.fillLevel > 0 then
                if self.fillLevel <= 0.0 then
                   self.fillLevel = 0.0;
                end;
            else
                self.myPipeParticleActivated = false;
            end;
        end;
        
        if self.currentGrainTankFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
            if self.currentManualPipeParticleSystem ~= nil then
                Utils.setEmittingState(self.currentManualPipeParticleSystem, false);
            end;
            if self.myPipeParticleActivated and self.currentGrainTankFruitType ~= nil then
                self.currentManualPipeParticleSystem = self.pipeParticleSystems[self.currentGrainTankFruitType];
                if self.currentManualPipeParticleSystem == nil then
                    self.currentManualPipeParticleSystem = self.defaultPipeParticleSystem;
                end;
                Utils.setEmittingState(self.currentManualPipeParticleSystem, true);
            end;
        else
            if self.currentManualPipeParticleSystem ~= nil then
                Utils.setEmittingState(self.currentManualPipeParticleSystem, false);
            end;
        end;
    end;
        
    local x,y,z = getRotation(self.myPipe);
    if y < 0 and y > Utils.degToRad(-89) then
        self.pipeOpening = true;
    elseif y < Utils.degToRad(-89) then
        self.pipeOpen = true;
    else
        self.pipeOpen = false
        self.pipeOpening = false;
    end;
    
    if not self.pipeOpening then
        self.showPipeOutLight = false;
    else
        self.showPipeOutLight = true;
    end;
    if self.pipeOutLight ~= nil then
        setVisibility(self.pipeOutLight, self.showPipeOutLight);
    end;
    
    self.wasThreshing = self.isThreshing;
--[[if self:getIsActive() and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() and InputBinding.hasEvent(InputBinding.DEBUG) then
        print(self.pipeRaycastDistance);
        print(self.manualUnloading);
    end; --]]
end;

function manualPipe:setManualUnloading(manualUnloading, noEventSend)
    if manualUnload == nil then
        self.manualUnloading = not self.manualUnloading
    else
        --self.manualUnloading = manualUnload
    end;
    
    if self.manualUnloading then
        self.pipeRaycastDistance = self.pipeRaycastDistanceOrig; 
        --self.unloadingStates = self.unloadingStatesOrig;
    else
        self.pipeRaycastDistance = 0.1; 
        --self.unloadingStates = 0;
    end;
    manualPipeEvent.sendEvent(self, self.manualUnloading, noEventSend);
end;

function manualPipe:draw()
    if self.pipeOpen and self.manualUnloading then
        g_currentMission:addHelpButtonText(g_i18n:getText("Stopdumpinggrain"), InputBinding.LACTIVATE_UNLOADING);
    elseif self.pipeOpen and not self.manualUnloading then
        g_currentMission:addHelpButtonText(g_i18n:getText("Startdumpinggrain"), InputBinding.LACTIVATE_UNLOADING);
    end;
end;

-- Event


manualPipeEvent = {};
manualPipeEvent_mt = Class(manualPipeEvent, Event);

InitEventClass(manualPipeEvent, "manualPipeEvent");

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

function manualPipeEvent:new(vehicle, manualUnloading, streamId)
    local self = manualPipeEvent:emptyNew()
    self.vehicle = vehicle;
    self.manualUnloading = manualUnloading;
    return self;
end;

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

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

function manualPipeEvent:run(connection)
    self.vehicle:setManualUnloading(self.manualUnloading, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(manualPipeEvent:new(self.vehicle, self.manualUnloading), nil, connection, self.vehicle);
    end;
end;

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