
cabinControls = {};

cabinControls.modDir = g_currentModDirectory;

function cabinControls.prerequisitesPresent(specializations)
    return true; 
end;

function cabinControls:load(savegame)
    -- Initialize our cabinControl object(?)(table?)
    self.CControls = {};
    -- Check joystick node
    self.CControls.joystick = {};
    self.CControls.joystick.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.joystick#node") );
    
    if self.CControls.joystick.node ~= nil then
        self.CControls.joystick.rotF = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.joystick#rotFront"), 0) );
        self.CControls.joystick.rotB = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.joystick#rotBack"), 0) );
        self.CControls.joystick.rotT = 0;
        self.CControls.joystick.rotC = 0;
        
        self.CControls.joystick.lastSpeedTarget = 999;
        self.CControls.joystick.limiterReached = true;
        self.CControls.joystick.direction = 1; -- DO NOT CHANGE THIS!
    end;
    
    
    -- Check shuttle node
    self.CControls.shuttle = {};
    self.CControls.shuttle.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.shuttle#node") );
    
    if self.CControls.shuttle.node ~= nil then
        --Forward position
        self.CControls.shuttle.rotFwd = {0, 0, 0};
        local rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.cabinControls.shuttle#rotFwd"));
        if rx ~= nil and ry ~= nil and rz ~= nil then
            self.CControls.shuttle.rotFwd = {math.rad(rx), math.rad(ry), math.rad(rz)};
        end;
        --Backward position
        self.CControls.shuttle.rotBwd = {0, 0, 0};
        rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.cabinControls.shuttle#rotBwd"));
        if rx ~= nil and ry ~= nil and rz ~= nil then
            self.CControls.shuttle.rotBwd = {math.rad(rx), math.rad(ry), math.rad(rz)};
        end;
        --Neutral/handbrake position
        self.CControls.shuttle.rotNeut = {0, 0, 0};
        rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.cabinControls.shuttle#rotNeut"));
        if rx ~= nil and ry ~= nil and rz ~= nil then
            self.CControls.shuttle.rotNeut = {math.rad(rx), math.rad(ry), math.rad(rz)};
        end;
    end;
    
    -- Check handThrottle node
    self.CControls.handThrottle = {};
    self.CControls.handThrottle.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.handthrottle#node") );
    
    if self.CControls.handThrottle.node ~= nil then
        self.CControls.handThrottle.rotMinX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.handthrottle#rotMinX"), 0) );
        self.CControls.handThrottle.rotMaxX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.handthrottle#rotMaxX"), 0) );
    end;
    
    
    --Check brake node
    self.CControls.pedals = {};
    self.CControls.pedals.rotSpeed = 0.00125;
    self.CControls.brake = {};
    self.CControls.brake.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.brake#node") );
    
    if self.CControls.brake.node ~= nil then
        self.CControls.brake.rotMinX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.brake#rotMinX"), 0) );
        self.CControls.brake.rotMaxX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.brake#rotMaxX"), 0) );
    end;
    --Check clutch node
    self.CControls.clutch = {};
    self.CControls.clutch.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.clutch#node") );
    
    if self.CControls.clutch.node ~= nil then
        self.CControls.clutch.rotMinX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.clutch#rotMinX"), 0) );
        self.CControls.clutch.rotMaxX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.clutch#rotMaxX"), 0) );
    end;
    --Check throttle node
    self.CControls.throttle = {};
    self.CControls.throttle.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.throttle#node") );
    
    if self.CControls.throttle.node ~= nil then
        self.CControls.throttle.rotMinX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.throttle#rotMinX"), 0) );
        self.CControls.throttle.rotMaxX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.throttle#rotMaxX"), 0) );
    end;
    
    
    --Check implement node
    self.CControls.implement = {};
    self.CControls.implement.node = Utils.indexToObject( self.components, getXMLString(xmlFile, "vehicle.cabinControls.implement#node") );
    
    if self.CControls.implement.node ~= nil then
        self.CControls.implement.rotMinX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.implement#rotMinX"), 0) );
        self.CControls.implement.rotMaxX = math.rad( Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.cabinControls.implement#rotMaxX"), 0) );
        
        
        self.CControls.implement.rotSpeed = 0.00125;
        self.CControls.implement.isRaised = 1;
        self.CControls.implement.reachedTarget = false;
        local rx, ry, rz = getRotation(self.CControls.implement.node);
        self.CControls.implement.defRotation = rx;
        self.CControls.implement.currRotation = rx;
        self.CControls.implement.maxRot = self.CControls.implement.rotMaxX - self.CControls.implement.rotMinX;
    end;
end;

function cabinControls:delete()

end;

function cabinControls:readStream(streamId, connection)
end;

function cabinControls:writeStream(streamId, connection)
end;

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

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

function cabinControls:update(dt)
    if self:getIsActive() then
        if self.isClient then
            
            local state = self.turnSignalState;
            if state ~= nil then
                if state == Vehicle.TURNSIGNAL_HAZARD then
                
                elseif state == Vehicle.TURNSIGNAL_LEFT then
                
                elseif state == Vehicle.TURNSIGNAL_RIGHT then
                
                else
                    --Off
                end;
            end;
        
        
        
        
            --Joystick
            if self.CControls.joystick.node then
                cabinControls.updateJoystick(self, dt);
            end;
            
            --Shuttle
            local isOn = false;
            if self.mrGbMS ~= nil then
                isOn = self:mrGbMGetIsOnOff();
            end;
            if isOn then
                cabinControls.updateShuttleMrGbMS(self);
                cabinControls.updatePedalsMrGbMS(self, dt);
            elseif self.driveControl and self.driveControl.shuttle.isActive then
                cabinControls.updateShuttleDC(self);
                cabinControls.updatePedalsDC(self, dt);
            else
                cabinControls.updateShuttle(self);
                cabinControls.updatePedals(self, dt);
            end
            
            --HandThrottle
            if self.CControls.handThrottle.node and self.mrGbMS ~= nil then
                cabinControls.updateHandThrottle(self, dt);
            end;
            
            
            --Pedals
            --if self.CControls.brake.node and self.CControls.clutch.node and self.CControls.throttle.node then
                --cabinControls.updatePedals(self, dt);
            --end;
            
            
            --Implement
            if self.CControls.implement.node then
                cabinControls.updateImplement(self, dt);
            end;
        end;
    end;
    
    if self.motor.speedLevel ~= 0 then
    end;
    
end;

function cabinControls:updateTick(dt)

end;

function cabinControls:onLeave()
end;

function cabinControls:draw()
end;

-- Joystick --
function cabinControls.updateJoystick(self, dt)
    local axisForward = 0;
    axisForward = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
    if InputBinding.isAxisZero(axisForward) then
        axisForward = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE)
    end;
    
    local currSpeed = self.lastSpeed*3600;
    
    -- Speed limiter changed.
    if self.CControls.joystick.lastSpeedTarget ~= self.cruiseControl.speed and self.cruiseControl.state == Drivable.CRUISECONTROL_STATE_ACTIVE then
        self.CControls.joystick.limiterReached = false;
        self.CControls.joystick.lastSpeedTarget = self.cruiseControl.speed;
        if currSpeed < self.cruiseControl.speed then
            self.CControls.joystick.direction = -1;
        else
            self.CControls.joystick.direction = 1;
        end;
    end;
    
    if not self.CControls.joystick.limiterReached then
        axisForward = self.CControls.joystick.direction;
        if self.CControls.joystick.direction == -1 and currSpeed > self.cruiseControl.speed then
            self.CControls.joystick.limiterReached = true;
        elseif self.CControls.joystick.direction == 1 and currSpeed < self.cruiseControl.speed then
            self.CControls.joystick.limiterReached = true;
        end;
    end;

    if axisForward < 0 then
        self.CControls.joystick.rotT = -self.CControls.joystick.rotF*axisForward;
    elseif axisForward > 0 then
        self.CControls.joystick.rotT = self.CControls.joystick.rotB*axisForward;
    else
        self.CControls.joystick.rotT = 0;
    end
    
    
    if self.CControls.joystick.rotC < self.CControls.joystick.rotT then
        self.CControls.joystick.rotC = self.CControls.joystick.rotC + dt/2000;
        if self.CControls.joystick.rotC > self.CControls.joystick.rotT then
            self.CControls.joystick.rotC = self.CControls.joystick.rotT;
        end;
    elseif self.CControls.joystick.rotC > self.CControls.joystick.rotT then
        self.CControls.joystick.rotC = self.CControls.joystick.rotC - dt/2000;
        if self.CControls.joystick.rotC < self.CControls.joystick.rotT then
            self.CControls.joystick.rotC = self.CControls.joystick.rotT;
        end;
    end;
    
    setRotation( self.CControls.joystick.node, self.CControls.joystick.rotC, 0, 0 );
end;

-- Shuttle --
-- GEARBOX -- 
function cabinControls.updateShuttleMrGbMS(self)
    if not self.CControls.shuttle.node then
        return;
    end;
    if self:mrGbMGetNeutralActive() then
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotNeut[1], self.CControls.shuttle.rotNeut[2], self.CControls.shuttle.rotNeut[3] );
    elseif self:mrGbMGetReverseActive() then
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotBwd[1], self.CControls.shuttle.rotBwd[2], self.CControls.shuttle.rotBwd[3] );
    else
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotFwd[1], self.CControls.shuttle.rotFwd[2], self.CControls.shuttle.rotFwd[3] );
    end;
end;
-- DRIVE CONTROL --
function cabinControls.updateShuttleDC(self)
    if not self.CControls.shuttle.node then
        return;
    end;
    --print(self.lastSpeed);
    if self.driveControl.shuttle.direction > 0 and self.lastSpeed > 0.0001 then
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotFwd[1], self.CControls.shuttle.rotFwd[2], self.CControls.shuttle.rotFwd[3] );
    elseif self.driveControl.shuttle.direction < 0 and self.lastSpeed > 0.0001 then
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotBwd[1], self.CControls.shuttle.rotBwd[2], self.CControls.shuttle.rotBwd[3] );
    else
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotNeut[1], self.CControls.shuttle.rotNeut[2], self.CControls.shuttle.rotNeut[3] );
    end;
end;
-- DEFAULT --
function cabinControls.updateShuttle(self)
    if not self.CControls.shuttle.node then
        return;
    end;
    --print(self.movingDirection );
    if self.movingDirection > 0.0001 then
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotFwd[1], self.CControls.shuttle.rotFwd[2], self.CControls.shuttle.rotFwd[3] );
    elseif self.movingDirection < -0.0001 then
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotBwd[1], self.CControls.shuttle.rotBwd[2], self.CControls.shuttle.rotBwd[3] );
    else
        setRotation( self.CControls.shuttle.node, self.CControls.shuttle.rotNeut[1], self.CControls.shuttle.rotNeut[2], self.CControls.shuttle.rotNeut[3] );
    end;
end;

-- HAND THROTTLE --
function cabinControls.updateHandThrottle(self)
    local throttle = self:mrGbMGetHandThrottle();
    local maxRot = self.CControls.handThrottle.rotMaxX - self.CControls.handThrottle.rotMinX;
    local currRotation = self.CControls.handThrottle.rotMinX + maxRot * throttle;
    --print("throttle: "..throttle);
    setRotation(self.CControls.handThrottle.node, currRotation, 0, 0 );
    

end;


-- Pedals --
-- GEARBOX -- 
function cabinControls.updatePedalsMrGbMS(self, dt)
    local axisForward = 0;
    axisForward = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
    if InputBinding.isAxisZero(axisForward) then
        axisForward = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE)
    end;
    
    local brakeAxis = 0;
    local throttleAxis = 0;
    --local clutchAxis = 0;
    if axisForward < 0 then
        if not self:mrGbMGetNeutralActive() then
            throttleAxis = axisForward * -1;
        elseif self.driveControl and self.driveControl.handBrake.isActive then
            throttleAxis = axisForward * -1;
        end;
    else
        brakeAxis = axisForward;
    end;
    --if self:mrGbMGetNeutralActive() then
        --clutchAxis = 1;
    --end;
    
    cabinControls.setPedals(self,throttleAxis, brakeAxis, 0, dt);
end;
-- DRIVE CONTROL --
function cabinControls.updatePedalsDC(self, dt)
    local brakeAxis = 0;
    local throttleAxis = 0;
    local axisForward = 0;
    axisForward = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
    if InputBinding.isAxisZero(axisForward) then
        axisForward = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE)
    end;
    
    if self.driveControl.shuttle.direction > 0 and self.lastSpeed > 0.0001 then
        if axisForward < 0 then
            throttleAxis = axisForward * -1;
        else
            brakeAxis = axisForward;
        end;
    elseif self.driveControl.shuttle.direction < 0 and self.lastSpeed > 0.0001 then
        if axisForward < 0 then
            throttleAxis = axisForward * -1;
        else
            brakeAxis = axisForward;
        end;
    end;
    
    cabinControls.setPedals(self,throttleAxis, brakeAxis, 0, dt);
end;
-- DEFAULT --
function cabinControls.updatePedals(self, dt)
    local brakeAxis = 0;
    local throttleAxis = 0;
    local axisForward = 0;
    axisForward = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
    if InputBinding.isAxisZero(axisForward) then
        axisForward = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE)
    end;
    
    if self.movingDirection > 0.0001 then
        if axisForward < 0 then
            throttleAxis = axisForward * -1;
        elseif self.movingDirection > 0.001 then
            brakeAxis = axisForward;
        end;
    elseif self.movingDirection < 0.0001 then
        if axisForward < 0 and self.movingDirection < 0.001 then
            brakeAxis = axisForward * -1;
        else
            throttleAxis = axisForward;
        end;
    end;
    
    cabinControls.setPedals(self, throttleAxis, brakeAxis, 0, dt);
end;
-- Set pedals --
function cabinControls.setPedals(self,throttleAxis, brakeAxis, clutchAxis, dt)
    local maxRot = 0;
    local currRotation = 0;
    local targetRot = 0;
    local cx, cy, cz;
    --brake
    if self.CControls.brake.node then
        maxRot = self.CControls.brake.rotMaxX - self.CControls.brake.rotMinX;
        targetRot = self.CControls.brake.rotMinX + maxRot * brakeAxis;
        cx, cy, cz = getRotation(self.CControls.brake.node);
        local x;
        if brakeAxis > 0 then
            x = cx + self.CControls.pedals.rotSpeed * dt;
            if x > targetRot then
                x = targetRot;
            end;
        else
            x = cx - self.CControls.pedals.rotSpeed * dt;
            if x < targetRot then
                x = targetRot;
            end;
        end;
            
        --if x < maxRot and x > self.CControls.brake.rotMinX then -- WARNING; 0 to -30 not 0 to 30 (inverted!)
            setRotation(self.CControls.brake.node, x, 0, 0 );
        --end;
        
    end;
    --clutch
    --if self.CControls.clutch.node then
        --maxRot = self.CControls.clutch.rotMaxX - self.CControls.clutch.rotMinX;
        --currRotation = self.CControls.clutch.rotMinX + maxRot * clutchAxis;
        --setRotation(self.CControls.clutch.node, currRotation, 0, 0 );
    --end;
    --throttle
    if self.CControls.throttle.node then
        maxRot = self.CControls.throttle.rotMaxX - self.CControls.throttle.rotMinX;
        targetRot = self.CControls.throttle.rotMinX + maxRot * throttleAxis;
        cx, cy, cz = getRotation(self.CControls.throttle.node);
        local x;
        if throttleAxis > 0 then
            x = cx + self.CControls.pedals.rotSpeed * dt;
            if x > targetRot then
                x = targetRot;
            end;
        else
            x = cx - self.CControls.pedals.rotSpeed * dt;
            if x < targetRot then
                x = targetRot;
            end;
        end;
            
        --if x < maxRot and x > self.CControls.throttle.rotMinX then 
            setRotation(self.CControls.throttle.node, x, 0, 0 );
        --end;
    
    
    
    
    
    
    
    
        --maxRot = self.CControls.throttle.rotMaxX - self.CControls.throttle.rotMinX;
        --currRotation = self.CControls.throttle.rotMinX + maxRot * throttleAxis;
        --setRotation(self.CControls.throttle.node, currRotation, 0, 0 );
    end;
end;

-- IMPLEMENT --
function cabinControls.updateImplement(self, dt)
    local rearAttached = false;
    for i=1, table.getn(self.attachedImplements) do
        local implement = self.attachedImplements[i];
        local object = implement.object;
        if object ~= nil then 
            local jointDescIndex = implement.jointDescIndex;
            local jointDesc = self.attacherJoints[jointDescIndex];
            local inputJointDescIndex = implement.object.inputAttacherJointDescIndex;
            local moveDown = jointDesc.moveDown;
            if jointDescIndex == 1 then
                rearAttached = true;
                if jointDesc.moveDown then
                    self.CControls.implement.isRaised = 0;
                else
                    self.CControls.implement.isRaised = 1;
                end;
            end;
        end;
    end;
    if not rearAttached then
        self.CControls.implement.isRaised = 0.5;
    end;
    if self.CControls.implement.previousState ~= self.CControls.implement.isRaised then
        self.CControls.implement.reachedTarget = false;
    end;
    self.CControls.implement.previousState = self.CControls.implement.isRaised;

    local targetRotation = self.CControls.implement.rotMinX + self.CControls.implement.maxRot * self.CControls.implement.isRaised;
    if not self.CControls.implement.reachedTarget then
        if self.CControls.implement.currRotation < targetRotation then-- + self.CControls.implement.rotSpeed * 1.5 * dt then
            self.CControls.implement.currRotation = self.CControls.implement.currRotation + self.CControls.implement.rotSpeed * dt;
            if self.CControls.implement.currRotation > targetRotation then
                self.CControls.implement.reachedTarget = true;
            end;
        elseif self.CControls.implement.currRotation > targetRotation then -- - self.CControls.implement.rotSpeed * 1.5 * dt then
            self.CControls.implement.currRotation = self.CControls.implement.currRotation - self.CControls.implement.rotSpeed * dt;
            if self.CControls.implement.currRotation < targetRotation then
                self.CControls.implement.reachedTarget = true;
            end;
        end;
    end;
    
    setRotation(self.CControls.implement.node, self.CControls.implement.currRotation, 0, 0 );
end;