-- matrix code ------------------------------------------------------------------------------------
--local matrix = {}    -- "vtable"
--local mt_matrix= { __index = matrix }  -- metatable for "matrix"

-- create identity matrix
function matrix(x, y, z)
  local mat= userdata("f64", 4, 4)
  mat:set(  0,0, 
            x or 1, 0, 0, 0,
            0, y or 1, 0, 0,
            0, 0, z or 1, 0,
            0, 0, 0, 1 )
--  setmetatable(mat, mt_matrix)
  return mat
end


-- create a matrix which rotates around the x-axis by "a" pico8-degrees
function matrixRotX(a)
  local s,c= sin(a),cos(a)
  local mat= userdata("f64", 4, 4)
  mat:set(  0,0, 
            1, 0, 0, 0,
            0, c, s, 0,
            0,-s, c, 0,
            0, 0, 0, 1 )
  
--  setmetatable(mat, mt_matrix)
  return mat
end

-- create a matrix which rotates around the y-axis by "a" pico8-degrees
function matrixRotY(a)
  local s,c= sin(a),cos(a)
  local mat= userdata("f64", 4, 4)
  mat:set(0,0, 
         c, 0,-s, 0,
         0, 1, 0, 0,
         s, 0, c, 0,
         0, 0, 0, 1 )
--  setmetatable(mat, mt_matrix)
  return mat
end

-- create a matrix which rotates around the z-axis by "a" pico8-degrees
function matrixRotZ(a)
  local s,c= sin(a),cos(a)
  local mat= userdata("f64", 4, 4)
  mat:set(0,0, 
         c, s, 0, 0,
        -s, c, 0, 0,
         0, 0, 1, 0,
         0, 0, 0, 1
  )
--  setmetatable(mat, mt_matrix)
  return mat
end

-- create a matrix which translates by given x,y,z
function matrixTranslation(x, y, z)
  local mat= userdata("f64", 4, 4)
  mat:set( 0,0,
           1, 0, 0, 0,
           0, 1, 0, 0,
           0, 0, 1, 0,
           x or 0,
           y or 0,
           z or 0,
           1
  )
--  setmetatable(mat, mt_matrix)
  return mat
end

-- operator * for matrix (table[1..12])
-- TODO: use :matmul instead!
function matrixMul(a, b)
-- historical code, left for dead (and to check compatibility)
  local axx,axy,axz,axw= a[0],a[4],a[8],a[12]
  local ayx,ayy,ayz,ayw= a[1],a[5],a[9],a[13]
  local azx,azy,azz,azw= a[2],a[6],a[10],a[14]

  local bxx,bxy,bxz,bxw= b[0],b[4],b[8],b[12]
  local byx,byy,byz,byw= b[1],b[5],b[9],b[13]
  local bzx,bzy,bzz,bzw= b[2],b[6],b[10],b[14]

  local mat= userdata("f64", 4, 4)
  mat:set(0,0, 
    axx*bxx + axy*byx + axz*bzx, -- 0
    ayx*bxx + ayy*byx + ayz*bzx, -- 4
    azx*bxx + azy*byx + azz*bzx, -- 8
    0,

    axx*bxy + axy*byy + axz*bzy, -- 1
    ayx*bxy + ayy*byy + ayz*bzy, -- 5
    azx*bxy + azy*byy + azz*bzy, -- 9 
    0,

    axx*bxz + axy*byz + axz*bzz, -- 2
    ayx*bxz + ayy*byz + ayz*bzz, -- 6
    azx*bxz + azy*byz + azz*bzz, -- 10
    0,

    axx*bxw + axy*byw + axz*bzw + axw,
    ayx*bxw + ayy*byw + ayz*bzw + ayw,
    azx*bxw + azy*byw + azz*bzw + azw,
    1
  )

  return mat
end
