import { AddressTypeExtension } from "pbHelpers/AddressType";
import { DeviceAvailability } from "pbHelpers/DeviceAvailability";
import { pond } from "protobuf-ts/pond";
import { quack } from "protobuf-ts/quack";

export interface ConfigurablePin {
  address: number;
  label: string;
}

export const ConfigurablePinArray: AddressTypeExtension = {
  addressType: quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY,
  friendlyName: "Pin",
  humanReadableAddress: (
    componentType: quack.ComponentType,
    address: number,
    product?: pond.DeviceProduct
  ): string => {
    const availability = new DeviceAvailability(product).GetAvailability();
    let pinArray = availability.get(
      quack.AddressType.ADDRESS_TYPE_CONFIGURABLE_PIN_ARRAY
    ) as ConfigurablePin[];
    let pin = pinArray.find(p => p.address === address);
    return pin ? pin.label : "";
  },
  singular: false
};

const MAX_PINS = 14;

//converts an array of pins to an address
export function getAddressFromPinArray(pinArray: number[]): number {
  let address = 0;

  pinArray.forEach(pin => {
    if (!(pin <= 0 || pin > MAX_PINS)) {
      address |= 1 << (pin - 1); //physical array starts at 1, bit index starts at 0
    }
  });

  return address;
}

// converts an address to a configurable pin array
export function toConfigurablePinArray(address: number): number[] {
  let pinArray: number[] = [];

  for (let i = 0; i < MAX_PINS; i++) {
    if (address & (1 << i)) {
      pinArray.push(i + 1);
    } else {
      pinArray.push(0);
    }
  }

  return pinArray;
}

export function createPinsArray(): number[] {
  var pinsArray = [];

  for (var i = 1; i <= MAX_PINS; i++) {
    pinsArray.push(getAddressFromPinArray([i]));
  }

  return pinsArray;
}
