let cachedCapabilities = null;
// Default cell dimensions - updated by TUI when terminal responds to query
let cellDimensions = { widthPx: 9, heightPx: 18 };
export function getCellDimensions() {
  return cellDimensions;
}
export function setCellDimensions(dims) {
  cellDimensions = dims;
}
export function detectCapabilities() {
  const termProgram = process.env.TERM_PROGRAM?.toLowerCase() || '';
  const term = process.env.TERM?.toLowerCase() || '';
  const colorTerm = process.env.COLORTERM?.toLowerCase() || '';
  if (process.env.KITTY_WINDOW_ID || termProgram === 'kitty') {
    return { images: 'kitty', trueColor: true, hyperlinks: true };
  }
  if (termProgram === 'ghostty' || term.includes('ghostty') || process.env.GHOSTTY_RESOURCES_DIR) {
    return { images: 'kitty', trueColor: true, hyperlinks: true };
  }
  if (process.env.WEZTERM_PANE || termProgram === 'wezterm') {
    return { images: 'kitty', trueColor: true, hyperlinks: true };
  }
  if (process.env.ITERM_SESSION_ID || termProgram === 'iterm.app') {
    return { images: 'iterm2', trueColor: true, hyperlinks: true };
  }
  if (termProgram === 'vscode') {
    return { images: null, trueColor: true, hyperlinks: true };
  }
  if (termProgram === 'alacritty') {
    return { images: null, trueColor: true, hyperlinks: true };
  }
  const trueColor = colorTerm === 'truecolor' || colorTerm === '24bit';
  return { images: null, trueColor, hyperlinks: true };
}
export function getCapabilities() {
  if (!cachedCapabilities) {
    cachedCapabilities = detectCapabilities();
  }
  return cachedCapabilities;
}
export function resetCapabilitiesCache() {
  cachedCapabilities = null;
}
const KITTY_PREFIX = '\x1b_G';
const ITERM2_PREFIX = '\x1b]1337;File=';
export function isImageLine(line) {
  // Fast path: sequence at line start (single-row images)
  if (line.startsWith(KITTY_PREFIX) || line.startsWith(ITERM2_PREFIX)) {
    return true;
  }
  // Slow path: sequence elsewhere (multi-row images have cursor-up prefix)
  return line.includes(KITTY_PREFIX) || line.includes(ITERM2_PREFIX);
}
/**
 * Generate a random image ID for Kitty graphics protocol.
 * Uses random IDs to avoid collisions between different module instances
 * (e.g., main app vs extensions).
 */
export function allocateImageId() {
  // Use random ID in range [1, 0xffffffff] to avoid collisions
  return Math.floor(Math.random() * 0xfffffffe) + 1;
}
export function encodeKitty(base64Data, options = {}) {
  const CHUNK_SIZE = 4096;
  const params = ['a=T', 'f=100', 'q=2'];
  if (options.columns) params.push(`c=${options.columns}`);
  if (options.rows) params.push(`r=${options.rows}`);
  if (options.imageId) params.push(`i=${options.imageId}`);
  if (base64Data.length <= CHUNK_SIZE) {
    return `\x1b_G${params.join(',')};${base64Data}\x1b\\`;
  }
  const chunks = [];
  let offset = 0;
  let isFirst = true;
  while (offset < base64Data.length) {
    const chunk = base64Data.slice(offset, offset + CHUNK_SIZE);
    const isLast = offset + CHUNK_SIZE >= base64Data.length;
    if (isFirst) {
      chunks.push(`\x1b_G${params.join(',')},m=1;${chunk}\x1b\\`);
      isFirst = false;
    } else if (isLast) {
      chunks.push(`\x1b_Gm=0;${chunk}\x1b\\`);
    } else {
      chunks.push(`\x1b_Gm=1;${chunk}\x1b\\`);
    }
    offset += CHUNK_SIZE;
  }
  return chunks.join('');
}
/**
 * Delete a Kitty graphics image by ID.
 * Uses uppercase 'I' to also free the image data.
 */
export function deleteKittyImage(imageId) {
  return `\x1b_Ga=d,d=I,i=${imageId}\x1b\\`;
}
/**
 * Delete all visible Kitty graphics images.
 * Uses uppercase 'A' to also free the image data.
 */
export function deleteAllKittyImages() {
  return `\x1b_Ga=d,d=A\x1b\\`;
}
export function encodeITerm2(base64Data, options = {}) {
  const params = [`inline=${options.inline !== false ? 1 : 0}`];
  if (options.width !== undefined) params.push(`width=${options.width}`);
  if (options.height !== undefined) params.push(`height=${options.height}`);
  if (options.name) {
    const nameBase64 = Buffer.from(options.name).toString('base64');
    params.push(`name=${nameBase64}`);
  }
  if (options.preserveAspectRatio === false) {
    params.push('preserveAspectRatio=0');
  }
  return `\x1b]1337;File=${params.join(';')}:${base64Data}\x07`;
}
export function calculateImageRows(
  imageDimensions,
  targetWidthCells,
  cellDimensions = { widthPx: 9, heightPx: 18 }
) {
  const targetWidthPx = targetWidthCells * cellDimensions.widthPx;
  const scale = targetWidthPx / imageDimensions.widthPx;
  const scaledHeightPx = imageDimensions.heightPx * scale;
  const rows = Math.ceil(scaledHeightPx / cellDimensions.heightPx);
  return Math.max(1, rows);
}
export function getPngDimensions(base64Data) {
  try {
    const buffer = Buffer.from(base64Data, 'base64');
    if (buffer.length < 24) {
      return null;
    }
    if (buffer[0] !== 0x89 || buffer[1] !== 0x50 || buffer[2] !== 0x4e || buffer[3] !== 0x47) {
      return null;
    }
    const width = buffer.readUInt32BE(16);
    const height = buffer.readUInt32BE(20);
    return { widthPx: width, heightPx: height };
  } catch {
    return null;
  }
}
export function getJpegDimensions(base64Data) {
  try {
    const buffer = Buffer.from(base64Data, 'base64');
    if (buffer.length < 2) {
      return null;
    }
    if (buffer[0] !== 0xff || buffer[1] !== 0xd8) {
      return null;
    }
    let offset = 2;
    while (offset < buffer.length - 9) {
      if (buffer[offset] !== 0xff) {
        offset++;
        continue;
      }
      const marker = buffer[offset + 1];
      if (marker >= 0xc0 && marker <= 0xc2) {
        const height = buffer.readUInt16BE(offset + 5);
        const width = buffer.readUInt16BE(offset + 7);
        return { widthPx: width, heightPx: height };
      }
      if (offset + 3 >= buffer.length) {
        return null;
      }
      const length = buffer.readUInt16BE(offset + 2);
      if (length < 2) {
        return null;
      }
      offset += 2 + length;
    }
    return null;
  } catch {
    return null;
  }
}
export function getGifDimensions(base64Data) {
  try {
    const buffer = Buffer.from(base64Data, 'base64');
    if (buffer.length < 10) {
      return null;
    }
    const sig = buffer.slice(0, 6).toString('ascii');
    if (sig !== 'GIF87a' && sig !== 'GIF89a') {
      return null;
    }
    const width = buffer.readUInt16LE(6);
    const height = buffer.readUInt16LE(8);
    return { widthPx: width, heightPx: height };
  } catch {
    return null;
  }
}
export function getWebpDimensions(base64Data) {
  try {
    const buffer = Buffer.from(base64Data, 'base64');
    if (buffer.length < 30) {
      return null;
    }
    const riff = buffer.slice(0, 4).toString('ascii');
    const webp = buffer.slice(8, 12).toString('ascii');
    if (riff !== 'RIFF' || webp !== 'WEBP') {
      return null;
    }
    const chunk = buffer.slice(12, 16).toString('ascii');
    if (chunk === 'VP8 ') {
      if (buffer.length < 30) return null;
      const width = buffer.readUInt16LE(26) & 0x3fff;
      const height = buffer.readUInt16LE(28) & 0x3fff;
      return { widthPx: width, heightPx: height };
    } else if (chunk === 'VP8L') {
      if (buffer.length < 25) return null;
      const bits = buffer.readUInt32LE(21);
      const width = (bits & 0x3fff) + 1;
      const height = ((bits >> 14) & 0x3fff) + 1;
      return { widthPx: width, heightPx: height };
    } else if (chunk === 'VP8X') {
      if (buffer.length < 30) return null;
      const width = (buffer[24] | (buffer[25] << 8) | (buffer[26] << 16)) + 1;
      const height = (buffer[27] | (buffer[28] << 8) | (buffer[29] << 16)) + 1;
      return { widthPx: width, heightPx: height };
    }
    return null;
  } catch {
    return null;
  }
}
export function getImageDimensions(base64Data, mimeType) {
  if (mimeType === 'image/png') {
    return getPngDimensions(base64Data);
  }
  if (mimeType === 'image/jpeg') {
    return getJpegDimensions(base64Data);
  }
  if (mimeType === 'image/gif') {
    return getGifDimensions(base64Data);
  }
  if (mimeType === 'image/webp') {
    return getWebpDimensions(base64Data);
  }
  return null;
}
export function renderImage(base64Data, imageDimensions, options = {}) {
  const caps = getCapabilities();
  if (!caps.images) {
    return null;
  }
  const maxWidth = options.maxWidthCells ?? 80;
  const rows = calculateImageRows(imageDimensions, maxWidth, getCellDimensions());
  if (caps.images === 'kitty') {
    // Only use imageId if explicitly provided - static images don't need IDs
    const sequence = encodeKitty(base64Data, { columns: maxWidth, rows, imageId: options.imageId });
    return { sequence, rows, imageId: options.imageId };
  }
  if (caps.images === 'iterm2') {
    const sequence = encodeITerm2(base64Data, {
      width: maxWidth,
      height: 'auto',
      preserveAspectRatio: options.preserveAspectRatio ?? true
    });
    return { sequence, rows };
  }
  return null;
}
export function imageFallback(mimeType, dimensions, filename) {
  const parts = [];
  if (filename) parts.push(filename);
  parts.push(`[${mimeType}]`);
  if (dimensions) parts.push(`${dimensions.widthPx}x${dimensions.heightPx}`);
  return `[Image: ${parts.join(' ')}]`;
}
//# sourceMappingURL=terminal-image.js.map
