// math.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors

/* eslint-disable camelcase */
import {NumericArray} from '@math.gl/types';
// vec2 additions

export function vec2_transformMat4AsVector<T extends NumericArray>(
  out: T,
  a: Readonly<NumericArray>,
  m: Readonly<NumericArray>
): T {
  const x = a[0];
  const y = a[1];
  const w = m[3] * x + m[7] * y || 1.0;
  out[0] = (m[0] * x + m[4] * y) / w;
  out[1] = (m[1] * x + m[5] * y) / w;
  return out;
}

// vec3 additions

// Transform as vector, only uses 3x3 minor matrix
export function vec3_transformMat4AsVector<T extends NumericArray>(
  out: T,
  a: Readonly<NumericArray>,
  m: Readonly<NumericArray>
): T {
  const x = a[0];
  const y = a[1];
  const z = a[2];
  const w = m[3] * x + m[7] * y + m[11] * z || 1.0;
  out[0] = (m[0] * x + m[4] * y + m[8] * z) / w;
  out[1] = (m[1] * x + m[5] * y + m[9] * z) / w;
  out[2] = (m[2] * x + m[6] * y + m[10] * z) / w;
  return out;
}

export function vec3_transformMat2<T extends NumericArray>(
  out: T,
  a: Readonly<NumericArray>,
  m: Readonly<NumericArray>
): T {
  const x = a[0];
  const y = a[1];
  out[0] = m[0] * x + m[2] * y;
  out[1] = m[1] * x + m[3] * y;
  out[2] = a[2];
  return out;
}

// vec4 additions

export function vec4_transformMat2<T extends NumericArray>(
  out: T,
  a: Readonly<NumericArray>,
  m: Readonly<NumericArray>
): T {
  const x = a[0];
  const y = a[1];
  out[0] = m[0] * x + m[2] * y;
  out[1] = m[1] * x + m[3] * y;
  out[2] = a[2];
  out[3] = a[3];
  return out;
}

export function vec4_transformMat3<T extends NumericArray>(
  out: T,
  a: Readonly<NumericArray>,
  m: Readonly<NumericArray>
): T {
  const x = a[0];
  const y = a[1];
  const z = a[2];
  out[0] = m[0] * x + m[3] * y + m[6] * z;
  out[1] = m[1] * x + m[4] * y + m[7] * z;
  out[2] = m[2] * x + m[5] * y + m[8] * z;
  out[3] = a[3];
  return out;
}
