--[[************************************************************************************************************************************************************
    
    mrDynamicExhaustingSystem v3.1 (NEW version for MoreRealistic mod)
    
    11/2013 by Saty / http://forum.lsczech.cz
    
****************************************************************************************************************************************************************
    
    Very thanks for :
    
    Manuel Leithner (SFM-Modding) - author of previous version
    Dural - author of MoreRealistic mod & convert DynamicExhaustingSystem for MR
    
****************************************************************************************************************************************************************
    
    (EN) INFO
    
    Free for use on mods. Modifications only with my permission !
    
****************************************************************************************************************************************************************
    
    (CZ) INFO
    
    Pro volne pouziti v modech. ZAKAZ modifikaci bez meho souhlasu !
    
************************************************************************************************************************************************************]]--

mrDynamicExhaustingSystem = {};

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

function mrDynamicExhaustingSystem:load(savegame)
    self.exhaustingSystem = {};
    self.exhaustingSystem.cap = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.dynamicExhaustingSystem#cap"));
    self.exhaustingSystem.axis = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dynamicExhaustingSystem#rotAxis"),1);
    self.exhaustingSystem.maxRot = Utils.degToRad(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dynamicExhaustingSystem#maxRot"),0));
    
    local startSequence = AnimCurve:new(linearInterpolator4);
    local i=0;
    while true do
        local path = string.format("vehicle.dynamicExhaustingSystem.startSequence.key(%d)", i);
        local timeStamp = getXMLFloat(xmlFile, path .. "#time");
        if timeStamp == nil then
            break;
        end;
        local r,g,b,alpha = Utils.getVectorFromString(getXMLString(xmlFile, path .. "#value"));
        startSequence:addKeyframe({x=r, y=g, z=b, w=alpha, time=timeStamp})
        i = i + 1;
    end;
    self.exhaustingSystem.minAlpha = math.min(math.abs(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dynamicExhaustingSystem#minAlpha"),0)),1);
    self.exhaustingSystem.maxAlpha = math.min(math.abs(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.dynamicExhaustingSystem#maxAlpha"),1)),1);
    local x1,y1,z1,w1 = startSequence:get(1.0);
    self.exhaustingSystem.startSequence = startSequence;
    self.exhaustingSystem.lastValue = {x=x1,y=y1,z=z1,w=w1};
    self.exhaustingSystem.param = getXMLString(xmlFile, "vehicle.dynamicExhaustingSystem#param");
    self.exhaustingSystem.offset = 0;
    self.exhaustingSystem.deltaTime = 0;
    self.exhaustingSystem.workAlpha = 0;
end;

function mrDynamicExhaustingSystem:delete()
end;

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

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

function mrDynamicExhaustingSystem:update(dt)
    if self.isMotorStarted then
        if self.time <= self.motorStartTime then
            local time = (self.exhaustingSystem.deltaTime - (self.motorStartTime - self.time)) / self.exhaustingSystem.deltaTime;
            local x1,y1,z1,w1 = self.exhaustingSystem.startSequence:get(time);
            local values = self.exhaustingSystem.lastValue;
            
            if math.abs(values.x - x1) > 0.01 or math.abs(values.y - y1) > 0.01 or math.abs(values.z - z1) > 0.01 or math.abs(values.w - w1) > 0.01 then
                setShaderParameter(self.exhaustParticleSystems[1].shape, self.exhaustingSystem.param, x1, y1, z1, w1, false);
                self.exhaustingSystem.lastValue = {x=x1, y=y1, z=z1, w=w1};
            end;
            
            if self.exhaustingSystem.cap ~= nil then
                -- angle function of engine load on moreRealistic vehicles
                local angle = math.rad(math.random(-20,5)) + self.exhaustingSystem.maxRot * self.exhaustingSystem.lastValue.w;
                if self.exhaustingSystem.maxRot < 0 then
                    angle = math.max(math.min(angle, 0), self.exhaustingSystem.maxRot);
                else
                    angle = math.min(math.max(angle, 0), self.exhaustingSystem.maxRot);
                end;
                local newRot = {};
                local x,y,z = getRotation(self.exhaustingSystem.cap);
                local rot = {x,y,z};
                if self.exhaustingSystem.axis == 2 then
                    newRot = Utils.getMovedLimitedValues(rot, {x,180,z}, {x,angle,z}, 3, 60000, dt, true);
                elseif self.exhaustingSystem.axis == 3 then
                    newRot = Utils.getMovedLimitedValues(rot, {x,y,180}, {x,y,angle}, 3, 60000, dt, true);
                else
                    newRot = Utils.getMovedLimitedValues(rot, {180,y,z}, {angle,y,z}, 3, 60000, dt, true);
                end;
                setRotation(self.exhaustingSystem.cap, unpack(newRot));
            end;
        else
            -- alpha function of engine load on moreRealistic vehicles
            local alpha = ((self.exhaustingSystem.maxAlpha - self.exhaustingSystem.minAlpha) * self.realMotorLoadS) + self.exhaustingSystem.minAlpha;
            -- math alpha with walue from mrPloughingSpec
            if self.workExhaustAlpha ~= nil then
                if self.workExhaustAlpha > 0 then
                    self.exhaustingSystem.workAlpha = math.min(self.workExhaustAlpha, self.exhaustingSystem.workAlpha + 0.05);
                elseif self.workExhaustAlpha == 0 then
                    self.exhaustingSystem.workAlpha = math.max(0, self.exhaustingSystem.workAlpha - 0.05);
                end;
            end;
            alpha = alpha + self.exhaustingSystem.workAlpha;
            
            if math.abs(self.exhaustingSystem.lastValue.w - alpha) > 0.01 then
                local values = self.exhaustingSystem.lastValue;
                setShaderParameter(self.exhaustParticleSystems[1].shape, self.exhaustingSystem.param, values.x, values.y, values.z, alpha, false);
                self.exhaustingSystem.lastValue.w = alpha;
            end;
            
            if self.exhaustingSystem.cap ~= nil then
                -- angle function of engine load on moreRealistic vehicles
                local angle = math.rad(math.random(-20,5)) + self.exhaustingSystem.maxRot * self.realSoundMotorFx;
                if self.exhaustingSystem.maxRot < 0 then
                    angle = math.max(math.min(angle, 0), self.exhaustingSystem.maxRot);
                else
                    angle = math.min(math.max(angle, 0), self.exhaustingSystem.maxRot);
                end;
                local newRot = {};
                local x,y,z = getRotation(self.exhaustingSystem.cap);
                local rot = {x,y,z};
                if self.exhaustingSystem.axis == 2 then
                    newRot = Utils.getMovedLimitedValues(rot, {x,180,z}, {x,angle,z}, 3, 60000, dt, true);
                elseif self.exhaustingSystem.axis == 3 then
                    newRot = Utils.getMovedLimitedValues(rot, {x,y,180}, {x,y,angle}, 3, 60000, dt, true);
                else
                    newRot = Utils.getMovedLimitedValues(rot, {180,y,z}, {angle,y,z}, 3, 60000, dt, true);
                end;
                setRotation(self.exhaustingSystem.cap, unpack(newRot));
            end;
        end;
    else
        if self.exhaustingSystem.cap ~= nil then
            local newRot = {};
            local x,y,z = getRotation(self.exhaustingSystem.cap);
            local rot = {x,y,z};
            if self.exhaustingSystem.axis == 2 then
                newRot = Utils.getMovedLimitedValues(rot, {x,0,z}, {x,self.exhaustingSystem.maxRot,z}, 3, 600, dt, false);
            elseif self.exhaustingSystem.axis == 3 then
                newRot = Utils.getMovedLimitedValues(rot, {x,y,0}, {x,y,self.exhaustingSystem.maxRot}, 3, 600, dt, false);
            else
                newRot = Utils.getMovedLimitedValues(rot, {0,y,z}, {self.exhaustingSystem.maxRot,y,z}, 3, 600, dt, false);
            end;
            setRotation(self.exhaustingSystem.cap, unpack(newRot));
        end;
    end;
end;

function mrDynamicExhaustingSystem:draw()
end;

function mrDynamicExhaustingSystem:startMotor()
    self.exhaustingSystem.deltaTime = self.motorStartTime - self.time - self.exhaustingSystem.offset;
end;
