import { stitchTypes } from '$lib/file-renderer/pattern';

/**
 * Decodes stitch flags from the 3rd byte of a DST stitch command.
 *
 * @param {number} b2 The third byte of the stitch command.
 * @returns {number} Bitmask representing stitch types.
 */
function decodeExp(b2) {
  if (b2 === 0xf3) {
    return stitchTypes.end;
  }
  if ((b2 & 0xc3) === 0xc3) {
    return stitchTypes.trim | stitchTypes.stop;
  }

  let returnCode = 0;
  if (b2 & 0x80) {
    returnCode |= stitchTypes.trim;
  }
  if (b2 & 0x40) {
    returnCode |= stitchTypes.stop;
  }
  return returnCode;
}

/**
 * Reads a DST embroidery file and populates the pattern object.
 *
 *
 * @param {EmbroideryFileView} file
 * @param {EmbroideryPattern} pattern
 */
export function dstRead(file, pattern) {
  let prevJump = false;
  const byteCount = file.byteLength;

  file.seek(512); // Skip DST header

  while (file.tell() < byteCount - 3) {
    /** @type {number[]} */
    const b = [file.getUint8(), file.getUint8(), file.getUint8()];

    let x = 0;
    let y = 0;

    // Decode X movements
    if (b[0] & 0x01) x += 1;
    if (b[0] & 0x02) x -= 1;
    if (b[0] & 0x04) x += 9;
    if (b[0] & 0x08) x -= 9;

    if (b[1] & 0x01) x += 3;
    if (b[1] & 0x02) x -= 3;
    if (b[1] & 0x04) x += 27;
    if (b[1] & 0x08) x -= 27;

    if (b[2] & 0x04) x += 81;
    if (b[2] & 0x08) x -= 81;

    // Decode Y movements
    if (b[0] & 0x80) y += 1;
    if (b[0] & 0x40) y -= 1;
    if (b[0] & 0x20) y += 9;
    if (b[0] & 0x10) y -= 9;

    if (b[1] & 0x80) y += 3;
    if (b[1] & 0x40) y -= 3;
    if (b[1] & 0x20) y += 27;
    if (b[1] & 0x10) y -= 27;

    if (b[2] & 0x20) y += 81;
    if (b[2] & 0x10) y -= 81;

    let flags = decodeExp(b[2]);
    const thisJump = (flags & stitchTypes.jump) !== 0;

    if (prevJump) {
      flags |= stitchTypes.jump;
    }

    pattern.addStitchRel(x, y, flags, true);

    prevJump = thisJump;
  }

  pattern.addStitchRel(0, 0, stitchTypes.end, true);
  pattern.invertPatternVertical();
}
