

export function createProgramFromScripts(gl: WebGLRenderingContext,) {

}



// 创建着色器方法，输入参数：渲染上下文，着色器类型，数据源
export function createShader(gl: WebGLRenderingContext, type: number, source: string): WebGLShader | undefined {
  var shader = gl.createShader(type)!; // 创建着色器对象
  gl.shaderSource(shader, source); // 提供数据源
  gl.compileShader(shader); // 编译 -> 生成着色器
  var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (success) {
    return shader;
  }

  console.log("error", gl.getShaderInfoLog(shader));
  gl.deleteShader(shader);
}

export function createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram | undefined {
  var program = gl.createProgram()!;
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  var success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (success) {
    return program;
  }

  console.log("error", gl.getProgramInfoLog(program));
  gl.deleteProgram(program);
}





// export function loadImage(canvas : any, url: string): Promise<HTMLImageElement> {
//   return new Promise((done, reject) => {
//     let image = canvas.createImage();
//     image.src = url;
//     image.onload = () => done(image)
//     image.onerror = reject
//   })
// }

export function loadImage(url: string): Promise<HTMLImageElement> {
  return new Promise((done, reject) => {
    let image = new Image();
    image.src = url;
    image.onload = () => done(image)
    image.onerror = reject
  })
}



export function createScaledImage(image: HTMLImageElement | HTMLCanvasElement, width: number, height: number) {
  let canvas = document.createElement('canvas');
  canvas.width = width
  canvas.height = height
  let ctx = canvas.getContext('2d')!
  ctx.imageSmoothingEnabled = false;
  ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, width, height)
  return canvas
}



export function parseColorInt(color: number): Float32Array {
  let out = new Float32Array(4)
  out[0] = color >> 24 & 0xff
  out[1] = color >> 16 & 0xff
  out[2] = color >> 8 & 0xff
  out[3] = color & 0xff
  return out
}



export function coerceIn(n: number, min: number, max: number): number {
  if (n < min) return min
  else if (n > max) return max
  else return n
}

export function randomColor() {
  return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + 1 + ')';
}


// rgba 转成 hsl 颜色
export function rgbaToHsl(rgba: number[]): number[] {
  const [r, g, b, a] = rgba.map(val => val / 255);
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h, s, l = (max + min) / 2;

  if (max === min) {
    h = s = 0; // achromatic
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h! /= 6;
  }

  return [h! * 360, s * 100, l * 100, a];
}

// hsl 转成 rgba
export function hslToRgba(hsl: number[]): number[] {
  let [h, s, l, a] = hsl;
  s /= 100;
  l /= 100;

  const c = (1 - Math.abs(2 * l - 1)) * s;
  const x = c * (1 - Math.abs((h / 60) % 2 - 1));
  const m = l - c / 2;
  let r, g, b;

  if (0 <= h && h < 60) { r = c; g = x; b = 0; }
  else if (60 <= h && h < 120) { r = x; g = c; b = 0; }
  else if (120 <= h && h < 180) { r = 0; g = c; b = x; }
  else if (180 <= h && h < 240) { r = 0; g = x; b = c; }
  else if (240 <= h && h < 300) { r = x; g = 0; b = c; }
  else if (300 <= h && h < 360) { r = c; g = 0; b = x; }

  return [
    Math.round((r! + m) * 255),
    Math.round((g! + m) * 255),
    Math.round((b! + m) * 255),
    a
  ];
}

// 字符串rgba转成数组形式
export function rgbaStringToArray(rgbaString: string) {
  const regex = /rgba\((\d+),\s*(\d+),\s*(\d+),\s*([\d.]+)\)/;
  const match = rgbaString.match(regex);
  if (match) {
    return match.slice(1).map(Number);
  }
  return null;
}

// 数组形式rgba转成字符串形式
export function rgbaArrayToString(rgbaArray: number[]) {
  return `rgba(${rgbaArray[0]}, ${rgbaArray[1]}, ${rgbaArray[2]}, ${rgbaArray[3]})`;
}

// 给定颜色， 生成相似颜色数组
export function generateSimilarColors(rgbaString: string, n: number) {
  const rgba = rgbaStringToArray(rgbaString);
  if (!rgba) {
    return [];
  }

  const hsl = rgbaToHsl(rgba);
  const similarColors = [];

  for (let i = 0; i < n; i++) {
    const hueOffset = Math.random() * 60 - 30; // 随机色相偏移量 (-30 到 30)
    const saturationOffset = Math.random() * 40 - 20; // 随机饱和度偏移量 (-20 到 20)
    const lightnessOffset = Math.random() * 40 - 20; // 随机亮度偏移量 (-20 到 20)

    const newHue = (hsl[0] + hueOffset) % 360;
    const newSaturation = Math.max(0, Math.min(100, hsl[1] + saturationOffset));
    const newLightness = Math.max(0, Math.min(100, hsl[2] + lightnessOffset));
    similarColors.push(rgbaArrayToString(hslToRgba([newHue, newSaturation, newLightness, hsl[3]])));
  }

  return similarColors;
}