/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/piot/swamp-render
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */

use swamp_app::prelude::*;
use swamp_render::api::Glyph;

const VIRTUAL_SCREEN_SIZE: UVec2 = UVec2::new(320 * 2, 240 * 2);
const START_WINDOW_SIZE: UVec2 = UVec2::new(VIRTUAL_SCREEN_SIZE.x * 2, VIRTUAL_SCREEN_SIZE.y * 2);

#[derive(Debug)]
pub struct FontGlyphExample {
    pub font: FontAndMaterialRef,
    pub offset: u16,
    pub glyphs: Option<Vec<Glyph>>,
}

const REALLY_LONG_STRING: &str = "\
... it will start soon...         Hello, can you see this text? If so, it seems to be working. \
Grab a snack, sit back, and enjoy the scrolling... it’s mesmerizing, isn’t it? \
So cool to bring back the scroll text from the 1980s. #retro                 ";

impl Application for FontGlyphExample {
    fn new(assets: &mut impl Assets) -> Self {
        Self {
            font: assets.bm_font("menu"),
            offset: 0,
            glyphs: None,
        }
    }

    fn tick(&mut self) {
        self.offset += 4;
        self.offset %= VIRTUAL_SCREEN_SIZE.x * 12;
    }

    fn render(&mut self, gfx: &mut impl Gfx) {
        const MAX_AMPLITUDE: i16 = 32;
        let time_angle = (self.offset as f32) * 0.02;

        if let Some(glyphs) = &self.glyphs {
            let start_x = (VIRTUAL_SCREEN_SIZE.x as i16) - (self.offset as i16);
            for glyph in glyphs {
                let local_angle = (glyph.relative_position.x as f32) * 0.002;
                let amplitude = ((time_angle + local_angle).sin() * MAX_AMPLITUDE as f32) as i16;
                gfx.sprite_atlas(
                    Vec3::new(
                        start_x + glyph.relative_position.x,
                        (VIRTUAL_SCREEN_SIZE.y / 2) as i16 + glyph.relative_position.y + amplitude,
                        1,
                    ),
                    glyph.texture_rectangle,
                    &self.font.material_ref,
                )
            }
        } else {
            self.glyphs = Some(gfx.text_glyphs(Vec2::new(0, 0), REALLY_LONG_STRING, &self.font));
        }
    }
}

fn main() {
    App::<FontGlyphExample>::run(
        "Font Glyphs Example",
        VIRTUAL_SCREEN_SIZE,
        START_WINDOW_SIZE,
    );
}
