import { TYPES } from '../../../constants.mjs';

const attribSyncCache = {};
function generateAttributesSignature(attributes) {
  let s = "";
  for (let i = 0; i < attributes.length; i++) {
    const attr = attributes[i];
    if (i > 0) {
      s += "|";
    }
    s += `${attr.buffer}/${attr.size}${attr.type}/${attr.stride}/${attr.start}`;
  }
  return s;
}
function generateAttributeSync(attributes, genBuffers) {
  const funcFragments = [];
  let lastBuffer = -1;
  let bufSyncCount = 0;
  for (let i = 0; i < attributes.length; i++) {
    const attr = attributes[i];
    const bufInd = attr.buffer;
    if (genBuffers && lastBuffer !== bufInd) {
      lastBuffer = bufInd;
      funcFragments.push(`
if (lastBuffer !== buffers[${bufInd}]) {
    lastBuffer = buffers[${bufInd}];
    bufferSystem.bind(lastBuffer);
}`);
      bufSyncCount++;
    }
    const type = attr.type || TYPES.FLOAT;
    if (attr.int) {
      funcFragments.push(`gl.vertexAttribIPointer(locations[${i}], ${attr.size}, ${type}, ${attr.stride}, instOffset * ${attr.stride} + ${attr.start})`);
    } else {
      funcFragments.push(`gl.vertexAttribPointer(locations[${i}], ${attr.size}, ${type}, ${attr.normalized}, ${attr.stride}, instOffset * ${attr.stride} + ${attr.start})
`);
    }
  }
  let syncFunc;
  if (genBuffers) {
    funcFragments.push(`return lastBuffer;`);
    syncFunc = new Function("gl", "locations", "instOffset", "bufferSystem", "buffers", "lastBuffer", funcFragments.join("\n"));
  } else {
    syncFunc = new Function("gl", "locations", "instOffset", funcFragments.join("\n"));
  }
  return {
    syncFunc,
    bufSyncCount,
    bufFirstIndex: attributes[0].buffer,
    stride: attributes[0].stride
  };
}
function generateAttribSyncForGeom(geom) {
  const { attributes } = geom;
  let firstBuf = -1;
  let genBuffers = false;
  const instAttribs = [];
  for (const i in attributes) {
    const attr = attributes[i];
    if (attr.instance && !attr.hasSingleValue) {
      instAttribs.push(attr);
      if (firstBuf !== attr.buffer) {
        if (firstBuf !== -1) {
          genBuffers = true;
        } else {
          firstBuf = attr.buffer;
        }
      }
    }
  }
  const sign = generateAttributesSignature(instAttribs);
  let val = attribSyncCache[sign];
  if (!val) {
    val = attribSyncCache[sign] = generateAttributeSync(instAttribs, genBuffers);
  }
  return val;
}

export { attribSyncCache, generateAttribSyncForGeom, generateAttributeSync, generateAttributesSignature };
//# sourceMappingURL=generateAttributeSync.mjs.map
