//! Sintexy — a lightweight, keyboard-driven terminal text editor.
//!
//! Entry point: parses CLI args, sets up the terminal, builds an [`Editor`],
//! then runs the event loop until the user quits.

#![deny(rust_2018_idioms)]

mod buffer;
mod editor;
mod highlight;
mod keybindings;
mod terminal;
mod ui;

use std::env;
use std::path::PathBuf;
use std::process::ExitCode;

use crossterm::event::{self, Event, KeyEventKind};

use crate::editor::Editor;
use crate::terminal::Terminal;
use crate::ui::Ui;

fn main() -> ExitCode {
    let args: Vec<String> = env::args().skip(1).collect();
    if let Some(first) = args.first() {
        if first == "--help" || first == "-h" {
            print_help();
            return ExitCode::SUCCESS;
        }
        if first == "--version" || first == "-V" {
            println!("sintexy {}", env!("CARGO_PKG_VERSION"));
            return ExitCode::SUCCESS;
        }
    }
    let path = args.into_iter().next().map(PathBuf::from);

    let term = match Terminal::new() {
        Ok(t) => t,
        Err(e) => {
            eprintln!("sintexy: failed to initialise terminal: {e}");
            return ExitCode::from(1);
        }
    };

    match run(path, term) {
        Ok(()) => ExitCode::SUCCESS,
        Err(e) => {
            eprintln!("sintexy: {e}");
            ExitCode::from(1)
        }
    }
}

fn print_help() {
    println!("Sintexy {} — a lightweight terminal text editor", env!("CARGO_PKG_VERSION"));
    println!();
    println!("USAGE:");
    println!("  sintexy [FILE]");
    println!();
    println!("In-editor: press F1 (or Ctrl-H) for the full key map.");
}

fn run(path: Option<PathBuf>, mut term: Terminal) -> std::io::Result<()> {
    let mut editor = Editor::new(path, term.width, term.height)?;
    let mut ui = Ui::new();

    ui.full_redraw(&mut editor, &mut term)?;

    while editor.running {
        match event::read()? {
            Event::Key(ev) => {
                if ev.kind != KeyEventKind::Press && ev.kind != KeyEventKind::Repeat {
                    continue;
                }
                editor.handle_key(ev)?;
                ui.redraw(&mut editor, &mut term)?;
            }
            Event::Resize(w, h) => {
                term.width = w;
                term.height = h;
                editor.on_resize(w, h);
                ui.full_redraw(&mut editor, &mut term)?;
            }
            _ => {}
        }
    }
    Ok(())
}
