--
-- PowerTakeoff
--
-- Power takeoff script
--
-- @author  Stefan Geiger
-- @date  30/04/12
--
-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.

PowerTakeoff = {};

function PowerTakeoff.prerequisitesPresent(specializations)
    return true;
end

function PowerTakeoff:load(xmlFile)
    local ptoInputNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.powerTakeoffInput#index"));
    if ptoInputNode ~= nil then

        local filename = getXMLString(xmlFile, "vehicle.powerTakeoffInput#filename");
        local attachOffset = Utils.getVectorNFromString(getXMLString(xmlFile, "vehicle.powerTakeoffInput#attachOffset"), 3);
        if filename ~= nil and attachOffset ~= nil then
            filename = Utils.getFilename(filename, self.baseDirectory);
            local i3dNode = Utils.loadSharedI3DFile(filename);
            if i3dNode ~= 0 then
                local rootNode = getChildAt(i3dNode, 0);
                unlink(rootNode);
                delete(i3dNode);
                setTranslation(rootNode, 0,0,0);
                local dirNode = getChildAt(rootNode, 0);
                local transNode = getChildAt(dirNode, 0);
                local attachNode = getChildAt(transNode, 0);

                local _,_,baseDistance = getTranslation(attachNode);
                unlink(attachNode);
                setTranslation(attachNode, attachOffset[1], attachOffset[2], attachOffset[3]);

                local rotSpeed = math.rad(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.powerTakeoffInput#rotSpeed"), 140)*0.001);

                self.ptoInput = {node = ptoInputNode, rotSpeed=rotSpeed, rootNode=rootNode, dirNode=dirNode, transNode=transNode, attachNode=attachNode, baseDistance=baseDistance, rotation=0};
            end
        end
    end

    self.ptoInputActive = false;

    self.ptoOutputs = {};

    local i=0;
    while true do
        local baseName = string.format("vehicle.powerTakeoffOutputs.powerTakeoffOutput(%d)", i);
        if not hasXMLProperty(xmlFile, baseName) then
            break;
        end
        local attacherJointIndex = getXMLInt(xmlFile, baseName.."#attacherJointIndex");
        local node = Utils.indexToObject(self.components, getXMLString(xmlFile, baseName.."#index"));

        if attacherJointIndex ~= nil and node ~= nil then
            local ptoOutput = { node=node };
            self.ptoOutputs[attacherJointIndex+1] = ptoOutput;
        end
        i = i + 1;
    end

end

function PowerTakeoff:delete()
    if self.ptoInput ~= nil then
        delete(self.ptoInput.rootNode);
        delete(self.ptoInput.attachNode);
        self.ptoInput = nil;
    end;
end

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

function PowerTakeoff:keyEvent(unicode, sym, modifier, isDown)
end

function PowerTakeoff:update(dt)
    if self:getIsActive() then
        if self.ptoInputActive then
            PowerTakeoff.updatePTO(self, dt);
        end
    end
end

function PowerTakeoff:updateTick(dt)
end

function PowerTakeoff:draw()
end

function PowerTakeoff.getIsPowerTakeoffActive(self)
    if self.isTurnedOn ~= nil and self.isTurnedOn then
        return true;
    end
    if self.getNeedsActivePowerTakeoff ~= nil then
        return self:getNeedsActivePowerTakeoff();
    end

    return false;
end

function PowerTakeoff.updatePTO(self, dt)
    if self.ptoInput.rotSpeed ~= 0 then
        local isActive = PowerTakeoff.getIsPowerTakeoffActive(self);
        if isActive then
            self.ptoInput.rotation = (self.ptoInput.rotation + dt*self.ptoInput.rotSpeed) % (2*math.pi);
            setRotation(self.ptoInput.rootNode, 0, 0, self.ptoInput.rotation);
            setRotation(self.ptoInput.attachNode, 0, 0, self.ptoInput.rotation);
        end
    end

    local x,y,z = getWorldTranslation(self.ptoInput.attachNode);
    local dx,dy,dz = worldToLocal(self.ptoInput.rootNode, x,y,z);
    setDirection(self.ptoInput.dirNode, dx, dy, dz, 0, 1, 0);

    local _,_,dist = worldToLocal(self.ptoInput.dirNode, x,y,z);
    setTranslation(self.ptoInput.transNode, 0, 0, dist-self.ptoInput.baseDistance);
end;

function PowerTakeoff:attachImplement(implement)
    local ptoOutput = self.ptoOutputs[implement.jointDescIndex];
    if implement.object.ptoInput ~= nil and ptoOutput ~= nil then
        implement.object.ptoInputActive = true;
        link(ptoOutput.node, implement.object.ptoInput.rootNode);
        link(implement.object.ptoInput.node, implement.object.ptoInput.attachNode);

        PowerTakeoff.updatePTO(implement.object, 0);
    end
end

function PowerTakeoff:detachImplement(implementIndex)
    local implement = self.attachedImplements[implementIndex];
    if implement.object.ptoInput ~= nil and implement.object.ptoInputActive then
        unlink(implement.object.ptoInput.rootNode);
        unlink(implement.object.ptoInput.attachNode);
        implement.object.ptoInputActive = false;
    end
end

