use piston_window;
use piston_window::{Context, G2d, Glyphs, RenderArgs, Transformed};
use piston_window::types::Scalar;
use rusttype::{Rect, Scale, VMetrics};

use {GameState, InnerState, Progress};

mod text;

/// Draws the game state.
pub fn 
(state: &GameState,
            render_args: RenderArgs,
            context: Context,
            graphics: &mut G2d,
            glyphs: &mut Glyphs) {
    let black = [0.0, 0.0, 0.0, 1.0];
    let white = [1.0, 1.0, 1.0, 1.0];
    piston_window::clear(black, graphics);

    let border = 32.0; // thickness of border, in pixels

    let (title, shake) = match state.state {
        InnerState::Falling(progress) => {
            ((render_args.height as Scalar - border) * progress * progress, 0.0)
        }
        InnerState::Settling(progress) => {
            (render_args.height as Scalar - border,
             border * (1.0 - progress) * Progress::sin(progress * 64.0))
        }
        InnerState::Done => (render_args.height as Scalar - border, 0.0),
    };

    {
        let points = 16;
        let pixels = text::points_to_pixels(points);
        let VMetrics { ascent, descent, .. } = glyphs.font
            .v_metrics(Scale::uniform(pixels));
        let fps_text = format!("{} FPS", state.fps);
        let mut draw = |text, x: &Fn(Rect<f32>) -> Scalar, y| {
            let bounding_box = text::bounding_box(&glyphs.font, pixels, text)
                .unwrap();
            let transform = context.transform.trans(x(bounding_box), y);
            piston_window::text(white,
                                points,
                                text,
                                glyphs,
                                transform,
                                graphics);
        };
        draw("Games, Inc.",
             &|bounding_box| border - bounding_box.min.x as Scalar,
             border + ascent as Scalar + shake);
        draw("This is some text.",
             &|bounding_box| {
                 render_args.width as Scalar - border -
                 bounding_box.max.x as Scalar
             },
             border + ascent as Scalar + shake);
        draw("Copyright 1942",
             &|bounding_box| border - bounding_box.min.x as Scalar,
             render_args.height as Scalar - border + descent as Scalar + shake);
        draw(&fps_text,
             &|bounding_box| {
                 render_args.width as Scalar - border -
                 bounding_box.max.x as Scalar
             },
             render_args.height as Scalar - border + descent as Scalar + shake);
    }

    let text = "COUNTDOWN";
    let points = 128;
    let pixels = text::points_to_pixels(points);
    let bounding_box = text::bounding_box(&glyphs.font, pixels, text).unwrap();
    let transform = context.transform
        .trans(render_args.width as Scalar / 2.0 -
               (bounding_box.min.x + bounding_box.width() / 2.0) as Scalar,
               title + shake +
               glyphs.font.v_metrics(Scale::uniform(pixels)).descent as Scalar);
    piston_window::text(white, points, text, glyphs, transform, graphics);
}

draw