/* COPYRIGHT Esri - https://js.arcgis.com/5.1.0/LICENSE.txt */
import{copy as e,set as o}from"../core/libs/gl-matrix-2/math/vec2.js";import{create as r}from"../core/libs/gl-matrix-2/factories/vec2f64.js";import{ZEROS as i}from"../core/libs/gl-matrix-2/factories/vec4f64.js";import{isColor as a}from"../views/3d/webgl-engine/core/shaderLibrary/ShaderOutput.js";import{RejectBySliceDraw as t}from"../views/3d/webgl-engine/core/shaderLibrary/Slice.glsl.js";import{ObjectAndLayerIdColor as l}from"../views/3d/webgl-engine/core/shaderLibrary/attributes/ObjectAndLayerIdColor.glsl.js";import{AlignPixel as s}from"../views/3d/webgl-engine/core/shaderLibrary/hud/AlignPixel.glsl.js";import{HUD as n}from"../views/3d/webgl-engine/core/shaderLibrary/hud/HUD.glsl.js";import{OutputHighlight as c}from"../views/3d/webgl-engine/core/shaderLibrary/output/OutputHighlight.glsl.js";import{ReadDepth as d}from"../views/3d/webgl-engine/core/shaderLibrary/output/ReadDepth.glsl.js";import{positionOutsideClipSpace as u}from"../views/3d/webgl-engine/core/shaderLibrary/shading/PositionOutsideClipSpace.js";import{VisualVariables as f}from"../views/3d/webgl-engine/core/shaderLibrary/shading/VisualVariables.glsl.js";import{ColorConversion as p}from"../views/3d/webgl-engine/core/shaderLibrary/util/ColorConversion.glsl.js";import{ScreenSizePerspective as g,addScreenSizePerspective as m,addScreenSizePerspectiveAlignment as v}from"../views/3d/webgl-engine/core/shaderLibrary/util/ScreenSizePerspective.glsl.js";import{addPixelRatio as x}from"../views/3d/webgl-engine/core/shaderLibrary/util/View.glsl.js";import{Float2PassUniform as h}from"../views/3d/webgl-engine/core/shaderModules/Float2PassUniform.js";import{Float4BindUniform as b}from"../views/3d/webgl-engine/core/shaderModules/Float4BindUniform.js";import{Float4PassUniform as C}from"../views/3d/webgl-engine/core/shaderModules/Float4PassUniform.js";import{FloatPassUniform as w}from"../views/3d/webgl-engine/core/shaderModules/FloatPassUniform.js";import{glsl as S,If as z}from"../views/3d/webgl-engine/core/shaderModules/glsl.js";import{IntegerPassUniform as P}from"../views/3d/webgl-engine/core/shaderModules/IntegerPassUniform.js";import{Texture2DBindUniform as y}from"../views/3d/webgl-engine/core/shaderModules/Texture2DBindUniform.js";import{Texture2DPassUniform as j}from"../views/3d/webgl-engine/core/shaderModules/Texture2DPassUniform.js";import{styleToEffect as A}from"../views/3d/webgl-engine/effects/focusArea/FocusAreaColorNode.js";import{alphaCutoff as O}from"../views/3d/webgl-engine/shaders/alphaCutoff.glsl.js";import{outputColorHighlightOLID as F}from"../views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js";import{ShaderBuilder as D}from"../views/webgl/ShaderBuilder.js";const B=e=>e?A[e]:0;function $(e){const r=new D;r.include(n,e),r.vertex.include(t,e);const{output:A,hasOcclusionTexture:$,signedDistanceFieldEnabled:T,pixelSnappingEnabled:_,hasEmission:q,hasScreenSizePerspective:R,debugDrawLabelBorder:k,hasVVSize:H,hasVVColor:I,hasRotation:E,occludedFragmentFade:G,sampleSignedDistanceFieldTexelCenter:N,hasVertexColor:J,hasVertexSize:K,hasVertexRotation:Q,hasVertexUVi:W}=e;r.include(g),r.include(f,e),r.include(l,e),r.include(F,e);const{vertex:X,fragment:Y}=r;Y.include(p),Y.code.add(S`
    vec4 applyFocusAreaStyle(vec4 color, int style) {
      const float factor = 0.46;
      const float factorBright = 0.32;

      if (style == ${S.int(0)}) {
        float luma = (color.r + color.g + color.b) / 3.0;
        float bright = luma * (1.0 - 0.6 * factorBright) + 0.6 * factorBright * color.a;
        float brightScaled = bright * factorBright;
        return vec4(brightScaled, brightScaled, brightScaled, color.a * factorBright);
      }

      float darkScaled = factor * factor;
      return vec4(color.rgb * darkScaled, color.a * factor);
    }
  `),r.varyings.add("vcolor","vec4"),r.varyings.add("vtc","vec2"),r.varyings.add("vsize","vec2");const Z=10===A;X.uniforms.add(new b("viewport",e=>e.camera.fullViewport),new h("screenOffset",(e,r)=>o(M,2*e.screenOffset[0]*r.camera.pixelRatio,2*e.screenOffset[1]*r.camera.pixelRatio)),new h("anchorPosition",e=>V(e)),new C("materialColor",({color:e})=>e),new w("materialRotation",e=>e.rotation),new h("materialSize",e=>e.size),new j("tex",e=>e.texture)),x(X),T&&(X.uniforms.add(new C("outlineColor",e=>e.outlineColor)),Y.uniforms.add(new C("outlineColor",e=>L(e)?e.outlineColor:i),new w("outlineSize",e=>L(e)?e.outlineSize:0))),_&&X.include(s),R&&(m(X),v(X)),k&&r.varyings.add("debugBorderCoords","vec4"),r.attributes.add("uv0","vec2"),W&&r.attributes.add("uvi","vec4"),J&&r.attributes.add("color","vec4"),K&&r.attributes.add("size","vec2"),Q&&r.attributes.add("rotation","float"),(H||I)&&r.attributes.add("featureAttribute","vec4"),X.main.add(S`
    ProjectHUDAux projectAux;
    vec4 posProj = projectPositionHUD(projectAux);
    forwardObjectAndLayerIdColor();

    if (rejectBySlice(projectAux.posModel)) {
      gl_Position = ${u};
      return;
    }

    vec2 vertexSize = materialSize${z(K," * size")};
    vec2 inputSize;
    ${z(R,S`
        inputSize = screenSizePerspectiveScaleVec2(vertexSize, projectAux.absCosAngle, projectAux.distanceToCamera, screenSizePerspective);
        vec2 screenOffsetScaled = screenSizePerspectiveScaleVec2(screenOffset, projectAux.absCosAngle, projectAux.distanceToCamera, screenSizePerspectiveAlignment);`,S`
        inputSize = vertexSize;
        vec2 screenOffsetScaled = screenOffset;`)}
    ${z(H,S`inputSize *= vvScale(featureAttribute).xx;`)}

    vec2 combinedSize = inputSize * pixelRatio;
    vec4 quadOffset = vec4(0.0);
  `);const ee=S`
  ${z(W,S`
    vec2 texSize = vec2(textureSize(tex, 0));
    vec2 uv = mix(uvi.xy, uvi.zw, bvec2(uv0)) / texSize;
    `,S`
    vec2 uv = mix(vec2(0.), vec2(1.), bvec2(uv0));
    `)}

    quadOffset.xy = (uv0 - anchorPosition) * 2.0 * combinedSize;

    ${z(E,S`
        float angle = radians(materialRotation${z(Q," + rotation")});
        float cosAngle = cos(angle);
        float sinAngle = sin(angle);
        mat2 rotate = mat2(cosAngle, -sinAngle, sinAngle,  cosAngle);

        quadOffset.xy = rotate * quadOffset.xy;
      `)}

    quadOffset.xy = (quadOffset.xy + screenOffsetScaled) / viewport.zw * posProj.w;
  `,oe=_?T?S`posProj = alignToPixelOrigin(posProj, viewport.zw) + quadOffset;`:S`posProj += quadOffset;
if (inputSize.x == vertexSize.x) {
posProj = alignToPixelOrigin(posProj, viewport.zw);
}`:S`posProj += quadOffset;`;X.include(O),X.main.add(S`
    ${ee}
    ${I?"vcolor = interpolateVVColor(featureAttribute.y) * materialColor;":J?"vcolor = color * materialColor;":"vcolor = materialColor;"}

    ${z(11===A,S`vcolor.a = 1.0;`)}

    bool alphaDiscard = vcolor.a < alphaCutoff;
    ${z(T,"alphaDiscard = alphaDiscard && outlineColor.a < alphaCutoff;")}
    if (alphaDiscard) {
      // "early discard" if both symbol color (= fill) and outline color (if applicable) are transparent
      gl_Position = vec4(1e38, 1e38, 1e38, 1.0);
      return;
    } else {
      ${oe}
      gl_Position = posProj;
    }

    vtc = uv;

    ${z(k,S`debugBorderCoords = vec4(uv0, 1.5 / combinedSize);`)}
    vsize = inputSize;
  `);const re=a(A)&&e.hasFocusAreaStyle&&!e.draped;switch(Y.uniforms.add(new j("tex",e=>e.texture)),re&&Y.uniforms.add(new P("focusAreaStyle",e=>B(e.focusAreaStyle))),G&&!Z&&(Y.include(d),Y.uniforms.add(new y("depthMap",e=>e.mainDepth),new w("occludedOpacity",e=>e.occludedFragmentOpacity?.value??1))),$&&Y.uniforms.add(new y("texOcclusion",e=>e.hudOcclusion?.attachment)),k?Y.main.add("\n        float isBorder = float(any(lessThan(debugBorderCoords.xy, debugBorderCoords.zw)) || any(greaterThan(debugBorderCoords.xy, 1.0 - debugBorderCoords.zw)));\n        // don't discard fragments on debug border\n        float textureAlphaCutoff = isBorder > 0.0 ? 0.0 : alphaCutoff;\n      "):Y.main.add("float textureAlphaCutoff = alphaCutoff;"),Y.main.add("vec2 samplePos = vtc;"),N&&Y.main.add(S`float txSize = float(textureSize(tex, 0).x);
float texelSize = 1.0 / txSize;
vec2 scaleFactor = (vsize - txSize) * texelSize;
samplePos += (vec2(1.0, -1.0) * texelSize) * scaleFactor;`),T?Y.main.add(S`
      vec4 fillPixelColor = vcolor;

      // Get distance in output units (i.e. pixels)

      float sdf = texture(tex, samplePos).r;
      float pixelDistance = sdf * vsize.x;

      // Create smooth transition from the icon into its outline
      float fillAlphaFactor = clamp(0.5 - pixelDistance, 0.0, 1.0);
      fillPixelColor.a *= fillAlphaFactor;

      if (outlineSize > 0.25) {
        vec4 outlinePixelColor = outlineColor;
        float clampedOutlineSize = min(outlineSize, 0.5*vsize.x);

        // Create smooth transition around outline
        float outlineAlphaFactor = clamp(0.5 - (abs(pixelDistance) - 0.5*clampedOutlineSize), 0.0, 1.0);
        outlinePixelColor.a *= outlineAlphaFactor;

        if (
          outlineAlphaFactor + fillAlphaFactor < textureAlphaCutoff ||
          fillPixelColor.a + outlinePixelColor.a < alphaCutoff
        ) {
          discard;
        }

        // perform un-premultiplied over operator (see https://en.wikipedia.org/wiki/Alpha_compositing#Description)
        float compositeAlpha = outlinePixelColor.a + fillPixelColor.a * (1.0 - outlinePixelColor.a);
        vec3 compositeColor = vec3(outlinePixelColor) * outlinePixelColor.a +
                              vec3(fillPixelColor) * fillPixelColor.a * (1.0 - outlinePixelColor.a);

        ${z(!Z,S`fragColor = vec4(compositeColor, compositeAlpha);`)}
      } else {
        if (fillAlphaFactor < textureAlphaCutoff) {
          discard;
        }

        ${z(!Z,S`fragColor = premultiplyAlpha(fillPixelColor);`)}
      }

      // visualize SDF:
      // fragColor = vec4(clamp(-pixelDistance/vsize.x*2.0, 0.0, 1.0), clamp(pixelDistance/vsize.x*2.0, 0.0, 1.0), 0.0, 1.0);
      `):Y.main.add(S`
        vec4 texColor = texture(tex, samplePos, -0.5);
        if (texColor.a < textureAlphaCutoff) {
          discard;
        }
        ${z(!Z,S`fragColor = texColor * premultiplyAlpha(vcolor);`)}
      `),G&&!Z&&Y.main.add(S`
        float zSample = -linearizeDepth(texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x);
        float zFragment = -linearizeDepth(gl_FragCoord.z);
        if (zSample < ${S.float(1-U)} * zFragment) {
          fragColor *= occludedOpacity;
        }
      `),$&&Y.main.add("fragColor *= texelFetch(texOcclusion, ivec2(gl_FragCoord.xy), 0).r;"),!Z&&k&&Y.main.add("fragColor = mix(fragColor, vec4(1.0, 0.0, 1.0, 1.0), isBorder * 0.5);"),2===A&&Y.main.add(S`if (fragColor.a < alphaCutoff) {
discard;
}`),re&&Y.main.add(S`fragColor = applyFocusAreaStyle(fragColor, focusAreaStyle);`),a(A)&&q&&Y.main.add("fragEmission = vec4(0.0);"),A){case 1:Y.main.add("\n        fragColor = vec4(fragColor.rgb * floatBlendOutputScale, fragColor.a);\n        fragAlpha = fragColor.a * floatBlendOutputScale;\n      ");break;case 2:Y.main.add("fragColor.rgb /= fragColor.a;");break;case 11:Y.main.add("outputObjectAndLayerIdColor();");break;case 10:r.include(c,e),Y.main.add("outputHighlight(false);")}return r}function L(e){return e.outlineColor[3]>0&&e.outlineSize>0}function V(o){return o.textureIsSignedDistanceField?T(o.anchorPosition,o.distanceFieldBoundingBox,M):e(M,o.anchorPosition),M}const M=r();function T(e,r,i){o(i,e[0]*(r[2]-r[0])+r[0],e[1]*(r[3]-r[1])+r[1])}const U=.08,_=Object.freeze(Object.defineProperty({__proto__:null,anchorPosition:V,build:$},Symbol.toStringTag,{value:"Module"}));export{_ as H,V as a,$ as b};
