extern crate cairo;

use std::io::Write;
use std::{time,thread};

const XSIZE: i32 = 1024;
const YSIZE: i32 = 768;
const XCENTER: f64 = XSIZE as f64 / 2.0;
const YCENTER: f64 = YSIZE as f64 / 2.0;
const TAU: f64 = 2.0 * std::f64::consts::PI;

/// Return `true` if slim has started, `false` otherwise
fn check_slim() -> bool {
    use std::process::{Command};

    let o = Command::new("sv")
        .args(&["status", "slim"])
        .output()
        .unwrap();
    String::from_utf8_lossy(&o.stdout).contains("run")
}

/// draw a clock on the surface
fn draw(surf: &cairo::ImageSurface, t: usize) {
    let ctx = cairo::Context::new(&surf);
    ctx.set_source_rgb(0.6, 0.6, 0.6);
    ctx.paint();

    ctx.set_source_rgb(0.0, 0.0, 0.0);
    ctx.set_line_width(12.0);
    ctx.arc(XCENTER, YCENTER, 200.0, 0.0, TAU);
    ctx.stroke();

    let theta = (t as f64 / 24.0) * TAU;
    ctx.move_to(XCENTER, YCENTER);
    ctx.line_to(
        XCENTER + theta.sin() * 200.0,
        YCENTER + theta.cos() * 200.0,
    );
    ctx.stroke();
}

fn main() {
    let mut surf = cairo::ImageSurface::create(
        cairo::Format::Rgb24,
        XSIZE,
        YSIZE,
    ).unwrap();
    let mut t: usize = 0;

    while !check_slim() {
        t = (t + 1) % 24;
        draw(&surf, t);

        let mut f = std::fs::File::create("/dev/fb0").unwrap();
        f.write(&surf.get_data().unwrap()).unwrap();

        thread::sleep(time::Duration::from_millis(50));
    }
}
