/**
 * @license
 * Copyright 2025-2026 Open Home Foundation
 * SPDX-License-Identifier: Apache-2.0
 */
import { asObject, pickNumber, pickString } from "./attribute-shapes.js";
const AVSUM_CLUSTER_ID = 1362;
const ATTR_MPTZ_POSITION = 0;
const ATTR_MAX_PRESETS = 1;
const ATTR_MPTZ_PRESETS = 2;
const ATTR_DPTZ_STREAMS = 3;
const ATTR_ZOOM_MAX = 4;
const ATTR_TILT_MIN = 5;
const ATTR_TILT_MAX = 6;
const ATTR_PAN_MIN = 7;
const ATTR_PAN_MAX = 8;
const ATTR_MOVEMENT_STATE = 9;
const ATTR_FEATURE_MAP = 65532;
const AVSUM_FEAT_DPTZ = 1 << 0;
const AVSUM_FEAT_MPAN = 1 << 1;
const AVSUM_FEAT_MTILT = 1 << 2;
const AVSUM_FEAT_MZOOM = 1 << 3;
const AVSUM_FEAT_MPRESETS = 1 << 4;
function readAttr(node, endpoint, attrId) {
  return node.attributes[`${endpoint}/${AVSUM_CLUSTER_ID}/${attrId}`];
}
function readFeatures(node, endpoint) {
  const fm = readAttr(node, endpoint, ATTR_FEATURE_MAP);
  const bits = typeof fm === "number" ? fm : 0;
  return {
    dptz: (bits & AVSUM_FEAT_DPTZ) !== 0,
    mPan: (bits & AVSUM_FEAT_MPAN) !== 0,
    mTilt: (bits & AVSUM_FEAT_MTILT) !== 0,
    mZoom: (bits & AVSUM_FEAT_MZOOM) !== 0,
    mPresets: (bits & AVSUM_FEAT_MPRESETS) !== 0
  };
}
function pickFieldNumber(obj, named, tagId) {
  return pickNumber(obj, named) ?? pickNumber(obj, tagId);
}
function readPosition(node, endpoint) {
  const obj = asObject(readAttr(node, endpoint, ATTR_MPTZ_POSITION));
  if (!obj) return { pan: null, tilt: null, zoom: null };
  return {
    pan: pickFieldNumber(obj, "pan", "0"),
    tilt: pickFieldNumber(obj, "tilt", "1"),
    zoom: pickFieldNumber(obj, "zoom", "2")
  };
}
function readRanges(node, endpoint) {
  const v = (id) => {
    const x = readAttr(node, endpoint, id);
    return typeof x === "number" ? x : null;
  };
  return {
    panMin: v(ATTR_PAN_MIN),
    panMax: v(ATTR_PAN_MAX),
    tiltMin: v(ATTR_TILT_MIN),
    tiltMax: v(ATTR_TILT_MAX),
    zoomMax: v(ATTR_ZOOM_MAX)
  };
}
function readMovementState(node, endpoint) {
  const v = readAttr(node, endpoint, ATTR_MOVEMENT_STATE);
  if (v === 0) return "idle";
  if (v === 1) return "moving";
  return "unknown";
}
function readPresets(node, endpoint) {
  const max = readAttr(node, endpoint, ATTR_MAX_PRESETS);
  const raw = readAttr(node, endpoint, ATTR_MPTZ_PRESETS);
  const items = new Array();
  if (Array.isArray(raw)) {
    for (const item of raw) {
      const obj = asObject(item);
      if (!obj) continue;
      const presetId = pickFieldNumber(obj, "presetId", "0");
      const name = pickString(obj, "name") ?? pickString(obj, "1");
      const settings = asObject(obj["settings"] ?? obj["2"]);
      if (presetId === null || name === null) continue;
      items.push({
        presetId,
        name,
        settings: {
          pan: settings ? pickFieldNumber(settings, "pan", "0") : null,
          tilt: settings ? pickFieldNumber(settings, "tilt", "1") : null,
          zoom: settings ? pickFieldNumber(settings, "zoom", "2") : null
        }
      });
    }
  }
  return { items, max: typeof max === "number" ? max : 0 };
}
function readDptzStreams(node, endpoint) {
  const raw = readAttr(node, endpoint, ATTR_DPTZ_STREAMS);
  if (!Array.isArray(raw)) return [];
  const out = new Array();
  for (const item of raw) {
    const obj = asObject(item);
    if (!obj) continue;
    const id = pickFieldNumber(obj, "videoStreamId", "0");
    if (id !== null) out.push({ videoStreamId: id });
  }
  return out;
}
async function relativeMove(client, nodeId, endpoint, delta) {
  await client.deviceCommand(nodeId, endpoint, AVSUM_CLUSTER_ID, "MPTZRelativeMove", delta);
}
async function moveToPreset(client, nodeId, endpoint, presetId) {
  await client.deviceCommand(nodeId, endpoint, AVSUM_CLUSTER_ID, "MPTZMoveToPreset", { presetID: presetId });
}
async function savePreset(client, nodeId, endpoint, name, presetId) {
  const payload = { name };
  if (presetId !== void 0) payload.presetID = presetId;
  await client.deviceCommand(nodeId, endpoint, AVSUM_CLUSTER_ID, "MPTZSavePreset", payload);
}
async function removePreset(client, nodeId, endpoint, presetId) {
  await client.deviceCommand(nodeId, endpoint, AVSUM_CLUSTER_ID, "MPTZRemovePreset", { presetID: presetId });
}
async function dptzRelativeMove(client, nodeId, endpoint, streamId, delta) {
  await client.deviceCommand(nodeId, endpoint, AVSUM_CLUSTER_ID, "DPTZRelativeMove", {
    videoStreamID: streamId,
    ...delta
  });
}
function hasAvsumOnEndpoint(node, endpoint) {
  const prefix = `${endpoint}/${AVSUM_CLUSTER_ID}/`;
  return Object.keys(node.attributes).some((k) => k.startsWith(prefix));
}
export {
  AVSUM_CLUSTER_ID,
  AVSUM_FEAT_DPTZ,
  AVSUM_FEAT_MPAN,
  AVSUM_FEAT_MPRESETS,
  AVSUM_FEAT_MTILT,
  AVSUM_FEAT_MZOOM,
  dptzRelativeMove,
  hasAvsumOnEndpoint,
  moveToPreset,
  readDptzStreams,
  readFeatures,
  readMovementState,
  readPosition,
  readPresets,
  readRanges,
  relativeMove,
  removePreset,
  savePreset
};
//# sourceMappingURL=avsum.js.map
