use eframe::egui::FontDefinitions;
use eframe::{
    egui::{Context, Slider, Window},
    App, Frame, NativeOptions,
};
use egui::{Color32, FontId, Shadow, Style, Visuals};
use egui_notify::{Toast, Toasts};
use std::time::Duration;

struct ExampleApp {
    toasts: Toasts,
    caption: String,
    closable: bool,
    show_progress_bar: bool,
    expires: bool,
    duration: f32,
    font_size: f32,
    dark: bool,
    custom_level_string: String,
    custom_level_color: egui::Color32,
    shadow: bool,
}

impl App for ExampleApp {
    fn update(&mut self, ctx: &Context, _: &mut Frame) {
        Window::new("Controls").show(ctx, |ui| {
            ui.text_edit_multiline(&mut self.caption);
            ui.checkbox(&mut self.expires, "Expires");
            ui.checkbox(&mut self.closable, "Closable");
            ui.checkbox(&mut self.show_progress_bar, "ShowProgressBar");
            ui.checkbox(&mut self.shadow, "Shadow").clicked().then(|| {
                self.toasts = if self.shadow {
                    Toasts::default().with_shadow(Shadow {
                        offset: Default::default(),
                        blur: 30.0,
                        spread: 5.0,
                        color: Color32::from_black_alpha(70),
                    })
                } else {
                    Toasts::default()
                };
            });
            if !(self.expires || self.closable) {
                ui.label("Warning; toasts will have to be closed programatically");
            }
            ui.add_enabled_ui(self.expires, |ui| {
                ui.horizontal(|ui| {
                    ui.label("Duration (in s)");
                    ui.add(Slider::new(&mut self.duration, 1.0..=10.0));
                });
                ui.horizontal(|ui| {
                    ui.label("Font size");
                    ui.add(Slider::new(&mut self.font_size, 8.0..=20.0));
                });
            });
            ui.text_edit_singleline(&mut self.custom_level_string);
            ui.color_edit_button_srgba(&mut self.custom_level_color);

            let customize_toast = |t: &mut Toast| {
                let duration = if self.expires {
                    Some(Duration::from_millis((1000. * self.duration) as u64))
                } else {
                    None
                };
                t.closable(self.closable)
                    .duration(duration)
                    .show_progress_bar(self.show_progress_bar)
                    .font(FontId::proportional(self.font_size));
            };

            ui.horizontal(|ui| {
                if ui.button("Success").clicked() {
                    customize_toast(self.toasts.success(self.caption.clone()));
                }

                if ui.button("Info").clicked() {
                    customize_toast(self.toasts.info(self.caption.clone()));
                }

                if ui.button("Warning").clicked() {
                    customize_toast(self.toasts.warning(self.caption.clone()));
                }

                if ui.button("Error").clicked() {
                    customize_toast(self.toasts.error(self.caption.clone()));
                }

                if ui.button("Basic").clicked() {
                    customize_toast(self.toasts.basic(self.caption.clone()));
                }

                if ui.button("Custom").clicked() {
                    customize_toast(self.toasts.custom(
                        self.caption.clone(),
                        self.custom_level_string.clone(),
                        self.custom_level_color,
                    ));
                }

                if ui
                    .button("Phosphor")
                    .on_hover_text("This toast uses egui-phosphor icons")
                    .clicked()
                {
                    customize_toast(self.toasts.custom(
                        self.caption.clone(),
                        egui_phosphor::regular::FAN.to_owned(),
                        self.custom_level_color,
                    ));
                }
            });

            ui.separator();

            if ui.button("Dismiss all toasts").clicked() {
                self.toasts.dismiss_all_toasts();
            }
            if ui.button("Dismiss latest toast").clicked() {
                self.toasts.dismiss_latest_toast();
            }
            if ui.button("Dismiss oldest toast").clicked() {
                self.toasts.dismiss_oldest_toast();
            }

            ui.separator();

            if ui.radio(self.dark, "Toggle dark theme").clicked() {
                self.dark = !self.dark;

                let mut style = ctx.style().as_ref().clone();
                if self.dark {
                    style.visuals = Visuals::dark();
                } else {
                    style.visuals = Visuals::light();
                }
                ctx.set_style(style);
            }
        });

        self.toasts.show(ctx);
    }
}

fn main() -> eframe::Result<()> {
    eframe::run_native(
        "example",
        NativeOptions::default(),
        Box::new(|cc| {
            cc.egui_ctx.set_style(Style::default());

            let mut font_def = FontDefinitions::default();
            egui_phosphor::add_to_fonts(&mut font_def, egui_phosphor::Variant::Regular);
            for data in font_def.font_data.values_mut() {
                data.tweak.scale = 1.25;
            }
            cc.egui_ctx.set_fonts(font_def);

            Ok(Box::new(ExampleApp {
                caption: r#"Hello! It's a multiline caption
Next line
Another one
And another one"#
                    .into(),
                toasts: Toasts::default(),
                closable: true,
                expires: true,
                show_progress_bar: true,
                duration: 3.5,
                dark: true,
                font_size: 16.,
                custom_level_string: "$".into(),
                custom_level_color: egui::Color32::GREEN,
                shadow: true,
            }))
        }),
    )
}
