next = ag.next
type = ag.type
ag._objects = {}

pairs = function(table)
    return next, table, nil
end

ipairs = function(table)
    local iter_func = function(t, i)
        i = i + 1
        if t[i] == nil then
            return nil
        else
            return i, t[i]
        end
    end
    return iter_func, table, 0
end

ag.createAMotor = function(obj1, obj2, axis0, axis1, axis2)
    local function setAMotorAxis(amotor, anum, axis)
        local rel, x, y, z = 0, 1, 0, 0
        for k, v in pairs(axis) do
            if     (k == "rel") then
                rel = v
            elseif (k == "x") then
                x = v
            elseif (k == "y") then
                y = v
            elseif (k == "z") then
                z = v
            elseif (k == "angle") then
                amotor:setAngle(anum, v)
            elseif (k == "lo_stop") then
                amotor:setLoStop(v)
            elseif (k == "hi_stop") then
                amotor:setHiStop(v)
            elseif (k == "vel") then
                amotor:setVel(v)
            elseif (k == "fmax") then
                amotor:setFMax(v)
            elseif (k == "bounce") then
                amotor:setBounce(v)
            end
        end
        amotor:setAxis(anum, rel, x, y, z)
    end

    local o1 = obj1
    local o2 = obj2
    local num_axes = 0

    if (type(obj1) == "number") then
        if (obj1 == 0) then
            o1 = { id = 0 }
        end
    end

    if (type(obj2) == "number") then
        if (obj2 == 0) then
            o2 = { id = 0 }
        end
    end

    local amotor = ag._createAMotor(o1, o2)

    if (amotor ~= nil) then
        if (axis0 ~= nil) then
            setAMotorAxis(amotor, 0, axis0)
            num_axes = 1
            if (axis1 ~= nil) then
                setAMotorAxis(amotor, 1, axis1)
                num_axes = 1
                if (axis2 ~= nil) then
                    setAMotorAxis(amotor, 2, axis2)
                    num_axes = 2
                end
            end
        end
        amotor:setNumAxes(num_axes)
    else
        ag.println("Error creating AMotor!")
    end

    return amotor
end

ag.createHinge = function(obj1, obj2, anchor, axis)
    local o1 = obj1
    local o2 = obj2

    if (type(obj1) == "number") then
        if (obj1 == 0) then
            o1 = { id = 0 }
        end
    end

    if (type(obj2) == "number") then
        if (obj2 == 0) then
            o2 = { id = 0 }
        end
    end

    return ag._createHinge(o1, o2,
        anchor[1], anchor[2], anchor[3],
        axis[1], axis[2], axis[3])
end

ag.loadModel = function(name, args)
    local scale = 1.0
    local static = false
    local reference = false
    local blending = false
    if (type(args) == "table") then
        if (type(args.scale) == "number") then
            scale = args.scale
        end
        if (type(args.static) == "boolean") then
            static = args.static
        end
        if (type(args.reference) == "boolean") then
            reference = args.reference
        end
        if (type(args.enable_blending) == "boolean") then
            blending = args.enable_blending
        end
    end
    return ag.loadModelSpecify(name, scale, static, reference, blending)
end

ag.createBox = function(x, y, z, args)
    local static = false
    local reference = false
    local blending = false
    if (type(args) == "table") then
        if (type(args.static) == "boolean") then
            static = args.static
        end
        if (type(args.reference) == "boolean") then
            reference = args.reference
        end
        if (type(args.enable_blending) == "boolean") then
            blending = args.enable_blending
        end
    end
    return ag.createBoxSpecify(x, y, z, static, reference, blending)
end

ag.createSphere = function(radius, args)
    local static = false
    local reference = false
    local blending = false
    if (type(args) == "table") then
        if (type(args.static) == "boolean") then
            static = args.static
        end
        if (type(args.reference) == "boolean") then
            reference = args.reference
        end
        if (type(args.enable_blending) == "boolean") then
            blending = args.enable_blending
        end
    end
    return ag.createSphereSpecify(radius, static, reference, blending)
end

ag.createPlane = function(a, b, c, d, x, y, z)
    local t = nil
    if (type(x) == "table") then
        t = x
    end
    if (type(z) == "table") then
        t = z
    end
    local reference = false
    local blending = false
    if (type(t) == "table") then
        if (type(t.reference) == "boolean") then
            reference = t.reference
        end
        if (type(args.enable_blending) == "boolean") then
            blending = args.enable_blending
        end
    end
    if (type(y) == "nil") then
        return ag.createPlaneSpecify(a, b, c, d, reference, blending)
    else
        return ag.createPlaneSpecify(a, b, c, d, x, y, reference, blending)
    end
end

ag.createCapsule = function(radius, length, args)
    local static = false
    local reference = false
    local blending = false
    if (type(args) == "table") then
        if (type(args.static) == "boolean") then
            static = args.static
        end
        if (type(args.reference) == "boolean") then
            reference = args.reference
        end
        if (type(args.enable_blending) == "boolean") then
            blending = args.enable_blending
        end
    end
    return ag.createCapsuleSpecify(radius, length, static, reference, blending)
end
