use conrod_piston::draw::Transformed;
use piston_window::*;
use find_folder;

trait State {
    fn updata(&mut self,_args:&UpdateArgs);
    fn input(&mut self,button:Button)->Option<StateCommand>;
    fn render(&mut self,c:Context,g:&mut G2d,glyphs:&mut Glyphs);
}
enum StateCommand{
    Push(Box<dyn State>),
    Pop,
    None,
}

struct ModalWindows{
    count:usize,
}
impl ModalWindows{
    fn new()->Self{
        Self { count: 0 }
    }
}
impl State for ModalWindows {
    fn input(&mut self, button: Button) -> Option<StateCommand> {
        if let Button::Keyboard(key) = button {
            match key {
                Key::Escape => return Some(StateCommand::Pop),
                Key::Space => {
                    self.count += 1;
                    println!("計數器增加到 {}", self.count);
                    return Some(StateCommand::None);
                }
                _ => {}
            }
        }
        None
    }

    fn render(&mut self, c: Context, g: &mut G2d, glyphs: &mut Glyphs) {
        // 半透明遮罩
        graphics::rectangle([0.0, 0.0, 0.0, 0.5], [0.0, 0.0, 640.0, 480.0], c.transform, g);
        // 白色視窗
        let rect = [120.0, 140.0, 400.0, 240.0];
        graphics::rectangle([1.0, 1.0, 1.0, 1.0], rect, c.transform, g);

        let text_obj = graphics::text::Text::new_color([0.0, 0.0, 0.0, 1.0], 32);
        text_obj
            .draw(
                "這是彈出視窗",
                glyphs,
                &graphics::DrawState::default(),
                c.transform.trans(180.0, 200.0),
                g,
            )
            .unwrap();
        text_obj
            .draw(
                "按 ESC 關閉，按空白鍵增加計數器",
                glyphs,
                &graphics::DrawState::default(),
                c.transform.trans(120.0, 240.0),
                g,
            )
            .unwrap();

        let counter_str = format!("空白鍵按下次數: {}", self.count);
        text_obj
            .draw(
                &counter_str,
                glyphs,
                &graphics::DrawState::default(),
                c.transform.trans(180.0, 280.0),
                g,
            )
            .unwrap();
    }
}

struct StateStack{
    stack:Vec<Box<dyn State>>
}

impl StateStack{
    fn new(initial_state:Box<dyn State>)->Self{
        Self { stack:vec![initial_state]  }
    }
    fn pop(&mut self){
        if self.stack.is_empty(){
            return;
        }

        self.stack.pop();
        if self.stack.is_empty(){
            println!("堆疊結束");

        }
    }
    fn push(&mut self,state:Box<dyn State>){
        self.stack.push(state);
    }
    fn updata(&mut self,args:&UpdateArgs){
        if let Some(top)=self.stack.last_mut(){
            top.updata(args);
        }
    }
    fn is_empty(&self)->bool{
        self.stack.is_empty()
    }
    fn render(&mut self, c: Context, g: &mut G2d, glyphs: &mut Glyphs) {
        // 依序繪製堆疊中所有狀態（從底層到頂層）
        for state in &mut self.stack {
            state.render(c, g, glyphs);
        }
    }

    fn input(&mut self,button:Button){
        if let Some(top)=self.stack.last_mut(){
            if let Some(cmd)=top.input(button){
                match cmd {
                    StateCommand::Push(State)=>self.push(State),
                    StateCommand::Pop=>self.pop(),
                    StateCommand::None=>{}
                }
            }
        }
    }

}


struct MainPage{
    circle_x:f64,
    direction:f64,
    fps_timer:f64,
    fps_count:u32,
    fps:u32,
}
impl MainPage {
    fn new()->Self{
        Self { 
            circle_x: 220.0,
             direction: 50.0,
              fps_timer: 0.0,
               fps_count: 0, 
               fps: 0 }
    }
}

impl State for MainPage {
    fn updata(&mut self,args:&UpdateArgs) {
        self.circle_x+=self.direction*args.dt;
        if self.circle_x>=660.0{
            self.circle_x=660.0;
            self.direction= -self.direction;
        }else if self.circle_x<40.0{
            self.circle_x=40.0;
            self.direction=-self.direction
        };
        self.fps_timer +=args.dt;
        self.fps_count +=1;
        if self.fps_timer>=1.0 {
            self.fps=self.fps_count;
            self.fps_count =0;
            self.fps_timer -=1.0

        } 
    }
    fn input(&mut self,button:Button)->Option<StateCommand> {
        if let Button::Keyboard(Key)=button{
            match Key {
                Key::M =>Some(StateCommand::Push(Box::new(ModalWindows::new())));
            }
        }
        None
    }
    fn render(&mut self,c:Context,g:&mut G2d,glyphs:&mut Glyphs) {
        clear([0.8,0.8,0.8,1.0], g);
        draw_text_centered("主頁按鈕", c, g, glyphs, 240.0);

           graphics::ellipse(
            [1.0, 0.0, 0.0, 1.0],
            [self.circle_x - 20.0, 300.0 - 20.0, 40.0, 40.0],
            c.transform,
            g);
               let fps_text = format!("FPS: {}", self.fps);
        let text_obj = graphics::text::Text::new_color([0.0, 0.0, 0.0, 1.0], 24);
        text_obj
            .draw(
                &fps_text,
                glyphs,
                &graphics::DrawState::default(),
                c.transform.trans(10.0, 460.0),
                g,
            )
            .unwrap();


    }
}

fn draw_text_centered(
    text_str:&str,c:Context,g:&mut G2d,glyphs:&mut Glyphs,y:f64
){
   use graphics::Transformed;
   let text_width=text_str.len() as f64 *24.0/2.0;
   let x=320.0-text_width;
   let transform=c.transform.trans(x, y);
   let text_obj=graphics::text::Text::new_color([1.0;4], 32);
   text_obj.draw(text_str,glyphs, &graphics::DrawState::default(), transform, g).unwrap();
}

fn main() {
    let mut window: PistonWindow = WindowSettings::new("狀態堆疊示例", [640, 480])
        .exit_on_esc(true)
        .build()
        .unwrap();

    let assets = find_folder::Search::ParentsThenKids(3, 3)
        .for_folder("assets")
        .expect("找不到 assets 資料夾");

    let font_path = assets.join("mingliu.ttc");

    let mut glyphs = window.load_font(font_path).expect("無法載入字型");

    let mut state_stack = StateStack::new(Box::new(MainPage::new()));

    while let Some(event) = window.next() {
        if let Some(button) = event.press_args() {
            state_stack.input(button);
        }

        if let Some(args) = event.update_args() {
            state_stack.updata(&args);
        }

        window.draw_2d(&event, |c, g, device| {
            state_stack.render(c, g, &mut glyphs);
            glyphs.factory.encoder.flush(device);
        });

        if state_stack.is_empty() {
            break;
        }
    }
}

請修正