use piston_window::*;
use find_folder;

trait State {
    fn update(&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 MainPage{
    circle_x:f64,
    direction:f64,
    fps_timer:f64,
    fps_count:u32,
    fps:u32,
}
impl MainPage{
    fn new()->Self{
        Self { circle_x: 660.0,
             direction: 400.0,
              fps_timer: 0.0,
               fps_count: 0,
                fps: 0 }
    }
}
struct ModalWindow{
    counter:usize,
}
impl ModalWindow {
    fn new()->Self{
        Self { counter: 0 }
    }
}
struct StateStack{
    stack:Vec<Box<dyn State>>
}

impl StateStack{
    fn new(initial_state:Box<dyn State>)->Self{
        Self { stack: vec![initial_state] }
    }
    fn is_empty(&self)->bool{
        self.stack.is_empty()
    }
    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 update(&mut self,args:&UpdateArgs){
        if let Some(top)=self.stack.last_mut(){
            top.update(args);
        }
    }
    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=>{}
                    }
            }
        }
    }
    

}

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([0.0, 0.0, 0.0, 1.0], 32);
    text_obj.draw(
        text_str,
         glyphs, &graphics::DrawState::default(), c.transform, g).unwrap();

}


impl State for MainPage {
    fn update(&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 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!("{}",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 input(&mut self,button:Button)->Option<StateCommand> {
       if let Button::Keyboard(key)=button{
            if key == Key::M {
                return Some(StateCommand::Push(Box::new(MainPage::new())));
            }
       }
       None
    }
}
impl State for ModalWindow{
    fn update(&mut self,args:&UpdateArgs) {}
    fn render(&mut self,c:Context,g:&mut G2d,glyphs:&mut Glyphs) {
        graphics::rectangle(
            [1.0;4], 
            [120.0,140.0,240.0,440.0], 
            c.transform, g);
        
        let rect=[0.0,0.0,640.0,480.0];
        graphics::rectangle([1.0;4], rect, c.transform.trans(150.0, 50.0), g);

        let text_obj=graphics::text::Text::new_color([1.0;4], 32);
        text_obj.draw(
            "按下M",
             glyphs,
              &graphics::DrawState::default(),
               c.transform, g).unwrap();
        let conter_text=format!("鍵盤按下{}",self.counter);
        let text_obj=graphics::text::Text::new_color([1.0;4], 32);
        text_obj.draw(&conter_text, glyphs, &graphics::DrawState::default(), c.transform.trans(10.0, 50.0), g).unwrap();

    }
    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.counter +=1;
                        println!("列印{}",self.counter);
                        return Some(StateCommand::None);
            }
            _=>{}
            }
        }
        None
    }
}

fn main(){
    let mut window22:PistonWindow=WindowSettings::new("fdfdf", [640.0,480.0,]).exit_on_esc(true).build().unwrap();

    let mut assets=find_folder::Search::ParentsThenKids(3, 3).for_folder("assets").unwrap();
    let font_path=assets.join("mingliu.ttc");
    let mut glyphs=window22.load_font(font_path).expect("找不到字形");
    let mut state_stack=StateStack::new(Box::new(MainPage::new()));

    while let Some(event) = window22.next() {
        if let Some(args)=event.update_args(){
            state_stack.update(&args);
        }
        if let Some(button)=event.press_args(){
            state_stack.input(button);
        }

     window22.draw_2d(&event, |c,g,device|{
        state_stack.render(c, g, &mut glyphs);

        glyphs.factory.encoder.flush(device);
     });
     if state_stack.is_empty(){
        break;
     }
    }


}
請修正哪裡錯誤