--
-- Beleuchtung v3.1.2
-- Specialization for additional lights
-- Spezialisierung für Zusatzbeleuchtung
-- @author  Sven777b
-- 
-- frei verwendbar - keine erlaubnis nötig  |  free for use - no permission needed.
-- Modifikationen erst nach Rücksprache!    |  modifications only with my permission.
--
-- Hinweis: das kopieren von Sourcecode ist strafbar nach UrhG §2.1

BEL3 = {};
function BEL3.prerequisitesPresent(specializations)
    return true;
end;

function BEL3:load(savegame)
    local error = "Error: Beleuchtung V3 - %s (%s)";
    self.setState = SpecializationUtil.callSpecializationsFunction("setState");
    self.deactivate = SpecializationUtil.callSpecializationsFunction("deactivate");
    self.activate = SpecializationUtil.callSpecializationsFunction("activate");
    
    self.B3 = {}; 
    local i = 0; local fin = false;
    while true do
        while true do
            local on = string.format("vehicle.lightsaddon.light(%d)",i);
            local lt = getXMLString(xmlFile, on .. "#type");
            if lt == nil then fin=true; break; end;
            local is = getXMLString(xmlFile, on .. "#index");
            if is == nil then
                print(string.format(error,"kein Index definiert",on));
                i=i+1;
                break;
            end;
            local index = Utils.indexToObject(self.components, is);
            if index == nil or index == 0 then
                print(string.format(error,"Index "..is.." nicht gefunden",on));
                i=i+1;
                break;
            end;
            
            local tl = {};
            tl.na = getXMLString(xmlFile, on .. "#inputName");
            tl.index = index;
            tl.so = Utils.getNoNil(getXMLBool(xmlFile, on .. "#stayOn"),false);
            if lt == "work" then
                tl.ds = Utils.getNoNil(getXMLBool(xmlFile, on .. "#defaultOn"),false);
            else
                tl.ds = false;
            end;
            tl.a = tl.ds;
            tl.ht = getXMLString(xmlFile, on .. "#helptext");
            local rl = getXMLString(xmlFile,on.."#real");
            if rl ~= nil then
                tl.rl = Utils.indexToObject(self.components, rl);
            end;
            local fl = getXMLString(xmlFile,on.."#beam");
            if fl ~= nil then
                tl.fl = Utils.indexToObject(self.components, fl);
            end;
            
            if lt == "strobe" then
                local sq = getXMLString(xmlFile, on.."#sequence");
                tl.ls = false;
                tl.ns = 0;
                tl.t = 1;
                if sq ~= nil then
                    tl.rnd = false;
                    tl.sq = {Utils.getVectorFromString(sq)};
                    tl.inv = Utils.getNoNil(getXMLBool(xmlFile, on.."#invert"),false);
                    tl.ls = tl.inv;
                    tl.ss = 1;
                else
                    tl.rnd = true;
                    tl.rndnn = Utils.getNoNil(getXMLInt(xmlFile, on.."#minOn"),100);
                    tl.rndxn = Utils.getNoNil(getXMLInt(xmlFile, on.."#maxOn"),100);
                    tl.rndnf = Utils.getNoNil(getXMLInt(xmlFile, on.."#minOff"),100);
                    tl.rndxf = Utils.getNoNil(getXMLInt(xmlFile, on.."#maxOff"),400);
                    math.randomseed( os.time() ); math.random();
                end;
            end;
            if self.B3[lt] == nil then
                self.B3[lt] = {};
            end;
            table.insert(self.B3[lt],tl);
            setVisibility(tl.index, false);
            if tl.fl ~= nil then
                setVisibility(tl.fl, false);
            end;
            if tl.rl ~= nil then
                setVisibility(tl.rl, false);
            end;
            i=i+1;
        end;
        if fin then break; end;
    end;

    if self.B3.work ~= nil then
        for i=1,table.getn(self.B3.work) do
            self:setState("work:"..i,self.B3.work[i].a,true);
        end;
    end;
    
    local flwp = getXMLFloat(xmlFile, "vehicle.lightsaddon.fillLevelWarning#percent");
    if flwp ~= nil and self.grainTankCapacity ~= nil then
        self.B3.flw = {};
        self.B3.flw.p = flwp;
        self.B3.flw.a = false;
    end;
    
    self.B3.ab = false;
    if table.getn(self.beaconLights) > 0 then
        local i=0;
        while true do
            local str = string.format("vehicle.beaconLights.beaconLight(%d)#",i);
            if getXMLString(xmlFile, str.."index") == nil then break end;
            local rotNode = getXMLString(xmlFile, str.."rotIndex");
            if rotNode ~= nil then
                self.beaconLights[i+1].rotNode = Utils.indexToObject(self.components, rotNode);
                self.beaconLights[i+1].rotSpeed = self.beaconLights[i+1].speed;
                self.beaconLights[i+1].speed = 0;
                self.B3.ab = true;
            end;
            i=i+1;
        end;
        self.B3.blso = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.beaconLights#stayOn"),false);
    end;
    
    self.B3.sab = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.lightsaddon#strobesAreBeacons"),false);
    if self.B3.strobe == nil then
        self.B3.sab = false;
    end;
    if self.B3.sab == true then
        for i=1,table.getn(self.B3.strobe) do
            self.B3.strobe.na = nil;
            self.B3.strobe.ht = nil;
        end;
    end;


    local bsf = getXMLString(xmlFile, "vehicle.lightsaddon.flashers#soundfile");
    if bsf ~= nil then
        self.B3.bss = createSample("flasherSound");
        loadSample(self.B3.bss, Utils.getFilename(bsf,self.baseDirectory), false);
        self.B3.bsl = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon.flashers#lowPitch"),0.8);
        self.B3.bsh = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon.flashers#highPitch"),1.0);
        self.B3.bsv = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon.flashers#volume"),1.0);
    end;
    self.B3.dar = Utils.getNoNil(getXMLBool(xmlFile,"vehicle.lightsaddon.flashers#autoreturn"),false);
    self.B3.art = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon.flashers#tolerance"),0.3);

    local tsf = Utils.getNoNil(getXMLString(xmlFile,"vehicle.lightsaddon.toggleSound#file"),"$dataS2/sounds/switchFlashlight.wav");
    local tsp = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon.toggleSound#pitch"),1.0);
    self.B3.tsv = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon.toggleSound#volume"),1.0);
    self.B3.tss = createSample("tss");
    loadSample(self.B3.tss, Utils.getFilename(tsf,self.baseDirectory), false);
    setSamplePitch(self.B3.tss, tsp);
    
    self.B3.lso = Utils.getNoNil(getXMLBool(xmlFile,"vehicle.lightsaddon#lightsStayOn"),false);
    self.B3.md = Utils.getNoNil(getXMLInt(xmlFile,"vehicle.lightsaddon#modDirection"),1);
    self.B3.bspd   = Utils.getNoNil(getXMLFloat(xmlFile,"vehicle.lightsaddon#blinkSpeed"),0.5) * 1000;
    
    self.B3.atv = nil;
    self.B3.setLA = false;
    self.B3.noRL = false;
    self.B3.wl = false;
    self.B3.blt = 0;
    self.B3.lsa = false;
    self.B3.bls = false;
    self.B3.left = false;
    self.deactivateLightsOnLeave = not self.B3.lso;
    if SpecializationUtil.hasSpecialization(Steerable, self.specializations) then
        self.B3.iSt = true;
    else
        self.B3.iSt = false;
    end;
    self.isSelectable = true;
end;

function BEL3:delete()
    if self.B3.bss ~= nil then
        delete(self.B3.bss);
    end;
    if self.B3.tss ~= nil then
        delete(self.B3.tss);
    end;
end;

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

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

function BEL3:readStream(streamId, connection)
    if self.B3.work ~= nil then
        for i=1,table.getn(self.B3.work) do
            self:setState("work:"..i,streamReadBool(streamId),true);
        end;
    end;
    if self.B3.strobe ~= nil then
        for i=1,table.getn(self.B3.strobe) do
            self:setState("strobe:"..i,streamReadBool(streamId),true);
        end;
    end;
    if self.B3.highbeam ~= nil then
        self:setState("highbeam",streamReadBool(streamId),true);
    end;
    if self.B3.dirLeft ~= nil and self.B3.dirRight ~= nil then
        self:setState("dirLeft",streamReadBool(streamId),true);
        self:setState("dirRight",streamReadBool(streamId),true);
        self:setState("warnlights",streamReadBool(streamId),true);
    end;
    if self.B3.parkLeft ~= nil and self.B3.parkRight ~= nil then
        self:setState("parkLeft",streamReadBool(streamId),true);
        self:setState("parkRight",streamReadBool(streamId),true);
    end;
end;

function BEL3:writeStream(streamId, connection)
    if self.B3.work ~= nil then
        for k,v in pairs(self.B3.work) do
            streamWriteBool(streamId, v.a);
        end;
    end;
    if self.B3.strobe ~= nil then
        for k,v in pairs(self.B3.strobe) do
            streamWriteBool(streamId, v.a);
        end;
    end;
    if self.B3.highbeam ~= nil then
        streamWriteBool(streamId, self.B3.highbeam[1].a);
    end;
    if self.B3.dirLeft ~= nil and self.B3.dirRight ~= nil then
        streamWriteBool(streamId,self.B3.dirLeft[1].a);
        streamWriteBool(streamId,self.B3.dirRight[1].a);
        streamWriteBool(streamId,self.B3.wl);
    end;
    if self.B3.parkLeft ~= nil and self.B3.parkRight ~= nil then
        streamWriteBool(streamId,self.B3.parkLeft[1].a);
        streamWriteBool(streamId,self.B3.parkRight[1].a);
    end;
end;

function BEL3:update(dt)
    local updateState = {};
    if self:getIsActiveForInput() then
        if self.B3.work ~= nil then
            for i=1,table.getn(self.B3.work) do
                local wl = self.B3.work[i];
                if InputBinding.hasEvent(InputBinding[wl.na]) and InputBinding[wl.na] ~= nil and wl.na ~= nil then
                    self:setState("work:"..i,not wl.a);
                    if self:getIsActiveForSound() then
                        playSample(self.B3.tss, 1, self.B3.tsv, 0);
                    end;
                end;
            end;
        end;
        if self.B3.strobe ~= nil then
            for i=1,table.getn(self.B3.strobe) do
                local sl = self.B3.strobe[i];
                if InputBinding.hasEvent(InputBinding[sl.na]) and InputBinding[sl.na] ~= nil and sl.na ~= nil then
                    self:setState("strobe:"..i,not sl.a);
                    if self:getIsActiveForSound() then
                        playSample(self.B3.tss, 1, self.B3.tsv, 0);
                    end;
                end;
            end;
        end;
        if self.B3.highbeam ~= nil then
            local hb = self.B3.highbeam[1];
            if InputBinding.isPressed(InputBinding.TOGGLE_LIGHTS) then
                if hb.cnt == nil then
                    hb.cnt = 0;
                    if not self.lightsActive then
                        self.B3.setLA = true;
                        self:setLightsVisibility(true);
                    end;
                else
                    if hb.blk == nil then 
                        hb.cnt = hb.cnt + dt;
                        self.B3.noRL = not hb.a;
                    end;
                end;
                if hb.cnt > 1500 and hb.blk == nil then
                    self:setState("highbeam", not hb.a);
                    self.B3.setLA = false;
                    self.B3.noRL = not hb.a;
                    hb.blk = true;
                end;
            else
                if hb.cnt ~= nil and hb.blk == nil then
                    if self.B3.setLA then
                        hb.a = false;
                        self.B3.setLA = false;
                        self:setLightsVisibility(false);
                        self:setState("highbeam", false);
                    else
                        self.B3.setLA = false;
                    end;
                end;
                hb.cnt = nil;
                hb.blk = nil;
            end;
        end;
        
        if self.B3.dirLeft ~=nil and self.B3.dirRight ~= nil then
            local dl = self.B3.dirLeft[1]; local dr = self.B3.dirRight[1];
            if not self.B3.wl then
                if InputBinding.hasEvent(InputBinding.BEL3LEFT) then
                    if self:getIsActiveForSound() then
                        playSample(self.B3.tss, 1, self.B3.tsv, 0);
                    end;
                    self:setState("dirLeft",not dl.a);
                    self:setState("dirRight", false);
                end;
                if InputBinding.hasEvent(InputBinding.BEL3RIGHT) then
                    if self:getIsActiveForSound() then
                        playSample(self.B3.tss, 1, self.B3.tsv, 0);
                    end;
                    self:setState("dirLeft", false);
                    self:setState("dirRight", not dr.a);
                end;
            end;
            if InputBinding.hasEvent(InputBinding.BEL3WARN) then
                if self:getIsActiveForSound() then
                    playSample(self.B3.tss, 1, self.B3.tsv, 0);
                end;
                self:setState("warnlights",not self.B3.wl);
                self:setState("dirLeft",self.B3.wl);
                self:setState("dirRight",self.B3.wl);
            end;
        end;
    end;
    
    if self.B3.strobe ~= nil then
        for _,st in ipairs(self.B3.strobe) do
            if st.a then
                if st.t > st.ns then
                    st.ls = not st.ls;
                    setVisibility(st.index, st.ls);
                    st.t = 0;
                    if st.rnd then
                        if st.ls then
                            st.ns = math.random(st.rndnn,st.rndxn);
                        else
                            st.ns = math.random(st.rndnf,st.rndxf);
                        end;
                    else
                        st.ss = st.ss + 1; 
                        if st.ss > table.getn(st.sq) then st.ss = 1; end;
                        st.ns = st.sq[st.ss];
                    end;
                else
                    st.t = st.t + dt;
                end;
            end;
        end;
    end;
    
    if self.isServer and self:getIsActive() then
        if self.B3.brake ~= nil and self.B3.iSt then
            local iB = math.abs(Utils.sign(self.lastAcceleration)+ (-self.movingDirection*self.B3.md)) == 2;
            if self.B3.brake[1].a ~= iB then
                self:setState("brake",iB);
            end;
        end;
        if self.B3.reverse ~= nil then
            local iR = (self.movingDirection*self.B3.md) < 0;
            if self.B3.reverse[1].a ~= iR then         
                self:setState("reverse",iR);
            end;
        end;
    end;
    
    if self.B3.ab and self.B3.bla then
        for _,bl in ipairs(self.beaconLights) do
            if bl.rotNode ~= nil then
                rotate(bl.rotNode, 0, bl.rotSpeed*dt, 0);
            end;
        end;
    end;
    
end;

function BEL3:updateTick(dt)

    if self.B3.dirLeft ~=nil and self.B3.dirRight ~= nil then
        local dl = self.B3.dirLeft; local dr = self.B3.dirRight;
        if dl[1].a or dr[1].a then
            if self.B3.blt > self.B3.bspd then
                self.B3.bls = not self.B3.bls;
                self.B3.blt = 0;
                if dl[1].a then
                    for _,b in pairs(dl) do
                        setVisibility(b.index,not self.B3.bls);
                    end;
                end;
                if dr[1].a then
                    for _,b in pairs(dr) do
                        setVisibility(b.index,not self.B3.bls);
                    end;
                end;
                --blinkersound
                if self:getIsActiveForSound() and self.B3.bss then
                    if self.B3.bls then
                        setSamplePitch(self.B3.bss, self.B3.bsl);
                    else
                        setSamplePitch(self.B3.bss, self.B3.bsh);
                    end;
                    playSample(self.B3.bss, 1, self.B3.bsv, 0);
                end;
            else
                self.B3.blt = self.B3.blt+dt;
            end;
            if self.B3.dar and not self.B3.wl then
                local rtp = math.abs(self.rotatedTime/self.maxRotTime);
                if not self.B3.lsa then
                    if rtp > self.B3.art then
                        self.B3.lsa = true;
                    end;
                else
                    if rtp < self.B3.art then
                        self.B3.lsa = false;
                        self:setState("dirLeft",false);
                        self:setState("dirRight",false);
                        if self:getIsActiveForSound() then
                            playSample(self.B3.tss, 1, self.B3.tsv, 0);
                        end;
                    end;
                end;
            end;
        else
            self.B3.blt = 0;
            if self.B3.bls == true then
                for _,b in pairs(dl) do
                    setVisibility(b.index,false);
                end;
                for _,b in pairs(dr) do
                    setVisibility(b.index,false);
                end;
                self.B3.bls = false;
            end;
        end;
    end;
    
    if self.B3.highbeam and self.realLightsActive then
        if self.B3.highbeam[1].a and not self.B3.noRL then
            for _,light in pairs(self.lights) do
                setVisibility(light,false);
            end;
            self.B3.noRL = true;
        elseif not self.B3.highbeam[1].a and self.B3.noRL then
            for _,light in pairs(self.lights) do
                setVisibility(light,true);
            end;
            self.B3.noRL = false;
        end;
    end;

    if self:getIsActive() and not self.B3.iSt and self.B3.atv ~= nil then
        local atvb = false;
        if self.B3.atv.B3 ~= nil then 
            local atv = self.B3.atv.B3;
            if atv.brake ~= nil and self.B3.brake ~= nil then
                atvb = true;
                if self.B3.brake[1].a ~= atv.brake[1].a then
                    self:setState("brake",atv.brake[1].a,true);
                end;
            end;
            if atv.reverse ~= nil and self.B3.reverse ~= nil then
                if self.B3.reverse[1].a ~= atv.reverse[1].a then
                    self:setState("reverse",atv.reverse[1].a,true);
                end;
            end;
            if self.B3.dirLeft ~=nil and self.B3.dirRight ~= nil then
                if atv.wl ~= self.B3.wl then
                    self:setState("warnlights",not self.B3.wl);
                    self:setState("dirLeft",self.B3.wl);
                    self:setState("dirRight",self.B3.wl);
                else
                    if atv.dirLeft ~= nil and atv.dirRight ~= nil then
                        if atv.dirLeft[1].a ~= self.B3.dirLeft[1].a or atv.dirRight[1].a ~=  self.B3.dirRight[1].a then
                            self:setState("dirLeft", atv.dirLeft[1].a);
                            self:setState("dirRight", atv.dirRight[1].a);
                        end;
                    end;
                end;
            end;
        end;
        if not atvb and self.B3.brake ~= nil then
            local iB = math.abs(Utils.sign(self.B3.atv.lastAcceleration)+ (-self.movingDirection*self.B3.md)) == 2;
            if self.B3.brake[1].a ~= iB then
                self:setState("brake",iB);
            end;
        end;
    end;
    
    if self:getIsActive() then
        if self.B3.flw ~= nil then
            if not self.B3.flw.a then
                if self.grainTankFillLevel > 0 and not self.beaconLightsActive then
                    local p = self.grainTankFillLevel * 100 / self.grainTankCapacity;
                    if p >= self.B3.flw.p then
                        self:setBeaconLightsVisibility(true);
                        self.B3.flw.a = true;
                    end;
                end;
            else
                if self.beaconLightsActive then
                    local p = self.grainTankFillLevel * 100 / self.grainTankCapacity;
                    if p < self.B3.flw.p then
                        self:setBeaconLightsVisibility(false);
                        self.B3.flw.a = false;
                    end;
                end;
            end;
        end;

        self.B3.bla = self.beaconLightsActive;
        
        if self.B3.sab and self.B3.strobe ~= nil and self.beaconLightsActive ~= nil then
            if self.B3.strobe[1].a ~= self.beaconLightsActive then
                for i=1,table.getn(self.B3.strobe) do
                    self:setState("strobe:"..i, self.beaconLightsActive);
                end;
            end;
        end;

        if self.B3.drl ~= nil then
            if self.B3.drl[1].a == self.lightsActive then
                self:setState("drl", not self.lightsActive);
            end;
        end;

    end;
    
    if self.currentPipeState ~= nil and self.B3.pipe ~= nil then
        if (self.currentPipeState > 1) ~= self.B3.pipe[1].a then
            self:setState("pipe", self.currentPipeState > 1, true);
        end;
    end;
    
    if self.B3.bla and not self.beaconLightsActive then
        self:setBeaconLightsVisibility(true, true);
    end;
    
end;

function BEL3:draw()
    if self.B3.work ~= nil then
        for i=1,table.getn(self.B3.work) do
            local wl = self.B3.work[i];
            if wl.ht ~= nil and wl.na ~= nil then
                g_currentMission:addHelpButtonText(g_i18n:getText(wl.ht), InputBinding[wl.na]);
            end;
        end;
    end;
    if self.B3.strobe ~= nil then
        for i=1,table.getn(self.B3.strobe) do
            local sl = self.B3.strobe[i];
            if sl.ht ~= nil and sl.na ~= nil then
                g_currentMission:addHelpButtonText(g_i18n:getText(sl.ht), InputBinding[sl.na]);
            end;
        end;
    end;
end;

function BEL3:onAttach()
    local atv = self.attacherVehicle;
    self.B3.bbspd = self.B3.bspd;
    while true do 
        if atv.attacherVehicle ~= nil then
            atv = atv.attacherVehicle;
        else 
            break;
        end;
    end;
    self.B3.atv = atv;
    if atv.B3 ~= nil then
        if atv.B3.bspd ~= nil then
            self.B3.bspd = atv.B3.bspd;
        end;
    end;
    if atv.beaconLightsActive then
        self:setBeaconLightsVisibility(atv.beaconLightsActive);
    end;
    self:activate();
end;

function BEL3:onDetach()
    self.B3.atv = nil;
    if self.B3.bbspd ~= nil then
        self.B3.bspd = self.B3.bbspd;
    end;
    self:deactivate();
end;            

function BEL3:onDeactivate()
    self:deactivate();
end;

function BEL3:onLeave()
    self:deactivate();
end;

function BEL3:deactivate()
    if self.B3.left then
        self.B3.left = false;
        return;
    else
        self.B3.left = true;
    end;
    if self.B3.work ~= nil then
        for i=1,table.getn(self.B3.work) do
            local wl = self.B3.work[i];
            local newstate = false;
            if wl.so then
                newstate = wl.a;
            end;
            self:setState("work:"..i,newstate,true);
        end;
    end;
    if self.B3.strobe ~= nil then
        for i=1,table.getn(self.B3.strobe) do
            local sl = self.B3.strobe[i];
            local newstate = false;
            if sl.so then
                newstate = sl.a;
            end;
            self:setState("strobe:"..i,newstate,true);
        end;
    end;

    if self.B3.highbeam ~= nil then
        self:setState("highbeam", false,true);
    end;
    
    if self.B3.flw ~= nil then
        self.B3.flw.a = false;
    end;

    if self.B3.lso then
        --koronas an , licht aus
        local la = self.lightsActive;
        if self.attacherVehicle ~= nil then
            la = self.attacherVehicle.lightsActive;
        end;
        if la then
            self:setLightsVisibility(false);
            if self.B3.parkLeft and self.B3.parkRight then
                self:setState("parkLeft",true);
                self:setState("parkRight",true);
            else
                for _, corona in pairs(self.lightCoronas) do
                    setVisibility(corona, true);
                end;
              end;
            end;
    end;

    if not self.B3.wl then
        if self.B3.dirLeft and self.B3.dirRight then
            if self.B3.parkLeft and self.B3.parkRight then
                if self.B3.dirLeft[1].a then
                    self:setState("parkLeft",true);
                end;
                if self.B3.dirRight[1].a then
                    self:setState("parkRight",true);
                end;
            end;
            if self.B3.dirLeft[1].a then
                self:setState("dirLeft",false);
            end;
            if self.B3.dirRight[1].a then
                self:setState("dirRight",false);
            end;
        end;
    end;
    
    if self.B3.brake then
        if self.B3.brake[1].a then
            self:setState("brake",false);
        end;
    end;
    if self.B3.reverse then
        if self.B3.reverse[1].a then
            self:setState("reverse",false);
        end;
    end;

    if self.B3.drl ~= nil then
        if self.B3.drl[1].a then
            self:setState("drl", false);
        end;
    end;

    if self.B3.bla and not self.B3.blso then
        self.B3.bla = false;
    end;
    
end;    

function BEL3:onEnter()
    self:activate();
end;

function BEL3:onActivate()
    self:activate();
end;

function BEL3:activate()
    self.B3.left = false;
    if self.B3.work then
        for i=1,table.getn(self.B3.work) do
            local wl = self.B3.work[i];
            self:setState("work:"..i,wl.a,true);
        end;
    end;
    if self.B3.strobe then
        for i=1,table.getn(self.B3.strobe) do
            local sl = self.B3.strobe[i];
            self:setState("strobe:"..i,sl.a,true);
        end;
    end;
    if self.B3.parkLeft and self.B3.parkRight then
        if self.B3.parkLeft[1].a and self.B3.parkRight[1].a then
            self:setState("parkLeft",false);
            self:setState("parkRight",false);
            self:setLightsVisibility(true);
        end;
    end;
    if self.B3.dirLeft and self.B3.parkLeft then
        if self.B3.parkLeft[1].a then
            self:setState("dirLeft",true);
            self:setState("parkLeft",false);
        end;
    end;
    if self.B3.dirRight and self.B3.parkRight then
        if self.B3.parkRight[1].a then
            self:setState("dirRight",true);
            self:setState("parkRight",false);
        end;
    end;
    if self.lightCoronas ~= nil then
        if getVisibility(self.lightCoronas[1]) == true then
            self:setLightsVisibility(true);
        end;
    end;

    if self.B3.drl ~= nil then
        if self.B3.drl[1].a == false then
            self:setState("drl", true);
        end;
    end;

end;    

function BEL3:setState(object,state,noEventSend)
    if object=="warnlights" then
        self.B3.wl = state;
        SetLightStateEvent.sendEvent(self,object,state,noEventSend);
        return;
    end;
    local o,c = unpack(Utils.splitString(":",object));
    local lt = self.B3[o];
    local cs = 1; local cm = table.getn(lt);
    if c ~= nil then
        cs = tonumber(c); cm = cs;
    end;
    for c=cs,cm do
        local l = lt[c];
        l.a = state;
        setVisibility(l.index,state);
        local rstate = false; 
        local bstate = false;

        local isEntered = self.isEntered;
        if self.B3.atv ~= nil then
            isEntered = self.B3.atv.isEntered;
        end;

        if isEntered == true then
            rstate = state;
        else
            bstate = state;
        end;
        if l.rl ~= nil then
            setVisibility(l.rl,rstate);
        end;
        if l.fl ~= nil then
            setVisibility(l.fl,bstate);
        end;
    end;

    SetLightStateEvent.sendEvent(self,object,state,noEventSend);
end;


SetLightStateEvent = {};
SetLightStateEvent_mt = Class(SetLightStateEvent, Event);

InitEventClass(SetLightStateEvent, "SetLightStateEvent");

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

function SetLightStateEvent:new(object, light, state)
        local self = SetLightStateEvent:emptyNew()
        self.object = object;
        self.light = light;
        self.state = state;
        return self;
end;

function SetLightStateEvent:readStream(streamId, connection)
    self.object = networkGetObject(streamReadInt32(streamId));
        self.light  = streamReadString(streamId);
    self.state = streamReadBool(streamId);
    self:run(connection);
end;

function SetLightStateEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
        streamWriteString(streamId, self.light);
        streamWriteBool(streamId, self.state);
end;

function SetLightStateEvent:run(connection)
    self.object:setState(self.light,self.state, true);
  if not connection:getIsServer() then
      g_server:broadcastEvent(SetLightStateEvent:new(self.object, self.light, self.state), nil, connection, self.object);
  end;    
end;

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

