use egui::emath::GuiRounding;
use egui::{emath, CursorIcon, Id, InnerResponse, LayerId, Order, Sense, Ui, UiBuilder};
use std::any::Any;

pub mod shell;
pub mod tokens;

static FULL_SPAN_TAG: &str = "wxbox_fullspan";

pub trait UiExt {
    fn ui(&self) -> &egui::Ui;
    fn ui_mut(&mut self) -> &mut egui::Ui;

    fn full_span(&self) -> egui::Rangef {
        for node in self.ui().stack().iter() {
            if let Some(span) = node.tags().get_downcast(FULL_SPAN_TAG) {
                return *span;
            }

            if node.has_visible_frame()
                || node.is_area_ui()
                || node.is_panel_ui()
                || node.is_root_ui()
            {
                return (node.max_rect + node.frame().inner_margin).x_range();
            }
        }

        // should never happen
        egui::Rangef::EVERYTHING
    }

    fn full_span_separator(&mut self) -> egui::Response {
        let ui = self.ui_mut();
        let height = 1.0;
        let avail_space = ui.available_size_before_wrap();
        let size = egui::vec2(avail_space.x, height);
        let (rect, response) = ui.allocate_at_least(size, egui::Sense::hover());
        if ui.is_rect_visible(response.rect) {
            let stroke = ui.visuals().widgets.noninteractive.bg_stroke;
            let painter = ui.painter();

            painter.hline(
                ui.full_span(),
                rect.center().y.round_to_pixels(painter.pixels_per_point()),
                stroke,
            );
        }
        response
    }
}

impl UiExt for egui::Ui {
    #[inline]
    fn ui(&self) -> &egui::Ui {
        self
    }

    #[inline]
    fn ui_mut(&mut self) -> &mut egui::Ui {
        self
    }
}
