#![feature(array_zip)]

use std::default::Default;
use std::error::Error;
use bevy::{prelude::*, sprite::MaterialMesh2dBundle};
use csv::{Position, Reader, ReaderBuilder};
use clap::Parser;

#[derive(Parser, Resource)] // requires `derive` feature
enum UICli {
    CSV(CSVArgs)
}

#[derive(clap::Args)]
struct CSVArgs {
    path: std::path::PathBuf,
}

struct Position2D(i32, i32);

fn main() -> Result<(), Box<dyn Error>> {
    let cli = UICli::parse();

    App::new()
        .insert_resource(cli)
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            window: WindowDescriptor {
                title: "DLA Static 2D Render".to_string(),
                width: 800.,
                height: 800.,
                ..default()
            },
            ..default()
        }))
        .add_startup_system(setup_ui)
        .add_startup_system(read_csv)
        .run();

    Ok(())
}

fn read_csv(
    cli: Res<UICli>,
    mut commands: Commands
) {
    let csv_path = match &cli.into_inner() {
        UICli::CSV(CSVArgs { path }) => path,
        _ => panic!("Ahh"),
    };

    let mut reader = ReaderBuilder::new()
        .has_headers(true)
        .from_path(csv_path)
        .expect("Failed to read csv");

    let headers = reader.headers()
        .expect("Failed to read headers");

    let x_column = headers.iter().position(|name| name.trim() == "x")
        .expect("Failed to find x column");

    let y_column = headers.iter().position(|name| name.trim() == "y")
        .expect("Failed to find x column");

    let positions = reader
        .records()
        .map(|record| {
            let record = record.expect("Failed to read position");
            let x: i32 = record[x_column].trim().parse::<i32>().expect("Failed to read x");
            let y: i32 = record[y_column].trim().parse::<i32>().expect("Failed to read y");

            Position2D(x, y)
        });

    for Position2D(x, y) in positions {
        let rect_size = 5.0;

        commands.spawn(SpriteBundle {
            sprite: Sprite {
                color: Color::rgb(0.25, 0.25, 0.75),
                custom_size: Some(Vec2::new(rect_size, rect_size)),
                ..default()
            },
            transform: Transform::from_translation(Vec3::new((x as f32) * rect_size, (y as f32) * rect_size, 0.)),
            ..default()
        });
    }
}

fn setup_ui(
    mut commands: Commands,
) {
    commands.spawn(Camera2dBundle::default());
}