--
-- easyCylinder
--
-- author: upsidedown
-- date: 19.08.2013

-- NO RELEASE CANDIDATE!


easyCylinder = {};

function easyCylinder.prerequisitesPresent(specializations)
    return true; --SpecializationUtil.hasSpecialization(Steerable, specializations);
end;

function easyCylinder:load(savegame)
    
    self.easyCylinders = {};
    local i=0;
    while true do
        local areaKey = string.format("vehicle.easyCylinder.cylinder(%d)", i);
        if not hasXMLProperty(xmlFile, areaKey) then            
            break;
        end
        
        local easyCylinder = {};
        easyCylinder.index = i+1;
        easyCylinder.movingPart = Utils.indexToObject(self.components, getXMLString(xmlFile, areaKey .. "#movingPartIndex"));    
        easyCylinder.movingCylinder = Utils.indexToObject(self.components, getXMLString(xmlFile, areaKey .. "#movingCylinderIndex"));    
        easyCylinder.fixedCylinder = Utils.indexToObject(self.components, getXMLString(xmlFile, areaKey .. "#fixedCylinderIndex"));    
        easyCylinder.mode2 = Utils.getNoNil(getXMLBool(xmlFile, areaKey .. "#mode2"),false);
        easyCylinder.playSound = Utils.getNoNil(getXMLBool(xmlFile, areaKey .. "#playSound"),false);
        -- local x,y,z = getWorldTranslation(easyCylinder.movingCylinder);
        -- local TG = createTransformGroup("cylinder_"..tostring(i+1))
        -- link(easyCylinder.movingPart,TG);
        -- Utils.setWorldTranslation(TG,x,y,z)
        -- link(TG,easyCylinder.movingCylinder)
        -- setTranslation(easyCylinder.movingCylinder,0,0,0)
    
        
        -- easyCylinder.TG = TG;
        
        -- local TG2 = createTransformGroup("cylinder2_"..tostring(i+1))
        -- link(getParent(easyCylinder.fixedCylinder),TG2);
        -- x,y,z = getWorldTranslation(easyCylinder.fixedCylinder);
        -- Utils.setWorldTranslation(TG2,x,y,z)
        -- easyCylinder.TG2 = TG2;
        
        -- if easyCylinder.mode2 then
            -- unlink(easyCylinder.fixedCylinder)
            -- link(TG2,easyCylinder.fixedCylinder);--NEW
            -- setTranslation(easyCylinder.fixedCylinder,0,0,0);
        -- end;
        
        local tx, ty, tz = Utils.getVectorFromString(getXMLString(xmlFile, areaKey .."#movingPartTrans"));
        if tx ~= nil and ty ~= nil and tz ~= nil then
            setTranslation(easyCylinder.movingPart,tx,ty,tz)
        end;
        
        local rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, areaKey .."#movingPartRot"));
        if rx ~= nil and ry ~= nil and rz ~= nil then
            setRotation(easyCylinder.movingPart,math.rad(rx),math.rad(ry),math.rad(rz))
        end;
        
        easyCylinder.doFix = Utils.getNoNil(getXMLBool(xmlFile, areaKey .. "#doFixCylinder"),true);
        easyCylinder.doMove = Utils.getNoNil(getXMLBool(xmlFile, areaKey .. "#doMoveCylinder"),true);
        
        rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, areaKey .."#movingCylRotOffset"));
        easyCylinder.doRotOffMove = rx ~= nil and ry ~= nil and rz ~= nil;
        if easyCylinder.doRotOffMove then
            easyCylinder.rotOffMove = {math.rad(rx), math.rad(ry), math.rad(rz)};
        end;
        
        rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, areaKey .."#fixCylRotOffset"));
        easyCylinder.doRotOffFix = rx ~= nil and ry ~= nil and rz ~= nil;
        if easyCylinder.doRotOffFix then
            easyCylinder.rotOffFix = {math.rad(rx), math.rad(ry), math.rad(rz)};
        end;
        
    i = i + 1;
        self.easyCylinders[i] = easyCylinder;        
  end
    
    if self.isClient then
        self.easyCylinderSample = Utils.loadSample(xmlFile, {}, "vehicle.cylinderedHydraulicSound", nil, self.baseDirectory)
    end
end;


function easyCylinder:postLoad(xml)
    for i,easyCylinder in pairs(self.easyCylinders) do
        local x,y,z = getWorldTranslation(easyCylinder.movingCylinder);
        local TG = createTransformGroup("cylinder_"..tostring(i+1))
        link(easyCylinder.movingPart,TG);
        Utils.setWorldTranslation(TG,x,y,z)
        unlink(easyCylinder.movingCylinder);
        link(TG,easyCylinder.movingCylinder)
        setTranslation(easyCylinder.movingCylinder,0,0,0)
    
        
        easyCylinder.TG = TG;
        
        local TG2 = createTransformGroup("cylinder2_"..tostring(i+1))
        link(getParent(easyCylinder.fixedCylinder),TG2);
        x,y,z = getWorldTranslation(easyCylinder.fixedCylinder);
        Utils.setWorldTranslation(TG2,x,y,z)
        easyCylinder.TG2 = TG2;
        
        if easyCylinder.mode2 then
            unlink(easyCylinder.fixedCylinder)
            link(TG2,easyCylinder.fixedCylinder);--NEW
            setTranslation(easyCylinder.fixedCylinder,0,0,0);
        end;
    end;
end;

function easyCylinder:withSound( )
    if self.isClient and self.easyCylinderSample ~= nil and self.easyCylinderSample.sample ~= nil then
        return true
    end
    return false
end

function easyCylinder:delete()
    if easyCylinder.withSound( self ) then
        pcall( Utils.deleteSample, self.easyCylinderSample )
        self.easyCylinderSample = nil
    end    
end;

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

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

function easyCylinder:updateTick(dt)    
end;


function easyCylinder:update(dt)
    local playSound = false
    
    if self:getIsActive() then
        for _,cylinder in pairs(self.easyCylinders) do
            
            if cylinder.doMove then
                if false and not cylinder.mode2 then
                    local x,y,z = getWorldTranslation(cylinder.fixedCylinder) --part on moving side
                    x,y,z = worldToLocal(cylinder.TG,x,y,z);
                    setDirection(cylinder.movingCylinder,-x,-y,-z,0,1,0)
                    if cylinder.doRotOffMove then
                        local rx,ry,rz = getRotation(cylinder.movingCylinder)
                        rx = rx + cylinder.rotOffMove[1];
                        ry = ry + cylinder.rotOffMove[2];
                        rz = rz + cylinder.rotOffMove[3];
                        setRotation(cylinder.movingCylinder,rx,ry,rz)
                    end
                else
                    local upX, upY, upZ = localDirectionToWorld(cylinder.TG, 0, 1, 0); --tg at moving part
                    local x,y,z = getWorldTranslation(cylinder.TG2);
                    local a, b, c = worldToLocal(cylinder.TG,x,y,z);                    
                    local dirX, dirY, dirZ = localDirectionToWorld(cylinder.TG, a, b, c);            
                    Utils.setWorldDirection(cylinder.TG, -dirX, -dirY, -dirZ, upX, upY, upZ,nil);                    
                    if cylinder.doRotOffMove then
                        local rx,ry,rz = getRotation(cylinder.movingCylinder)
                        rx = 0*rx + cylinder.rotOffMove[1];
                        ry = 0*ry + cylinder.rotOffMove[2];
                        rz = 0*rz + cylinder.rotOffMove[3];
                        setRotation(cylinder.movingCylinder,rx,ry,rz)
                    end
                end;
            end
            if cylinder.doFix then
                if not cylinder.mode2 then
                    x,y,z = getWorldTranslation(cylinder.TG) --part on fixed side
                    x,y,z = worldToLocal(cylinder.TG2,x,y,z);
                    setDirection(cylinder.fixedCylinder,x,y,z,0,1,0)
                    --rotate(cylinder.fixedCylinder,0,math.rad(-90),0)
                    
                    if cylinder.doRotOffFix then
                        local rx,ry,rz = getRotation(cylinder.fixedCylinder)
                        rx = 1*rx + cylinder.rotOffFix[1];
                        ry = 1*ry + cylinder.rotOffFix[2];
                        rz = 1*rz + cylinder.rotOffFix[3];
                        setRotation(cylinder.fixedCylinder,rx,ry,rz)
                    end
                    
                else
                    local upX, upY, upZ = localDirectionToWorld(cylinder.TG2, 0, 1, 0); --tg at moving part
                    local x,y,z = getWorldTranslation(cylinder.TG);
                    local a, b, c = worldToLocal(cylinder.TG2,x,y,z);                    
                    local dirX, dirY, dirZ = localDirectionToWorld(cylinder.TG2, a, b, c);            
                    Utils.setWorldDirection(cylinder.TG2, dirX, dirY, dirZ, upX, upY, upZ,nil);    
                    --setDirection(cylinder.TG2,a,b,c,0,1,0);
                    
                    if cylinder.doRotOffFix then
                        local rx,ry,rz = getRotation(cylinder.fixedCylinder)
                        rx = 0*rx + cylinder.rotOffFix[1];
                        ry = 0*ry + cylinder.rotOffFix[2];
                        rz = 0*rz + cylinder.rotOffFix[3];
                        setRotation(cylinder.fixedCylinder,rx,ry,rz)
                    end
                    
                    -- local upX, upY, upZ = localDirectionToWorld(cylinder.fixedCylinder, 0, 1, 0); 
                    -- local x,y,z = getWorldTranslation(cylinder.TG);
                    -- local a, b, c = worldToLocal(cylinder.fixedCylinder,x,y,z);                    
                    -- local dirX, dirY, dirZ = localDirectionToWorld(cylinder.fixedCylinder, a, b, c);            
                    -- Utils.setWorldDirection(cylinder.fixedCylinder, dirX, dirY, dirZ, upX, upY, upZ,nil);
                    
                    
                    
                    --rotate(cylinder.fixedCylinder,0,math.rad(-90),0)
                    -- if cylinder.doRotOffMove then
                        -- local rx,ry,rz = getRotation(cylinder.movingCylinder)
                        -- rx = 0*rx + cylinder.rotOffMove[1];
                        -- ry = 0*ry + cylinder.rotOffMove[2];
                        -- rz = 0*rz + cylinder.rotOffMove[3];
                        -- setRotation(cylinder.movingCylinder,rx,ry,rz)
                    -- end
                
                
                end;
            end;
            
            if      easyCylinder.withSound( self )
                    and not ( playSound )
                    and cylinder.playSound
                    and cylinder.movingCylinder ~= nil 
                    and cylinder.fixedCylinder ~= nil then
                local x1, y1, z1 = getWorldTranslation( cylinder.movingCylinder )
                local x2, y2, z2 = getWorldTranslation( cylinder.fixedCylinder )
                local d1 = Utils.vector3Length( x1-x2, y1-y2, z1-z2 )
                
                if cylinder.lastDistance ~= nil then
                    local d0 = cylinder.lastDistance
                    
                --print(tostring(cylinder.index)..": "..tostring(d0).." - "..tostring(d1).." = "..tostring(d0-d1))
                    if math.abs( d0-d1 ) > 0.0001 then
                        playSound = true
                    end
                end
                
                cylinder.lastDistance = d1
            end
        end;
    end;
    
    if easyCylinder.withSound( self ) then
        if playSound then
            if not self.easyCylinderSample.isPlaying and self.getIsActiveForSound(self) then
                Utils.playSample( self.easyCylinderSample, 0, 0, nil)
            end
        elseif self.easyCylinderSample.isPlaying then
            Utils.stopSample( self.easyCylinderSample, true)
        end
    end
end;


function easyCylinder:draw()
    
end;


function easyCylinder:onDeactivate()
    
end;

function Cylindered:onDeactivateSounds()
    if easyCylinder.withSound( self ) and self.easyCylinderSample.isPlaying then
        Utils.stopSample( self.easyCylinderSample, true )
    end
end
