/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.24/esri/copyright.txt for details. */ import e from"../../core/Error.js";import{clone as a}from"../../core/lang.js";import{isSome as n}from"../../core/maybe.js";import{fetchMessageBundle as i}from"../../intl/messages.js";import l from"../../renderers/support/AuthoringInfo.js";import{AuthoringInfoClassBreakInfo as r}from"../../renderers/support/AuthoringInfoClassBreakInfo.js";import{AuthoringInfoFieldInfo as s}from"../../renderers/support/AuthoringInfoFieldInfo.js";import{createRenderer as o}from"./type.js";import{createColors as t,getClassBreaks as d,verifyBasicFieldValidity as m,getBasemapInfo as u}from"./support/utils.js";import{createLayerAdapter as f,featureCapableLayerTypes as p,getLayerTypeLabels as c}from"../support/adapters/support/layerUtils.js";import{getColors as h,flatten2DArray as y,cloneScheme as b,getSchemes as w}from"../symbology/relationship.js";import{applyColorToSymbol as v}from"../../symbols/support/utils.js";const g=["equal-interval","natural-breaks","quantile"],I=["HH","HL","LH","LL"],M={2:[["HL","HH"],["LL","LH"]],3:[["HL","HM","HH"],["ML","MM","MH"],["LL","LM","LH"]],4:[["HL","HM1","HM2","HH"],["M2L","M2M1","M2M2","M2H"],["M1L","M1M1","M1M2","M1H"],["LL","LM1","LM2","LH"]]},z={2:["L","H"],3:["L","M","H"],4:["L","M1","M2","H"]},F=e=>({minValue:e.minValue,maxValue:e.maxValue});async function T(a){if(!(a&&a.layer&&a.view&&a.field1&&a.field2))throw new e("relationship-renderer:missing-parameters","'layer', 'view', 'field1' and 'field2' parameters are required");const i={...a};if(i.symbolType=i.symbolType||"2d",i.defaultSymbolEnabled=null==i.defaultSymbolEnabled||i.defaultSymbolEnabled,i.classificationMethod=i.classificationMethod||"quantile",i.numClasses=i.numClasses||3,i.focus=i.focus||null,!g.includes(i.classificationMethod))throw new e("relationship-renderer:invalid-parameters",`classification method ${i.classificationMethod} is not supported`);if(i.numClasses<2||i.numClasses>4)throw new e("relationship-renderer:invalid-parameters","'numClasses' must be 2, 3 or 4");if(a.focus&&!I.includes(a.focus))throw new e("relationship-renderer:invalid-parameters","'focus' must be 'HH', 'HL', 'LH', 'LL' or null");const l=f(i.layer,p);if(i.layer=l,!l)throw new e("relationship-renderer:invalid-parameters","'layer' must be one of these types: "+c(p).join(", "));const r=n(i.signal)?{signal:i.signal}:null;await l.load(r);const s=l.geometryType,o=i.symbolType.includes("3d");if(i.outlineOptimizationEnabled="polygon"===s&&i.outlineOptimizationEnabled,i.sizeOptimizationEnabled=("point"===s||"multipoint"===s||"polyline"===s)&&i.sizeOptimizationEnabled,"mesh"===s)i.symbolType="3d-volumetric",i.colorMixMode=i.colorMixMode||"replace",i.edgesType=i.edgesType||"none";else{if("3d-volumetric-uniform"===i.symbolType&&"point"!==s)throw new e("relationship-renderer:not-supported","3d-volumetric-uniform symbols are supported for point layers only");if(o&&"polygon"===s)throw new e("relationship-renderer:not-supported","3d symbols are not supported for polygon layers");if(i.symbolType.includes("3d-volumetric")&&(!i.view||"3d"!==i.view.type))throw new e("relationship-renderer:invalid-parameters","'view' parameter should be an instance of SceneView when 'symbolType' parameter is '3d-volumetric' or '3d-volumetric-uniform'")}const{field1:t,field2:d}=i,u=[t.field,d.field];t.normalizationField&&u.push(t.normalizationField),d.normalizationField&&u.push(d.normalizationField);const h=m(l,u,"relationship-renderer:invalid-parameters");if(h)throw h;return i}async function V(a){if(!(a&&a.renderer&&a.numClasses))throw new e("update-relationship-renderer:missing-parameters","'renderer' and 'numClasses' parameters are required");const{field1:n,field2:i,renderer:l,numClasses:r,colors:s}=a,o=r**2;if((n||i)&&!(n&&i&&n.field&&i.field))throw new e("update-relationship-renderer:missing-parameters","'field1' and 'field2' parameters are required");if(n&&!n.classBreakInfos||i&&!i.classBreakInfos)throw new e("update-relationship-renderer:missing-parameters","'field1.classBreakInfos' and 'field2.classBreakInfos' are required");if(!l.authoringInfo)throw new e("update-relationship-renderer:missing-parameters","'renderer.authoringInfo' is required");if(l.uniqueValueInfos.length!==o)throw new e("update-relationship-renderer:invalid-parameters",`Renderer must have ${o} unique value infos to support ${r} classes`);if(s&&s.length!==o)throw new e("update-relationship-renderer:invalid-parameters",`The scheme must have ${o} colors`);return a}async function H(e){let a=e.relationshipScheme,i=null,l=null;const r=await u(e.basemap,e.view);if(i=n(r.basemapId)?r.basemapId:null,l=n(r.basemapTheme)?r.basemapTheme:null,a)return{scheme:b(a),basemapId:i,basemapTheme:l};const s=w({basemap:i,basemapTheme:l,geometryType:e.geometryType,theme:e.theme,worldScale:e.worldScale,view:e.view});return s&&(a=s.primaryScheme,i=s.basemapId,l=s.basemapTheme),{scheme:a,basemapId:i,basemapTheme:l}}function L(e,n){const i=a(M[e]);return y(i,n)}function k(e,a){return L(e,a).map((e=>({value:e,count:0})))}function C(e,a,n,i){const{field:l,normalizationField:r}=e,{field:s,normalizationField:o}=a,t=n.map((e=>[e.minValue,e.maxValue])),d=i.map((e=>[e.minValue,e.maxValue])),m=t.length,u=z[m];return`\n var field1 = $feature['${l}'];\n var field2 = $feature['${s}'];\n var hasNormField1 = ${r?"true":"false"};\n var hasNormField2 = ${o?"true":"false"};\n var normField1 = ${r?`$feature['${r}']`:"null"};\n var normField2 = ${o?`$feature['${o}']`:"null"};\n\n if (\n IsEmpty(field1) ||\n IsEmpty(field2) ||\n (hasNormField1 && (IsEmpty(normField1) || normField1 == 0)) ||\n (hasNormField2 && (IsEmpty(normField2) || normField2 == 0))\n ) {\n return null;\n }\n\n var value1 = IIf(hasNormField1, (field1 / normField1), field1);\n var value2 = IIf(hasNormField2, (field2 / normField2), field2);\n\n var breaks1 = ${JSON.stringify(t)};\n var breaks2 = ${JSON.stringify(d)};\n var classCodes = ${JSON.stringify(u)};\n\n function getClassCode(value, breaks) {\n var code = null;\n\n for (var i in breaks) {\n var info = breaks[i];\n if (value >= info[0] && value <= info[1]) {\n code = classCodes[i];\n break;\n }\n }\n\n return code;\n }\n\n var code1 = getClassCode(value1, breaks1);\n var code2 = getClassCode(value2, breaks2);\n\n var classValue = IIf(IsEmpty(code1) || IsEmpty(code2), null, code1 + code2);\n return classValue;\n `}async function E(a,n,r){const s=await i("esri/smartMapping/t9n/smartMapping"),{basemap:t,classificationMethod:d,field1:m,field2:u,focus:f,numClasses:p,signal:c}=a,y=a.layer,b=n.classBreakInfos,w=r.classBreakInfos;if(p!==b.length||b.length!==w.length)throw new e("relationship-renderer:error","incompatible class breaks");const v=k(p,f),g=C(a.field1,a.field2,b,w),I=(await H({basemap:t,geometryType:y.geometryType,theme:"default",relationshipScheme:a.relationshipScheme,worldScale:a.symbolType.includes("3d-volumetric"),view:a.view})).scheme,M=await o({layer:y,basemap:t,valueExpression:g,valueExpressionTitle:s.relationship.legendTitle,numTypes:-1,sortEnabled:!1,defaultSymbolEnabled:a.defaultSymbolEnabled,typeScheme:{colors:h(I,p,f),...I},statistics:{uniqueValueInfos:v},legendOptions:a.legendOptions,outlineOptimizationEnabled:a.outlineOptimizationEnabled,sizeOptimizationEnabled:a.sizeOptimizationEnabled,symbolType:a.symbolType,colorMixMode:a.colorMixMode,edgesType:a.edgesType,view:a.view,signal:c}),z=M.renderer,T=z.uniqueValueInfos,V=s.relationship;for(const e of T)e.label=V[e.value];const L=new l({type:"relationship",classificationMethod:d,numClasses:p,focus:f,field1:{field:m.field,normalizationField:m.normalizationField,label:m.label,classBreakInfos:b.map(F)},field2:{field:u.field,normalizationField:u.normalizationField,label:u.label,classBreakInfos:w.map(F)}});return z.authoringInfo=L,{renderer:z,classBreaks:{field1:n,field2:r},uniqueValueInfos:M.uniqueValueInfos,relationshipScheme:I,basemapId:M.basemapId,basemapTheme:M.basemapTheme}}function x(e,a,n){const i=L(a,n);e.sort(((e,a)=>{const n=i.indexOf(e.value),l=i.indexOf(a.value);let r=0;return nl&&(r=1),r}))}function $(e,a){const{authoringInfo:n}=e;n.numClasses=a.numClasses,n.focus=a.focus||null,n.focus||delete n.focus;const{field1:i,field2:l}=a;n.field1=new s({field:i.field,normalizationField:i.normalizationField,label:i.label,classBreakInfos:i.classBreakInfos.map((e=>new r(F(e))))}),n.field2=new s({field:l.field,normalizationField:l.normalizationField,label:l.label,classBreakInfos:l.classBreakInfos.map((e=>new r(F(e))))}),e.authoringInfo=n}async function S(e){const a=await V(e),{field1:n,field2:i,renderer:l,numClasses:r,focus:s,colors:o}=a,d=l.clone();if(d.valueExpression=C(n,i,n.classBreakInfos,i.classBreakInfos),x(d.uniqueValueInfos,r,s),o){const e=t(o,o.length);d.uniqueValueInfos.forEach(((a,n)=>v(a.symbol,e[n])))}return $(d,a),d}async function q(a){const n=await T(a),{layer:i,classificationMethod:l,field1:r,field2:s,numClasses:o,view:t,signal:m}=n,u={layer:i,classificationMethod:l,field:r.field,normalizationField:r.normalizationField,normalizationType:r.normalizationField?"field":null,minValue:r.minValue,maxValue:r.maxValue,analyzeData:!(null!=r.minValue&&null!=r.maxValue),numClasses:o,view:t,signal:m},f={layer:i,classificationMethod:l,field:s.field,normalizationField:s.normalizationField,normalizationType:s.normalizationField?"field":null,minValue:s.minValue,maxValue:s.maxValue,analyzeData:!(null!=s.minValue&&null!=s.maxValue),numClasses:o,view:t,signal:m},[p,c]=await Promise.all([d(u),d(f)]);if(!p||!c)throw new e("relationship-renderer:error","error when calculating class breaks");return E(n,p.result,c.result)}export{q as createRenderer,S as updateRenderer};