#[derive(Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Panels {
    left: bool,
    right: bool,
    top: bool,
    bottom: bool,
}

impl Default for Panels {
    fn default() -> Self {
        Self {
            left: true,
            right: true,
            top: true,
            bottom: false,
        }
    }
}

impl crate::Demo for Panels {
    fn name(&self) -> &'static str {
        "🗖 Panels"
    }

    fn show(&mut self, ui: &mut egui::Ui, open: &mut bool) {
        use crate::View as _;
        egui::Window::new("Panels")
            .default_width(600.0)
            .default_height(600.0)
            .vscroll(false)
            .open(open)
            .constrain_to(ui.available_rect_before_wrap())
            .show(ui, |ui| self.ui(ui));
    }
}

impl crate::View for Panels {
    fn ui(&mut self, ui: &mut egui::Ui) {
        // Note that the order we add the panels is very important!

        let Self {
            left,
            right,
            top,
            bottom,
        } = self;

        egui::Panel::top("top_panel")
            .resizable(true)
            .min_size(32.0)
            .show_collapsible(ui, top, |ui| {
                egui::ScrollArea::vertical().show(ui, |ui| {
                    ui.vertical_centered(|ui| {
                        ui.heading("Expandable Upper Panel");
                    });
                    lorem_ipsum(ui);
                });
            });

        egui::Panel::left("left_panel")
            .resizable(true)
            .default_size(150.0)
            .size_range(80.0..=200.0)
            .show_collapsible(ui, left, |ui| {
                ui.vertical_centered(|ui| {
                    ui.heading("Left Panel");
                });
                egui::ScrollArea::vertical().show(ui, |ui| {
                    lorem_ipsum(ui);
                });
            });

        egui::Panel::right("right_panel")
            .resizable(true)
            .default_size(150.0)
            .size_range(80.0..=200.0)
            .show_collapsible(ui, right, |ui| {
                ui.vertical_centered(|ui| {
                    ui.heading("Right Panel");
                });
                egui::ScrollArea::vertical().show(ui, |ui| {
                    lorem_ipsum(ui);
                });
            });

        // Bottom panel: drag the top edge down past the expanded panel's min size
        // to collapse; drag it back up past the collapsed panel's max size to
        // re-expand. Both panels are `.resizable(true)` so each one's edge accepts
        // the gesture; the collapsed panel uses `exact_size` so even a tiny
        // outward drag is enough to trigger the swap.
        egui::Panel::show_switched(
            ui,
            bottom,
            egui::Panel::bottom("bottom_panel_collapsed")
                .resizable(true)
                .exact_size(20.0),
            egui::Panel::bottom("bottom_panel_expanded")
                .resizable(true)
                .size_range(64.0..=128.0),
            |ui, expanded| {
                if expanded {
                    ui.vertical_centered(|ui| {
                        ui.heading("Bottom panel");
                    });
                    egui::ScrollArea::vertical().show(ui, |ui| {
                        lorem_ipsum(ui);
                    });
                } else {
                    ui.vertical_centered(|ui| {
                        ui.label("Bottom panel (collapsed)");
                    });
                }
            },
        );

        // TODO(emilk): This extra panel is superfluous - just use what's left of `ui` instead
        egui::CentralPanel::default().show(ui, |ui| {
            ui.vertical_centered(|ui| {
                ui.heading("Central Panel");
            });

            ui.horizontal(|ui| {
                ui.label("Panel toggles:");
                ui.toggle_value(left, "⬅");
                ui.toggle_value(top, "⬆");
                ui.toggle_value(bottom, "⬇");
                ui.toggle_value(right, "➡");
            });

            ui.separator();

            egui::ScrollArea::vertical().show(ui, |ui| {
                lorem_ipsum(ui);
            });
        });
    }
}

fn lorem_ipsum(ui: &mut egui::Ui) {
    ui.with_layout(
        egui::Layout::top_down(egui::Align::LEFT).with_cross_justify(true),
        |ui| {
            ui.label(egui::RichText::new(crate::LOREM_IPSUM_LONG).small().weak());
            ui.add(egui::Separator::default().grow(8.0));
            ui.label(egui::RichText::new(crate::LOREM_IPSUM_LONG).small().weak());
        },
    );
}
