///|
/// W1-W7: Weak Type Resolution
///
/// These rules resolve weak types (EN, ES, ET, AN, CS, NSM, BN)
/// within an isolating run sequence.

///|
/// Resolve weak types within an isolating run sequence
///
/// The rules apply one after another over the whole sequence, each seeing
/// the types the previous rule left. Two passes reproduce that: the first
/// applies W1-W3, the second W4-W7, and each keeps the earlier-rule types it
/// still needs in locals instead of re-reading them.
fn resolve_weak_types(
  types : Array[BidiClass],
  _levels : Array[Int32],
  seq : IsolatingRunSequence,
) -> Unit {
  let indices = seq.indices
  let count = indices.length()
  if count == 0 {
    return
  }

  // W1: NSM takes the type of the previous character (or sos), or ON after
  //     an isolate initiator or PDI.
  // W2: EN becomes AN when the most recent strong type is AL.
  // W3: AL becomes R.
  // The type after W1 of the previous character, which W1 reads.
  let mut previous_w1 = seq.sos
  // The most recent L, R or AL after W1, which W2 reads.
  let mut last_strong = seq.sos
  for idx in indices {
    let mut bc = types[idx]
    if bc is NSM {
      bc = if previous_w1.is_isolate_initiator() || previous_w1 is PDI {
        BidiClass::ON
      } else {
        previous_w1
      }
    }
    if !(bc is BN) {
      previous_w1 = bc
    }
    match bc {
      L => last_strong = BidiClass::L
      R => last_strong = BidiClass::R
      AL => {
        last_strong = BidiClass::AL
        bc = BidiClass::R
      }
      EN => if last_strong is AL { bc = BidiClass::AN }
      _ => ()
    }
    types[idx] = bc
  }

  // W4: A single ES between two ENs becomes EN; a single CS between two
  //     ENs becomes EN, and between two ANs becomes AN.
  // W5: A sequence of ETs adjacent to EN becomes EN.
  // W6: Remaining ES, ET and CS become ON.
  // W7: EN becomes L when the most recent strong type is L.
  // The type after W4 of the previous character, which W4 reads.
  let mut previous_w4 = BidiClass::ON
  // Whether the previous character is EN after W5.
  let mut previous_is_en = false
  // Start of a run of ETs that no EN precedes; an EN right after the run
  // still turns it into EN.
  let mut et_run_start = -1
  // The most recent L or R, which W7 reads. W3 has removed AL.
  last_strong = seq.sos
  for i in 0.. 0 && i < count - 1 {
      // The next character has not been through W4 yet, as in a W4-only pass.
      let next_bc = types[indices[i + 1]]
      if previous_w4 is EN && next_bc is EN {
        bc = BidiClass::EN
      } else if bc is CS && previous_w4 is AN && next_bc is AN {
        bc = BidiClass::AN
      }
    }
    previous_w4 = bc
    types[idx] = match bc {
      ET =>
        if previous_is_en {
          if last_strong is L {
            BidiClass::L
          } else {
            BidiClass::EN
          }
        } else {
          if et_run_start < 0 {
            et_run_start = i
          }
          BidiClass::ON
        }
      EN => {
        let resolved = if last_strong is L {
          BidiClass::L
        } else {
          BidiClass::EN
        }
        if et_run_start >= 0 {
          for j in et_run_start.. {
        previous_is_en = false
        et_run_start = -1
        match bc {
          ES | CS => BidiClass::ON
          L => {
            last_strong = BidiClass::L
            bc
          }
          R => {
            last_strong = BidiClass::R
            bc
          }
          _ => bc
        }
      }
    }
  }
}