import 'package:wolf_3d_dart/src/registry/keys/hud_key.dart';
import 'package:wolf_3d_dart/src/registry/modules/hud_module.dart';

/// Built-in HUD module for Wolf3D shareware data variants.
///
/// For known original WL1 data, the HUD picture table is shifted by +12 from
/// retail indices. For unknown shareware-like data, the offset is detected from
/// the STATUSBARPIC landmark at runtime.
class SharewareHudModule extends HudModule {
  SharewareHudModule({this.useOriginalWl1Map = false});

  final bool useOriginalWl1Map;

  static const int _originalWl1Offset = 12;
  static const int _retailStatusBarIndex = 83;

  static const List<HudKey> _faceBands = [
    HudKey.faceHealthy,
    HudKey.faceScratched,
    HudKey.faceHurt,
    HudKey.faceWounded,
    HudKey.faceBadlyWounded,
    HudKey.faceDying,
    HudKey.faceNearDeath,
  ];

  static final Map<HudKey, int> _retailBaseline = {
    HudKey.statusBar: 83,
    HudKey.digit0: 96,
    HudKey.digit1: 97,
    HudKey.digit2: 98,
    HudKey.digit3: 99,
    HudKey.digit4: 100,
    HudKey.digit5: 101,
    HudKey.digit6: 102,
    HudKey.digit7: 103,
    HudKey.digit8: 104,
    HudKey.digit9: 105,
    HudKey.faceHealthy: 106,
    HudKey.faceScratched: 109,
    HudKey.faceHurt: 112,
    HudKey.faceWounded: 115,
    HudKey.faceBadlyWounded: 118,
    HudKey.faceDying: 121,
    HudKey.faceNearDeath: 124,
    HudKey.faceDead: 127,
    HudKey.pistolIcon: 89,
    HudKey.machineGunIcon: 90,
    HudKey.chainGunIcon: 91,
  };

  int? _offset;

  void initWithImageSizes(List<({int width, int height})> imageSizes) {
    _offset = _computeOffset(imageSizes);
  }

  int _computeOffset(List<({int width, int height})> sizes) {
    for (int i = 0; i < sizes.length; i++) {
      final s = sizes[i];
      if (s.width >= 280 && s.height >= 24 && s.height <= 64) {
        return i - _retailStatusBarIndex;
      }
    }
    return 0;
  }

  int get _effectiveOffset => useOriginalWl1Map ? _originalWl1Offset : (_offset ?? 0);

  @override
  HudAssetRef? resolve(HudKey key) {
    final base = _retailBaseline[key];
    if (base == null) return null;
    return HudAssetRef(base + _effectiveOffset);
  }

  @override
  HudKey faceKeyForHealth(int health) {
    if (health <= 0) return HudKey.faceDead;
    final band = ((100 - health) ~/ 16).clamp(0, _faceBands.length - 1);
    return _faceBands[band];
  }
}
