//#[cfg(not(test))]
#![crate_type = "bin"]
#![crate_name = "krakusc"]
#![feature(non_ascii_idents)]

#[macro_use]
extern crate krakus_vm as krakus;
extern crate getopts;
use getopts::Options;


use krakus::*;

use std::env;
use std::mem;




fn print_usage(program: &str, opts: Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

#[cfg_attr(test, allow(dead_code))]
fn main()

{
    use std::io::prelude::*;
    use std::fs::File;

    let args: Vec<String> = env::args().collect();
    let program = args[0].clone();

    let mut opts = Options::new();
    //opts.optopt("o", "", "set output file name", "NAME");
    opts.optflag("h", "help", "print this help menu");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };
    if matches.opt_present("h") {
        print_usage(&program, opts);
        return;
    }
    //let output = matches.opt_str("o");
    let input = if !matches.free.is_empty() {
        matches.free[0].clone()
    } else {
        print_usage(&program, opts);
        return;
    };


    let mut f = match File::open(input)
    {
        Ok(v) => v,
        Err(_) => panic!("Guy, that is not a file I can open!"),
    };
    let mut s = String::new();
    f.read_to_string(&mut s).unwrap();

    let forward_euler_ff = |args: Vec<u64>| -> Vec<u64>
    {
        let mut args = args.clone();
        let a = uint_to_float!(args[0]);
        let b = uint_to_float!(args[1]);
        let mut t = uint_to_float!(args[2]);
        let mut y = uint_to_float!(args[3]);
        let dt = uint_to_float!(args[4]);

        let n = ((b-a)/dt) as u64;
        let mut i = 0;
        while i < n
        {
            y = y + dt*y;
            t += dt;
            i += 1;
        }

        println!("in ff:{:.20}",y);
        
        args[2] = float_to_uint!(t);
        args[3] = float_to_uint!(y);
        

        return args;
    };

    let mut kr_con = KrakusContext::new();

    
    kr_con.add_function("forward-euler".to_string(),5,&forward_euler_ff);

    kr_con.execute_assembly(s);

    krakus::sexpr::test_s_expr();
}