--
-- manualIgnition
-- Specialization for manual Motor Ignition
--
-- @author  Templaer
-- @date  01/05/09
--
-- Modifikationen erst nach Rücksprache
-- Do not edit without my permission
--
-- @LS11 multiplayer ready: Andreas Schneider <aksdb@gmx.de> (24.10.2010)
-- V3 by Mofa-Killer

-- @ Add Aisound MP ready: Ago-Systemtech -- T.I.F. Tractor-italia.net--- (25.05.2012)

manualIgnition = {};

function manualIgnition.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function manualIgnition:load(savegame)
    self.invokeIgnition = SpecializationUtil.callSpecializationsFunction("invokeIgnition");

    -- Booleans
    self.ignitionKey = false;
    self.allowedIgnition = false;  
    
    self.fuelConsumption = 0;
    self.distanceDriven = 0;
    self.fuelUsed = 0;
    self.runningTime = 0;
    local motorSoundLeave  = getXMLString(xmlFile, "vehicle.motorSoundLeave#file");
    if motorSoundLeave  ~= nil and motorSoundLeave  ~= "" then
        motorSoundLeave  = Utils.getFilename(motorSoundLeave, self.baseDirectory);
        self.motorSoundLeavePitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.motorSoundLeave#pitchOffset"), 1);
        self.motorSoundLeaveRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.motorSoundLeave#radius"), 150);
        self.motorSoundLeaveInnerRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.motorSoundLeave#innerRadius"), 20);
        self.motorSoundLeaveVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.motorSoundLeave#volume"), 0.2);
        self.motorSoundLeave = createAudioSource("motorSoundLeave", motorSoundLeave, self.motorSoundLeaveRadius, self.motorSoundLeaveInnerRadius, self.motorSoundLeaveVolume, 0);
        link(self.components[1].node, self.motorSoundLeave);
        setVisibility(self.motorSoundLeave, false);
    end;
    local aiMotorSound  = getXMLString(xmlFile, "vehicle.aiMotorSound2#file");
    if aiMotorSound  ~= nil and aiMotorSound  ~= "" then
        aiMotorSound  = Utils.getFilename(aiMotorSound, self.baseDirectory);
        self.aiMotorSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.aiMotorSound#pitchOffset"), 1);
        self.aiMotorSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.aiMotorSound#pitchScale"), 0.02);
        self.aiMotorSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.aiMotorSound#pitchMax"), 1.40);
        self.aiMotorSoundRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.aiMotorSound#radius"), 150);
        self.aiMotorSoundInnerRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.aiMotorSound#innerRadius"), 20);
        self.aiMotorSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.aiMotorSound#volume"), 1.5);
        self.aiMotorSound = createAudioSource("aiMotorSound2", aiMotorSound, self.aiMotorSoundRadius, self.aiMotorSoundInnerRadius, self.aiMotorSoundPitchScale, self.aiMotorSoundPitchOffset, self.aiMotorSoundPitchMax, self.aiMotorSoundVolume, 0);
        link(self.components[1].node, self.aiMotorSound);
        setVisibility(self.aiMotorSound, false);
    end;
    
    -- Backup Stop Sound volume
    self.motorStopSoundVolume2 = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.motorStopSound#volume"), 1.0);
    
    self.isMIActor = false;
end;

function manualIgnition:readStream(streamId, connection)
    self.ignitionKey = streamReadBool(streamId);
    self.isMotorStarted = self.ignitionKey;
    self.steeringEnabled = self.ignitionKey;
    Utils.setEmittingState(self.exhaustParticleSystems, self.ignitionKey);
    setVisibility(self.aiMotorSound, self.ignitionKey);
    setVisibility(self.motorSoundLeave, self.ignitionKey);
    
    self.fuelConsumption = streamReadFloat32(streamId);
    self.distanceDriven = streamReadFloat32(streamId);
    self.fuelUsed = streamReadFloat32(streamId);
    self.runningTime = streamReadFloat32(streamId);
end;

function manualIgnition:writeStream(streamId, connection)
    streamWriteBool(streamId, self.ignitionKey);
    streamWriteFloat32(streamId, self.fuelConsumption);
    streamWriteFloat32(streamId, self.distanceDriven);
    streamWriteFloat32(streamId, self.fuelUsed);
    streamWriteFloat32(streamId, self.runningTime);
end;

function manualIgnition:delete()
end;

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

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

function manualIgnition:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
    local runningTime =  Utils.getNoNil(getXMLFloat(xmlFile, key.."#runningTime"),0);
    self.runningTime = runningTime;
    local distanceDriven =  Utils.getNoNil(getXMLFloat(xmlFile, key.."#distanceDriven"),0);
    self.distanceDriven = distanceDriven;
    local fuelUsed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#fuelUsed"), 0);
    self.fuelUsed = fuelUsed;
    return BaseMission.VEHICLE_LOAD_OK;
end;

function manualIgnition:getSaveAttributesAndNodes(nodeIdent)
    local runningTime = Utils.getNoNil(self.runningTime, 10);
    local distanceDriven = Utils.getNoNil(self.distanceDriven, 10);
    local fuelUsed = Utils.getNoNil(self.fuelUsed, 10);
    local attributes = 'runningTime="'..string.format("%f", runningTime)..'"'..' distanceDriven="'..string.format("%f", distanceDriven)..'"'..' fuelUsed="'..string.format("%f", fuelUsed)..'"';
    return attributes, nil;
end;

function manualIgnition:update(dt)
    acceleration = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
    if InputBinding.isAxisZero(acceleration) then
        acceleration = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
    end;

     if self.isMotorStarted and not self.isFuelFilling then
        local kmMs = self.lastSpeed*self.speedDisplayScale / 1000;
        self.distanceDriven = self.distanceDriven + (kmMs * dt);
        self.runningTime = self.runningTime + (dt / 1000 / 60 / 60);
        self.fuelConsumption = (self.lastMovedDistance*self.fuelUsage / dt) * 1000 * 60 * 60;
        self.fuelUsed = self.fuelUsed + self.lastMovedDistance*self.fuelUsage;
    end;
    
    -- Does not execute when AI is activated
    if not self.isAITractorActivated then
        -- Handles ignition key input
        if self:getIsActiveForInput() then
         --if self:getIsActive() then
            if InputBinding.hasEvent(InputBinding.SDF_START or InputBinding.SDF_STOP) then
                self.ignitionKey = not self.ignitionKey;
                self.allowedIgnition = true;
            end;
            
            -- Turn on the engine when pressing the accelerator
            if math.abs(acceleration) > 0.3 and self.isMotorStarted == false then
                self.ignitionKey = true;
                self.allowedIgnition = true;
            end;
        end;
        
        -- Mutes stop sound when engine is off
        if not self.ignitionKey or not self.deactivateOnLeave then
            self.motorStopSoundVolume = 0;
        else
            self.motorStopSoundVolume = self.motorStopSoundVolume2;
        end;
                                
        if self.ignitionKey and self.allowedIgnition then    
            ManualIgnitionEvent.sendEvent(self, true);
            self:startMotor();
            self.allowedIgnition = false;
            self.deactivateOnLeave = false;
            self.steeringEnabled = true;
            Utils.setEmittingState(self.exhaustParticleSystems, true);
        elseif not self.ignitionKey and self.allowedIgnition then
            ManualIgnitionEvent.sendEvent(self, false);
            if self.motorStopSoundVolume == 0 then
                self.motorStopSoundVolume = self.motorStopSoundVolume2;
            end;
            
            self:stopMotor();
            self.allowedIgnition = false;
            self.steeringEnabled = false;
            self.deactivateOnLeave = true;
            setVisibility(self.aiMotorSound, false);
            setVisibility(self.motorSoundLeave, false);
            
            -- Brakes the wheels upon turning off the engine
            if self.isServer then
                for k,wheel in pairs(self.wheels) do
                    setWheelShapeProps(wheel.node, wheel.wheelShape, 0, self.motor.brakeForce, 0);
                end;
            end;
            -- self:onDeactivateAttachements();
        end;
        
    -- Prevents the AI from working when engine is off
    elseif not self.ignitionKey and not self.deactivateOnLeave then
        self:stopAITractor();
    end;
end;

function manualIgnition:onLeave()
    if not self.deactivateOnLeave then
        Utils.setEmittingState(self.exhaustParticleSystems, true);
        self.allowedIgnition = false;
        self.isMotorStarted = true;
        self.ignitionKey = true; 
        self.steeringEnabled = false;
        
        if self.isAITractorActivated then
          setVisibility(self.aiMotorSound, true);
        else
          setVisibility(self.motorSoundLeave, true);
          setVisibility(self.aiMotorSound, false);
        end;
        
        if self.isServer then
            for k,wheel in pairs(self.wheels) do
                setWheelShapeProps(wheel.node, wheel.wheelShape, 0, self.motor.brakeForce, 0);
            end;
        end;
    else
        self.allowedIgnition = false;
        self.isMotorStarted = false;
        self.ignitionKey = false;
    end;
    
    if self.isMIActor then
        -- Update the stats for other clients (who could possibly enter the vehicle now)
        ManualIgnitionStatsEvent.sendEvent(self);
        self.isMIActor = false;
    end;
end;

function manualIgnition:onEnter()
    self.isMIActor = self.isEntered;

    -- Prevents the engine from starting upon entering
    if not self.ignitionKey then
        self.isMotorStarted = false;
        Motorized.stopSounds(self);
        self.steeringEnabled = false;
        Utils.setEmittingState(self.exhaustParticleSystems, false);
    else
        self.steeringEnabled = true;
        
    end;
    
    
    if self.isEntered then
        setVisibility(self.motorSoundLeave, false);
        setVisibility(self.aiMotorSound, false);
    else
        setVisibility(self.motorSoundLeave, self.ignitionKey);
        setVisibility(self.aiMotorSound, self.ignitionKey);
    end;
end;

function manualIgnition:draw()
    if not self.isMotorStarted then
        ---g_currentMission:addHelpButtonText(g_i18n:getText("IGNITION_START"), InputBinding.IGNITION_START);
    else
        ---g_currentMission:addHelpButtonText(g_i18n:getText("IGNITION_STOP"), InputBinding.IGNITION_STOP);
    end;
end;

function manualIgnition:invokeIgnition(isRunning)
    if self.ignitionKey ~= isRunning then
        self.ignitionKey = isRunning;
        if isRunning then            
            self:startMotor();
            self.allowedIgnition = false;
            self.deactivateOnLeave = false;
            self.steeringEnabled = true;
            Utils.setEmittingState(self.exhaustParticleSystems, true);            
        else            
            if self.motorStopSoundVolume == 0 then
                self.motorStopSoundVolume = self.motorStopSoundVolume2;
            end;
            
            self:stopMotor();
            self.allowedIgnition = false;
            self.steeringEnabled = false;
            self.deactivateOnLeave = true;
            setVisibility(self.aiMotorSound, false);
            setVisibility(self.motorSoundLeave, false);
            
            -- Brakes the wheels upon turning off the engine
            if self.isServer then
                for k,wheel in pairs(self.wheels) do
                    setWheelShapeProps(wheel.node, wheel.wheelShape, 0, self.motor.brakeForce, 0);
                end;
            end;
            -- self:onDeactivateAttachements();            
        end;
    end;
end;