use crate::elements::Code;
use crate::{DEFAULT_FONT_SIZE, WidgetBuilder};
use gtk4::{Overflow, PolicyType, ScrolledWindow, Widget, prelude::*};

impl WidgetBuilder {
    pub(super) fn create_source_view(&self, code: Code) -> Widget {
        let style_scheme = sourceview::StyleSchemeManager::default()
            .scheme("solarized-dark")
            .unwrap();

        let language = code
            .lang
            .as_deref()
            .and_then(|lang| sourceview::LanguageManager::default().language(lang))
            .unwrap_or_else(|| {
                sourceview::LanguageManager::default()
                    .language("c")
                    .unwrap()
            });

        let buffer = sourceview::Buffer::builder()
            .text(&code.text)
            .style_scheme(&style_scheme)
            .language(&language)
            .build();

        let font_size = buffer
            .create_tag(
                None,
                &[("size_points", &((self.config.font_size - 1) as f64))],
            )
            .unwrap();

        let len = code.text.chars().count() as i32 + 1;

        let start = buffer.iter_at_offset(0);
        let end = buffer.iter_at_offset(len);

        buffer.apply_tag(&font_size, &start, &end);

        let spacing = (3.0 * (self.config.font_size as f64 / DEFAULT_FONT_SIZE as f64)) as i32;

        let view = sourceview::View::builder()
            .buffer(&buffer)
            .editable(false)
            .pixels_above_lines(spacing)
            .pixels_below_lines(spacing)
            .background_pattern(sourceview::BackgroundPatternType::Grid)
            .left_margin(10)
            .right_margin(10)
            .top_margin(10)
            .bottom_margin(10)
            .build();

        let scrolled_window = ScrolledWindow::builder()
            .vscrollbar_policy(PolicyType::Never)
            .css_classes(["rounded-edges"])
            .overflow(Overflow::Hidden)
            .child(&view)
            .build();

        scrolled_window.upcast()
    }
}
