bevy 布局测试

use bevy::prelude::*;

const VIRTUAL_WIDTH: f32 = 1920.0;
const VIRTUAL_HEIGHT: f32 = 1080.0;

// 字体资源
#[derive(Resource)]
struct FontAssets {
    default: Handle<Font>,
}

// 图片资源
#[derive(Resource)]
struct ImageAssets {
    background: Handle<Image>,
    main_menu: Handle<Image>,
}

// 加载状态
#[derive(States, Debug, Clone, PartialEq, Eq, Hash, Default)]
enum AppState {
    #[default]
    Loading,
    Ready,
}

// 按钮组件
#[derive(Component)]
struct StartGameButton;

#[derive(Component)]
struct AboutButton;

#[derive(Component)]
struct HelpButton;

#[derive(Component)]
struct ExitGameButton;

#[derive(Component)]
struct SceneEntity;

// 字体大小枚举
#[derive(Clone, Copy)]
enum FontSize {
    Small,
    Normal,
    Large,
    XLarge,
    XXLarge,
}

impl FontSize {
    fn value(self) -> f32 {
        match self {
            FontSize::Small => 16.0,
            FontSize::Normal => 24.0,
            FontSize::Large => 32.0,
            FontSize::XLarge => 48.0,
            FontSize::XXLarge => 64.0,
        }
    }
}

// 字体样式
#[derive(Clone, Copy)]
enum FontStyle {
    Normal,
    Bold,
    Italic,
    Chinese,
}

// 字体设置结构体
struct FontConfig {
    style: FontStyle,
    size: FontSize,
    color: Color,
}

impl Default for FontConfig {
    fn default() -> Self {
        Self {
            style: FontStyle::Normal,
            size: FontSize::Normal,
            color: Color::WHITE,
        }
    }
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_state::<AppState>()
        .add_systems(Startup, load_assets)
        .add_systems(Update, (
            check_assets_loaded.run_if(in_state(AppState::Loading)),
            update_ui_scale.run_if(in_state(AppState::Ready)),
            handle_button_clicks.run_if(in_state(AppState::Ready)),
        ))
        .add_systems(OnEnter(AppState::Ready), setup)
        .run();
}

// 加载资源
fn load_assets(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
) {
    // 加载字体
    let font_assets = FontAssets {
        default: asset_server.load("fonts/SarasaFixedHC-Light.ttf"),
    };
    
    // 加载图片
    let image_assets = ImageAssets {
        background: asset_server.load("gui/game3.png"),
        main_menu: asset_server.load("gui/main_menu.png"),
    };
    
    commands.insert_resource(font_assets);
    commands.insert_resource(image_assets);
    
    // 显示加载画面
    commands.spawn((Camera2d, Camera::default()));
    
    // 简单的加载画面
    commands
        .spawn((
            Node {
                width: Val::Percent(100.0),
                height: Val::Percent(100.0),
                justify_content: JustifyContent::Center,
                align_items: AlignItems::Center,
                ..default()
            },
            BackgroundColor(Color::BLACK),
        ))
        .with_children(|parent| {
            parent.spawn((
                Text::new("Loading..."),
                TextFont {
                    font_size: 48.0,
                    ..default()
                },
                TextColor(Color::WHITE),
            ));
        });
}

// 检查资源是否加载完成
fn check_assets_loaded(
    asset_server: Res<AssetServer>,
    font_assets: Res<FontAssets>,
    image_assets: Res<ImageAssets>,
    mut next_state: ResMut<NextState<AppState>>,
    mut commands: Commands,
    loading_ui: Query<Entity, With<Node>>,
) {
    let font_loaded = matches!(
        asset_server.load_state(font_assets.default.id()), 
        bevy::asset::LoadState::Loaded
    );
    let background_loaded = matches!(
        asset_server.load_state(image_assets.background.id()), 
        bevy::asset::LoadState::Loaded
    );
    let main_menu_loaded = matches!(
        asset_server.load_state(image_assets.main_menu.id()), 
        bevy::asset::LoadState::Loaded
    );
    
    if font_loaded && background_loaded && main_menu_loaded {
        // 清除加载画面
        for entity in loading_ui.iter() {
            commands.entity(entity).despawn();
        }
        
        // 切换到就绪状态
        next_state.set(AppState::Ready);
        
        println!("All assets loaded successfully!");
    }
}

fn setup(
    mut commands: Commands, 
    _font_assets: Res<FontAssets>,
    image_assets: Res<ImageAssets>,
    asset_server: Res<AssetServer>,
) {
    // Logo设置
    let logo_text = "Raven engine";
    let logo_font_size = 48.0;
    let logo_text_color = Color::srgb(1.0, 0.8, 0.0); // 金色

    // UI 根容器
    commands
        .spawn((
            Node {
                width: Val::Percent(100.0),
                height: Val::Percent(100.0),
                justify_content: JustifyContent::Center,
                align_items: AlignItems::Center,
                ..default()
            },
            BackgroundColor(Color::BLACK),
        ))
        .with_children(|parent| {
            // 固定尺寸的内容区域
            parent
                .spawn((
                    Node {
                        width: Val::Px(VIRTUAL_WIDTH),
                        height: Val::Px(VIRTUAL_HEIGHT),
                        flex_direction: FlexDirection::Column,
                        justify_content: JustifyContent::Center,
                        align_items: AlignItems::Center,
                        ..default()
                    },
                    BackgroundColor(Color::srgb(0.2, 0.2, 0.2)),
                ))
                .with_children(|parent| {
                    // 背景图片 - game3.png (底层)
                    parent.spawn((
                        Node {
                            width: Val::Px(1920.0),
                            height: Val::Px(1080.0),
                            position_type: PositionType::Absolute,
                            left: Val::Px(0.0),
                            top: Val::Px(0.0),
                            ..default()
                        },
                        ImageNode::new(image_assets.background.clone()),
                        
                    ));

                    // 主菜单图片 - main_menu.png (覆盖在背景图片上面)
                    parent.spawn((
                        Node {
                            width: Val::Px(1920.0),
                            height: Val::Px(1080.0),
                            position_type: PositionType::Absolute,
                            left: Val::Px(0.0),
                            top: Val::Px(0.0),
                            ..default()
                        },
                        ImageNode::new(image_assets.main_menu.clone()),
                        
                    ));

                    // ===== UI菜单层 =====
                    parent.spawn((
                        SceneEntity,
                        Node {
                            width: Val::Percent(100.0),
                            height: Val::Percent(100.0),
                            flex_direction: FlexDirection::Row,
                            ..default()
                        },
                        // 使用高Z-index确保UI在Sprite之上
                        GlobalZIndex(100),
                    ))
                    .with_children(|parent| {
                        // 左侧菜单区域
                        parent.spawn((
                            Node {
                                position_type: PositionType::Absolute,
                                width: Val::Percent(50.0),
                                height: Val::Percent(100.0),
                                align_items: AlignItems::Start,
                                justify_content: JustifyContent::Center,
                                flex_direction: FlexDirection::Column,
                                padding: UiRect {
                                    left: Val::Px(50.0),
                                    right: Val::Px(30.0),
                                    top: Val::Px(0.0),
                                    bottom: Val::Px(70.0),
                                },
                                row_gap: Val::Px(20.0),
                                ..default()
                            },
                        ))
                        .with_children(|parent| {
                            // Logo文本
                            parent.spawn((
                                Text::new(logo_text),
                                TextFont {
                                    font: asset_server.load("fonts/SarasaFixedHC-Regular.ttf"),
                                    font_size: logo_font_size,
                                    ..default()
                                },
                                TextColor(logo_text_color),
                                Node {
                                    margin: UiRect {
                                        left: Val::Px(20.0),
                                        right: Val::Px(0.0),
                                        top: Val::Px(0.0),
                                        bottom: Val::Px(0.0),
                                    },
                                    ..default()
                                },
                                GlobalZIndex(110),
                            ));

                            // 开始游戏按钮
                            parent
                                .spawn((
                                    StartGameButton,
                                    Button,
                                    Node {
                                        width: Val::Px(200.0),
                                        height: Val::Px(35.0),
                                        margin: UiRect {
                                            left: Val::Px(40.0),
                                            right: Val::Px(0.0),
                                            top: Val::Px(0.0),
                                            bottom: Val::Px(0.0),
                                        },
                                        justify_content: JustifyContent::Center,
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.0)),
                                    GlobalZIndex(55),
                                ))
                                .with_children(|parent| {
                                    parent.spawn((
                                        Text::new("开始游戏"),
                                        TextFont {
                                            font: asset_server.load("fonts/SarasaFixedHC-Light.ttf"),
                                            font_size: 26.0,
                                            ..default()
                                        },
                                        TextColor(Color::srgb(0.9, 0.9, 0.9)),
                                    ));
                                });

                            // 关于按钮
                            parent
                                .spawn((
                                    AboutButton,
                                    Button,
                                    Node {
                                        width: Val::Px(200.0),
                                        height: Val::Px(35.0),
                                        margin: UiRect {
                                            left: Val::Px(40.0),
                                            right: Val::Px(0.0),
                                            top: Val::Px(0.0),
                                            bottom: Val::Px(0.0),
                                        },
                                        justify_content: JustifyContent::Center,
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.0)),
                                    GlobalZIndex(55),
                                ))
                                .with_children(|parent| {
                                    parent.spawn((
                                        Text::new("关于"),
                                        TextFont {
                                            font: asset_server.load("fonts/SarasaFixedHC-Light.ttf"),
                                            font_size: 26.0,
                                            ..default()
                                        },
                                        TextColor(Color::srgb(0.9, 0.9, 0.9)),
                                    ));
                                });

                            // 帮助按钮
                            parent
                                .spawn((
                                    HelpButton,
                                    Button,
                                    Node {
                                        width: Val::Px(200.0),
                                        height: Val::Px(35.0),
                                        margin: UiRect {
                                            left: Val::Px(40.0),
                                            right: Val::Px(0.0),
                                            top: Val::Px(0.0),
                                            bottom: Val::Px(0.0),
                                        },
                                        justify_content: JustifyContent::Center,
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.0)),
                                    GlobalZIndex(55),
                                ))
                                .with_children(|parent| {
                                    parent.spawn((
                                        Text::new("帮助"),
                                        TextFont {
                                            font: asset_server.load("fonts/SarasaFixedHC-Light.ttf"),
                                            font_size: 26.0,
                                            ..default()
                                        },
                                        TextColor(Color::srgb(0.9, 0.9, 0.9)),
                                    ));
                                });

                            // 退出按钮
                            parent
                                .spawn((
                                    ExitGameButton,
                                    Button,
                                    Node {
                                        width: Val::Px(200.0),
                                        height: Val::Px(35.0),
                                        margin: UiRect {
                                            left: Val::Px(40.0),
                                            right: Val::Px(0.0),
                                            top: Val::Px(0.0),
                                            bottom: Val::Px(0.0),
                                        },
                                        justify_content: JustifyContent::Center,
                                        align_items: AlignItems::Center,
                                        ..default()
                                    },
                                    BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.0)),
                                    GlobalZIndex(55),
                                ))
                                .with_children(|parent| {
                                    parent.spawn((
                                        Text::new("退出"),
                                        TextFont {
                                            font: asset_server.load("fonts/SarasaFixedHC-Light.ttf"),
                                            font_size: 26.0,
                                            ..default()
                                        },
                                        TextColor(Color::srgb(0.9, 0.9, 0.9)),
                                    ));
                                });
                        });

                        // 右侧透明区域
                        parent.spawn((
                            Node {
                                width: Val::Percent(50.0),
                                height: Val::Percent(100.0),
                                ..default()
                            },
                        ));
                    });
                });
        });
}

// 处理按钮点击
fn handle_button_clicks(
    mut interaction_query: Query<
        (&Interaction, &mut BackgroundColor),
        (Changed<Interaction>, With<Button>),
    >,
    start_button_query: Query<&Interaction, (Changed<Interaction>, With<StartGameButton>)>,
    about_button_query: Query<&Interaction, (Changed<Interaction>, With<AboutButton>)>,
    help_button_query: Query<&Interaction, (Changed<Interaction>, With<HelpButton>)>,
    exit_button_query: Query<&Interaction, (Changed<Interaction>, With<ExitGameButton>)>,
) {
    // 处理按钮悬停效果
    for (interaction, mut color) in &mut interaction_query {
        match *interaction {
            Interaction::Hovered => {
                *color = BackgroundColor(Color::srgba(1.0, 1.0, 1.0, 0.1));
            }
            Interaction::None => {
                *color = BackgroundColor(Color::srgba(0.0, 0.0, 0.0, 0.0));
            }
            Interaction::Pressed => {
                *color = BackgroundColor(Color::srgba(1.0, 1.0, 1.0, 0.2));
            }
        }
    }

    // 处理具体按钮点击事件
    for interaction in &start_button_query {
        if *interaction == Interaction::Pressed {
            println!("开始游戏按钮被点击!");
        }
    }

    for interaction in &about_button_query {
        if *interaction == Interaction::Pressed {
            println!("关于按钮被点击!");
        }
    }

    for interaction in &help_button_query {
        if *interaction == Interaction::Pressed {
            println!("帮助按钮被点击!");
        }
    }

    for interaction in &exit_button_query {
        if *interaction == Interaction::Pressed {
            println!("退出按钮被点击!");
        }
    }
}

fn update_ui_scale(
    windows: Query<&Window>,
    mut ui_scale: ResMut<UiScale>,
) {
    if let Some(window) = windows.iter().next() {
        let window_width = window.width();
        let window_height = window.height();
        
        // 计算缩放比例,保持宽高比
        let scale_x = window_width / VIRTUAL_WIDTH;
        let scale_y = window_height / VIRTUAL_HEIGHT;
        let scale = scale_x.min(scale_y);
        
        ui_scale.0 = scale;
    }
}