use super::input::InputSession;
use crate::pinyin::glide::{decode_glide, rank_by_dictionary, GlideKeyboard, GlidePoint};
use crate::types::{KeyResult, LocalInputMode, SchemeType};
const GLIDE_HYPOTHESES: usize = 16;
impl InputSession {
pub(super) fn glide(&mut self, keyboard: &GlideKeyboard, points: &[GlidePoint]) -> KeyResult {
self.exit_date_time_menu();
if self.dedicated_english
|| self.local_mode != LocalInputMode::None
|| self.scheme() != SchemeType::Quanpin
{
return KeyResult::unhandled();
}
self.leave_conversion();
let hypotheses = decode_glide(keyboard, points, GLIDE_HYPOTHESES);
let engine = &self.engine;
let ranked = rank_by_dictionary(hypotheses, |keys| engine.quanpin_best_weights(keys));
let Some(best) = ranked.into_iter().next() else {
return KeyResult::unhandled();
};
self.insert_glide_letters(&best.letters)
}
fn insert_glide_letters(&mut self, letters: &str) -> KeyResult {
let Some((&first, rest)) = letters.as_bytes().split_first() else {
return KeyResult::unhandled();
};
if !self.has_composition() {
let typed = self.handle_character(first, false);
if !typed.handled || rest.is_empty() {
return typed;
}
let text = {
let current = self.raw_with_cases();
let mut text = String::with_capacity(current.len() + rest.len());
text.push_str(current);
text.push_str(&letters[1..]);
text
};
let caret = text.len();
return self.replace_editing_text(&text, caret);
}
let caret = self.caret_position();
let (text, new_caret) = {
let current = self.raw_with_cases();
let left_separator = caret > 0 && !current[..caret].ends_with('\'');
let right_separator = caret < current.len() && !current[caret..].starts_with('\'');
let inserted_len =
letters.len() + usize::from(left_separator) + usize::from(right_separator);
let mut text = String::with_capacity(current.len() + inserted_len);
text.push_str(¤t[..caret]);
if left_separator {
text.push('\'');
}
text.push_str(letters);
if right_separator {
text.push('\'');
}
text.push_str(¤t[caret..]);
(text, caret + inserted_len)
};
self.replace_editing_text(&text, new_caret)
}
}