// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:ffi';

import 'package:ffi/ffi.dart';
import 'package:expect/expect.dart';

/// typedef struct {
///     unsigned int bold      : 1;
///     unsigned int underline : 2;
///     unsigned int italic    : 1;
///     unsigned int blink     : 1;
///     unsigned int reverse   : 1;
///     unsigned int strike    : 1;
///     unsigned int font      : 4;
/// } ScreenCellAttrs;
class ScreenCellAttrs extends Struct {
  @Int16()
  external int bits;

  int get bold => getBits(kBoldFieldOffset, kBoldFieldLength);
  void set bold(int value) =>
      setBits(kBoldFieldOffset, kBoldFieldLength, value);

  int get underline => getBits(kUnderlineFieldOffset, kUnderlineFieldLength);
  void set underline(int value) =>
      setBits(kUnderlineFieldOffset, kUnderlineFieldLength, value);

  int get italic => getBits(kItalicFieldOffset, kItalicFieldLength);
  void set italic(int value) =>
      setBits(kItalicFieldOffset, kItalicFieldLength, value);

  int get blink => getBits(kBlinkFieldOffset, kBlinkFieldLength);
  void set blink(int value) =>
      setBits(kBlinkFieldOffset, kBlinkFieldLength, value);

  int get reverse => getBits(kReverseFieldOffset, kReverseFieldLength);
  void set reverse(int value) =>
      setBits(kReverseFieldOffset, kReverseFieldLength, value);

  int get strike => getBits(kStrikeFieldOffset, kStrikeFieldLength);
  void set strike(int value) =>
      setBits(kStrikeFieldOffset, kStrikeFieldLength, value);

  int get font => getBits(kFontFieldOffset, kFontFieldLength);
  void set font(int value) =>
      setBits(kFontFieldOffset, kFontFieldLength, value);

  int getBits(int offset, int length) => bits.getBits(offset, length);

  void setBits(int offset, int length, int value) {
    bits = bits.setBits(offset, length, value);
  }
}

const int kBoldFieldOffset = 0;
const int kBoldFieldLength = 1;
const int kUnderlineFieldOffset = kBoldFieldOffset + kBoldFieldLength;
const int kUnderlineFieldLength = 2;
const int kItalicFieldOffset = kUnderlineFieldOffset + kUnderlineFieldLength;
const int kItalicFieldLength = 1;
const int kBlinkFieldOffset = kItalicFieldOffset + kItalicFieldLength;
const int kBlinkFieldLength = 1;
const int kReverseFieldOffset = kBlinkFieldOffset + kBlinkFieldLength;
const int kReverseFieldLength = 1;
const int kStrikeFieldOffset = kReverseFieldOffset + kReverseFieldLength;
const int kStrikeFieldLength = 1;
const int kFontFieldOffset = kStrikeFieldOffset + kStrikeFieldLength;
const int kFontFieldLength = 4;

/// Extension to use a 64-bit integer as bit field.
extension IntBitField on int {
  static int _bitMask(int offset, int lenght) => ((1 << lenght) - 1) << offset;

  /// Read `length` bits at `offset`.
  ///
  /// Truncates everything.
  int getBits(int offset, int length) {
    final mask = _bitMask(offset, length);
    return (this & mask) >> offset;
  }

  /// Returns a new integer value in which `length` bits are overwritten at
  /// `offset`.
  ///
  /// Truncates everything.
  int setBits(int offset, int length, int value) {
    final mask = _bitMask(offset, length);
    return (this & ~mask) | ((value << offset) & mask);
  }
}

main() {
  final p = calloc<ScreenCellAttrs>(3);

  // Zeroes out all fields.
  p.ref.bits = 0;

  // Set individual fields.
  p.ref.blink = 0;
  p.ref.bold = 1;
  p.ref.font = 15;
  p.ref.italic = 1;
  p.ref.reverse = 0;
  p.ref.strike = 0;
  p.ref.underline = 2;

  // Read individual fields.
  print(p.ref.blink);
  print(p.ref.bold);
  print(p.ref.font);
  print(p.ref.italic);
  print(p.ref.reverse);
  print(p.ref.strike);
  print(p.ref.underline);

  // A check for automated testing.
  Expect.equals(1933, p.ref.bits);

  calloc.free(p);
}
