// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:html' as html;
import 'dart:js_util' as js_util;
import 'dart:math' as math;
import 'dart:typed_data';

import 'package:ui/ui.dart' as ui;

import '../browser_detection.dart';
import '../util.dart';
import '../vector_math.dart';
import 'painting.dart';
import 'shaders/image_shader.dart';
import 'shaders/normalized_gradient.dart';
import 'shaders/shader_builder.dart';
import 'shaders/vertex_shaders.dart';
import 'shaders/webgl_context.dart';

GlRenderer? glRenderer;

class SurfaceVertices implements ui.Vertices {
  final ui.VertexMode mode;
  final Float32List positions;
  final Int32List? colors;
  final Uint16List? indices; // ignore: unused_field

  SurfaceVertices(
    this.mode,
    List<ui.Offset> positions, {
    List<ui.Color>? colors,
    List<int>? indices,
  })  : assert(mode != null), // ignore: unnecessary_null_comparison
        assert(positions != null), // ignore: unnecessary_null_comparison
        // ignore: unnecessary_this
        this.colors = colors != null ? _int32ListFromColors(colors) : null,
        // ignore: unnecessary_this
        this.indices = indices != null ? Uint16List.fromList(indices) : null,
        // ignore: unnecessary_this
        this.positions = offsetListToFloat32List(positions) {
    initWebGl();
  }

  SurfaceVertices.raw(
    this.mode,
    this.positions, {
    this.colors,
    this.indices,
  })  : assert(mode != null), // ignore: unnecessary_null_comparison
        assert(positions != null) { // ignore: unnecessary_null_comparison
    initWebGl();
  }

  static Int32List _int32ListFromColors(List<ui.Color> colors) {
    final Int32List list = Int32List(colors.length);
    final int len = colors.length;
    for (int i = 0; i < len; i++) {
      list[i] = colors[i].value;
    }
    return list;
  }
}

/// Lazily initializes web gl.
///
/// Used to treeshake WebGlRenderer when user doesn't create Vertices object
/// to use the API.
void initWebGl() {
  glRenderer ??= _WebGlRenderer();
}

void disposeWebGl() {
  GlContextCache.dispose();
  glRenderer = null;
}

abstract class GlRenderer {
  void drawVertices(
      html.CanvasRenderingContext2D? context,
      int canvasWidthInPixels,
      int canvasHeightInPixels,
      Matrix4 transform,
      SurfaceVertices vertices,
      ui.BlendMode blendMode,
      SurfacePaintData paint);

  Object? drawRect(ui.Rect targetRect, GlContext gl, GlProgram glProgram,
      NormalizedGradient gradient, int widthInPixels, int heightInPixels);

  String drawRectToImageUrl(
      ui.Rect targetRect,
      GlContext gl,
      GlProgram glProgram,
      NormalizedGradient gradient,
      int widthInPixels,
      int heightInPixels);

  void drawHairline(html.CanvasRenderingContext2D? _ctx, Float32List positions);
}

/// Treeshakeable backend for rendering webgl on canvas.
///
/// This class gets instantiated on demand by Vertices constructor. For apps
/// that don't use Vertices WebGlRenderer will be removed from release binary.
class _WebGlRenderer implements GlRenderer {
  @override
  void drawVertices(
      html.CanvasRenderingContext2D? context,
      int canvasWidthInPixels,
      int canvasHeightInPixels,
      Matrix4 transform,
      SurfaceVertices vertices,
      ui.BlendMode blendMode,
      SurfacePaintData paint) {
    // Compute bounds of vertices.
    final Float32List positions = vertices.positions;
    final ui.Rect bounds = _computeVerticesBounds(positions, transform);
    final double minValueX = bounds.left;
    final double minValueY = bounds.top;
    final double maxValueX = bounds.right;
    final double maxValueY = bounds.bottom;
    double offsetX = 0;
    double offsetY = 0;
    int widthInPixels = canvasWidthInPixels;
    int heightInPixels = canvasHeightInPixels;
    // If vertices fall outside the bitmap area, cull.
    if (maxValueX < 0 || maxValueY < 0) {
      return;
    }
    if (minValueX > widthInPixels || minValueY > heightInPixels) {
      return;
    }
    // If Vertices are is smaller than hosting canvas, allocate minimal
    // offscreen canvas to reduce readPixels data size.
    if ((maxValueX - minValueX) < widthInPixels &&
        (maxValueY - minValueY) < heightInPixels) {
      widthInPixels = maxValueX.ceil() - minValueX.floor();
      heightInPixels = maxValueY.ceil() - minValueY.floor();
      offsetX = minValueX.floor().toDouble();
      offsetY = minValueY.floor().toDouble();
    }
    if (widthInPixels == 0 || heightInPixels == 0) {
      return;
    }

    final bool isWebGl2 = webGLVersion == WebGLVersion.webgl2;

    final EngineImageShader? imageShader =
        paint.shader == null ? null : paint.shader! as EngineImageShader;

    final String vertexShader = imageShader == null
        ? VertexShaders.writeBaseVertexShader()
        : VertexShaders.writeTextureVertexShader();
    final String fragmentShader = imageShader == null
        ? _writeVerticesFragmentShader()
        : FragmentShaders.writeTextureFragmentShader(
            isWebGl2, imageShader.tileModeX, imageShader.tileModeY);

    final GlContext gl =
        GlContextCache.createGlContext(widthInPixels, heightInPixels)!;

    final GlProgram glProgram = gl.cacheProgram(vertexShader, fragmentShader);
    gl.useProgram(glProgram);

    final Object positionAttributeLocation =
        gl.getAttributeLocation(glProgram.program, 'position');

    setupVertexTransforms(gl, glProgram, offsetX, offsetY,
        widthInPixels.toDouble(), heightInPixels.toDouble(), transform);

    if (imageShader != null) {
      /// To map from vertex position to texture coordinate in 0..1 range,
      /// we setup scalar to be used in vertex shader.
      setupTextureTransform(
          gl,
          glProgram,
          0.0,
          0.0,
          1.0 / imageShader.image.width.toDouble(),
          1.0 / imageShader.image.height.toDouble());
    }

    // Setup geometry.
    //
    // Create buffer for vertex coordinates.
    final Object positionsBuffer = gl.createBuffer()!;
    assert(positionsBuffer != null); // ignore: unnecessary_null_comparison

    Object? vao;
    if (imageShader != null) {
      if (isWebGl2) {
        // Create a vertex array object.
        vao = gl.createVertexArray();
        // Set vertex array object as active one.
        gl.bindVertexArray(vao!);
      }
    }
    // Turn on position attribute.
    gl.enableVertexAttribArray(positionAttributeLocation);
    // Bind buffer as position buffer and transfer data.
    gl.bindArrayBuffer(positionsBuffer);
    bufferVertexData(gl, positions, 1.0);

    // Setup data format for attribute.
    js_util.callMethod(gl.glContext, 'vertexAttribPointer', <dynamic>[
      positionAttributeLocation,
      2,
      gl.kFloat,
      false,
      0,
      0,
    ]);

    final int vertexCount = positions.length ~/ 2;
    Object? texture;

    if (imageShader == null) {
      // Setup color buffer.
      final Object? colorsBuffer = gl.createBuffer();
      gl.bindArrayBuffer(colorsBuffer);

      // Buffer kBGRA_8888.
      if (vertices.colors == null) {
        final ui.Color color = paint.color ?? const ui.Color(0xFF000000);
        final Uint32List vertexColors = Uint32List(vertexCount);
        for (int i = 0; i < vertexCount; i++) {
          vertexColors[i] = color.value;
        }
        gl.bufferData(vertexColors, gl.kStaticDraw);
      } else {
        gl.bufferData(vertices.colors, gl.kStaticDraw);
      }
      final Object colorLoc = gl.getAttributeLocation(glProgram.program, 'color');
      js_util.callMethod(gl.glContext, 'vertexAttribPointer',
          <dynamic>[colorLoc, 4, gl.kUnsignedByte, true, 0, 0]);
      gl.enableVertexAttribArray(colorLoc);
    } else {
      // Copy image it to the texture.
      texture = gl.createTexture();
      // Texture units are a global array of references to the textures.
      // By setting activeTexture, we associate the bound texture to a unit.
      // Every time we call a texture function such as texImage2D with a target
      // like TEXTURE_2D, it looks up texture by using the currently active
      // unit.
      // In our case we have a single texture unit 0.
      gl.activeTexture(gl.kTexture0);
      gl.bindTexture(gl.kTexture2D, texture);

      gl.texImage2D(gl.kTexture2D, 0, gl.kRGBA, gl.kRGBA, gl.kUnsignedByte,
          imageShader.image.imgElement);

      if (isWebGl2) {
        // Texture REPEAT and MIRROR is only supported in WebGL 2, for
        // WebGL 1.0 we let shader compute correct uv coordinates.
        gl.texParameteri(gl.kTexture2D, gl.kTextureWrapS,
            tileModeToGlWrapping(gl, imageShader.tileModeX));

        gl.texParameteri(gl.kTexture2D, gl.kTextureWrapT,
            tileModeToGlWrapping(gl, imageShader.tileModeY));

        // Mipmapping saves your texture in different resolutions
        // so the graphics card can choose which resolution is optimal
        // without artifacts.
        gl.generateMipmap(gl.kTexture2D);
      } else {
        // For webgl1, if a texture is not mipmap complete, then the return
        // value of a texel fetch is (0, 0, 0, 1), so we have to set
        // minifying function to filter.
        // See https://www.khronos.org/registry/webgl/specs/1.0.0/#5.13.8.
        gl.texParameteri(gl.kTexture2D, gl.kTextureWrapS, gl.kClampToEdge);
        gl.texParameteri(gl.kTexture2D, gl.kTextureWrapT, gl.kClampToEdge);
        gl.texParameteri(gl.kTexture2D, gl.kTextureMinFilter, gl.kLinear);
      }
    }

    // Finally render triangles.
    gl.clear();

    final Uint16List? indices = vertices.indices;
    if (indices == null) {
      gl.drawTriangles(vertexCount, vertices.mode);
    } else {
      /// If indices are specified to use shared vertices to reduce vertex
      /// data transfer, use drawElements to map from vertex indices to
      /// triangles.
      final Object? indexBuffer = gl.createBuffer();
      gl.bindElementArrayBuffer(indexBuffer);
      gl.bufferElementData(indices, gl.kStaticDraw);
      gl.drawElements(gl.kTriangles, indices.length, gl.kUnsignedShort);
    }

    if (vao != null) {
      gl.unbindVertexArray();
    }

    context!.save();
    context.resetTransform();
    gl.drawImage(context, offsetX, offsetY);
    context.restore();
  }

  /// Renders a rectangle using given program into an image resource.
  ///
  /// Browsers that support OffscreenCanvas and the transferToImageBitmap api
  /// will return ImageBitmap, otherwise will return CanvasElement.
  @override
  Object? drawRect(ui.Rect targetRect, GlContext gl, GlProgram glProgram,
      NormalizedGradient gradient, int widthInPixels, int heightInPixels) {
    drawRectToGl(
        targetRect, gl, glProgram, gradient, widthInPixels, heightInPixels);
    final Object? image = gl.readPatternData();
    gl.bindArrayBuffer(null);
    gl.bindElementArrayBuffer(null);
    return image;
  }

  /// Renders a rectangle using given program into an image resource and returns
  /// url.
  @override
  String drawRectToImageUrl(
      ui.Rect targetRect,
      GlContext gl,
      GlProgram glProgram,
      NormalizedGradient gradient,
      int widthInPixels,
      int heightInPixels) {
    drawRectToGl(
        targetRect, gl, glProgram, gradient, widthInPixels, heightInPixels);
    final String imageUrl = gl.toImageUrl();
    // Cleanup buffers.
    gl.bindArrayBuffer(null);
    gl.bindElementArrayBuffer(null);
    return imageUrl;
  }

  /// Renders a rectangle using given program into [GlContext].
  ///
  /// Caller has to cleanup gl array and element array buffers.
  void drawRectToGl(ui.Rect targetRect, GlContext gl, GlProgram glProgram,
      NormalizedGradient gradient, int widthInPixels, int heightInPixels) {
    // Setup rectangle coordinates.
    final double left = targetRect.left;
    final double top = targetRect.top;
    final double right = targetRect.right;
    final double bottom = targetRect.bottom;
    // Form 2 triangles for rectangle.
    final Float32List vertices = Float32List(8);
    vertices[0] = left;
    vertices[1] = top;
    vertices[2] = right;
    vertices[3] = top;
    vertices[4] = right;
    vertices[5] = bottom;
    vertices[6] = left;
    vertices[7] = bottom;

    final Object transformUniform =
        gl.getUniformLocation(glProgram.program, 'u_ctransform');
    gl.setUniformMatrix4fv(transformUniform, false, Matrix4.identity().storage);

    // Set uniform to scale 0..width/height pixels coordinates to -1..1
    // clipspace range and flip the Y axis.
    final Object resolution = gl.getUniformLocation(glProgram.program, 'u_scale');
    gl.setUniform4f(resolution, 2.0 / widthInPixels.toDouble(),
        -2.0 / heightInPixels.toDouble(), 1, 1);
    final Object shift = gl.getUniformLocation(glProgram.program, 'u_shift');
    gl.setUniform4f(shift, -1, 1, 0, 0);

    // Setup geometry.
    final Object positionsBuffer = gl.createBuffer()!;
    assert(positionsBuffer != null); // ignore: unnecessary_null_comparison
    gl.bindArrayBuffer(positionsBuffer);
    gl.bufferData(vertices, gl.kStaticDraw);
    // Point an attribute to the currently bound vertex buffer object.
    js_util.callMethod(gl.glContext, 'vertexAttribPointer',
        <dynamic>[0, 2, gl.kFloat, false, 0, 0]);
    gl.enableVertexAttribArray(0);

    // Setup color buffer.
    final Object? colorsBuffer = gl.createBuffer();
    gl.bindArrayBuffer(colorsBuffer);
    // Buffer kBGRA_8888.
    final Int32List colors = Int32List.fromList(<int>[
      0xFF00FF00,
      0xFF0000FF,
      0xFFFFFF00,
      0xFF00FFFF,
    ]);
    gl.bufferData(colors, gl.kStaticDraw);
    js_util.callMethod(gl.glContext, 'vertexAttribPointer',
        <dynamic>[1, 4, gl.kUnsignedByte, true, 0, 0]);
    gl.enableVertexAttribArray(1);

    final Object? indexBuffer = gl.createBuffer();
    gl.bindElementArrayBuffer(indexBuffer);
    gl.bufferElementData(VertexShaders.vertexIndicesForRect, gl.kStaticDraw);

    if (gl.containsUniform(glProgram.program, 'u_resolution')) {
      final Object uRes = gl.getUniformLocation(glProgram.program, 'u_resolution');
      gl.setUniform2f(
          uRes, widthInPixels.toDouble(), heightInPixels.toDouble());
    }

    gl.clear();
    gl.viewport(0, 0, widthInPixels.toDouble(), heightInPixels.toDouble());

    gl.drawElements(
        gl.kTriangles, VertexShaders.vertexIndicesForRect.length, gl.kUnsignedShort);
  }

  /// This fragment shader enables Int32List of colors to be passed directly
  /// to gl context buffer for rendering by decoding RGBA8888.
  ///     #version 300 es
  ///     precision mediump float;
  ///     in vec4 vColor;
  ///     out vec4 fragColor;
  ///     void main() {
  ///       fragColor = vColor;
  ///     }
  String _writeVerticesFragmentShader() {
    final ShaderBuilder builder = ShaderBuilder.fragment(webGLVersion);
    builder.floatPrecision = ShaderPrecision.kMedium;
    builder.addIn(ShaderType.kVec4, name: 'v_color');
    final ShaderMethod method = builder.addMethod('main');
    method.addStatement('${builder.fragmentColor.name} = v_color;');
    return builder.build();
  }

  @override
  void drawHairline(
      html.CanvasRenderingContext2D? _ctx, Float32List positions) {
    assert(positions != null); // ignore: unnecessary_null_comparison
    final int pointCount = positions.length ~/ 2;
    _ctx!.lineWidth = 1.0;
    _ctx.beginPath();
    final int len = pointCount * 2;
    for (int i = 0; i < len;) {
      for (int triangleVertexIndex = 0;
          triangleVertexIndex < 3;
          triangleVertexIndex++, i += 2) {
        final double dx = positions[i];
        final double dy = positions[i + 1];
        switch (triangleVertexIndex) {
          case 0:
            _ctx.moveTo(dx, dy);
            break;
          case 1:
            _ctx.lineTo(dx, dy);
            break;
          case 2:
            _ctx.lineTo(dx, dy);
            _ctx.closePath();
            _ctx.stroke();
        }
      }
    }
  }
}

ui.Rect _computeVerticesBounds(Float32List positions, Matrix4 transform) {
  double minValueX, maxValueX, minValueY, maxValueY;
  minValueX = maxValueX = positions[0];
  minValueY = maxValueY = positions[1];
  final int len = positions.length;
  for (int i = 2; i < len; i += 2) {
    final double x = positions[i];
    final double y = positions[i + 1];
    if (x.isNaN || y.isNaN) {
      // Follows skia implementation that sets bounds to empty
      // and aborts.
      return ui.Rect.zero;
    }
    minValueX = math.min(minValueX, x);
    maxValueX = math.max(maxValueX, x);
    minValueY = math.min(minValueY, y);
    maxValueY = math.max(maxValueY, y);
  }
  return _transformBounds(
      transform, minValueX, minValueY, maxValueX, maxValueY);
}

ui.Rect _transformBounds(
    Matrix4 transform, double left, double top, double right, double bottom) {
  final Float32List storage = transform.storage;
  final double m0 = storage[0];
  final double m1 = storage[1];
  final double m4 = storage[4];
  final double m5 = storage[5];
  final double m12 = storage[12];
  final double m13 = storage[13];
  final double x0 = (m0 * left) + (m4 * top) + m12;
  final double y0 = (m1 * left) + (m5 * top) + m13;
  final double x1 = (m0 * right) + (m4 * top) + m12;
  final double y1 = (m1 * right) + (m5 * top) + m13;
  final double x2 = (m0 * right) + (m4 * bottom) + m12;
  final double y2 = (m1 * right) + (m5 * bottom) + m13;
  final double x3 = (m0 * left) + (m4 * bottom) + m12;
  final double y3 = (m1 * left) + (m5 * bottom) + m13;
  return ui.Rect.fromLTRB(
      math.min(x0, math.min(x1, math.min(x2, x3))),
      math.min(y0, math.min(y1, math.min(y2, y3))),
      math.max(x0, math.max(x1, math.max(x2, x3))),
      math.max(y0, math.max(y1, math.max(y2, y3))));
}

/// Converts from [VertexMode] triangleFan and triangleStrip to triangles.
Float32List convertVertexPositions(ui.VertexMode mode, Float32List positions) {
  assert(mode != ui.VertexMode.triangles);
  if (mode == ui.VertexMode.triangleFan) {
    final int coordinateCount = positions.length ~/ 2;
    final int triangleCount = coordinateCount - 2;
    final Float32List triangleList = Float32List(triangleCount * 3 * 2);
    final double centerX = positions[0];
    final double centerY = positions[1];
    int destIndex = 0;
    int positionIndex = 2;
    for (int triangleIndex = 0;
        triangleIndex < triangleCount;
        triangleIndex++, positionIndex += 2) {
      triangleList[destIndex++] = centerX;
      triangleList[destIndex++] = centerY;
      triangleList[destIndex++] = positions[positionIndex];
      triangleList[destIndex++] = positions[positionIndex + 1];
      triangleList[destIndex++] = positions[positionIndex + 2];
      triangleList[destIndex++] = positions[positionIndex + 3];
    }
    return triangleList;
  } else {
    assert(mode == ui.VertexMode.triangleStrip);
    // Set of connected triangles. Each triangle shares 2 last vertices.
    final int vertexCount = positions.length ~/ 2;
    final int triangleCount = vertexCount - 2;
    double x0 = positions[0];
    double y0 = positions[1];
    double x1 = positions[2];
    double y1 = positions[3];
    final Float32List triangleList = Float32List(triangleCount * 3 * 2);
    int destIndex = 0;
    for (int i = 0, positionIndex = 4; i < triangleCount; i++) {
      final double x2 = positions[positionIndex++];
      final double y2 = positions[positionIndex++];
      triangleList[destIndex++] = x0;
      triangleList[destIndex++] = y0;
      triangleList[destIndex++] = x1;
      triangleList[destIndex++] = y1;
      triangleList[destIndex++] = x2;
      triangleList[destIndex++] = y2;
      x0 = x1;
      y0 = y1;
      x1 = x2;
      y1 = y2;
    }
    return triangleList;
  }
}
