use super::spectralbase;
use super::spectralbase::*;
use super::super::mydefine::*;
use lazy_static::lazy_static;
use chrono::{self, Datelike, Timelike};
use std::thread;
use std::fs::File;
use std::mem;
use std::path::Path;
use std::io::Read;
#[derive(PartialEq)]
enum WorkStat {
    IDLE,
    WOKING,
    STOP,
    OPTING,
    
}


use std::vec;
use std::{
    sync::{Arc, Mutex}, 
};
struct is11_dev_data {
    sensor_info: super::spectralbase::STRSensorInfo,
    shuttertime: i32,
    stat: WorkStat,
    percent: i32,
    workname: String,
    hasdark: bool,
    hasflat: bool,
    removedark: bool,
    computeflat: bool,
    average_number_data: u32,
    average_number_dark: u32,
    average_number_flat: u32,
    has_CalidataUP: bool,
    
}

lazy_static! {
    static ref DEV_STAT: Arc<Mutex<is11_dev_data>> = Arc::new(Mutex::new(is11_dev_data {
        sensor_info: super::spectralbase::STRSensorInfo::default(),
        shuttertime: 0,
        stat: WorkStat::IDLE,
        percent: 0,
        workname: "noting".to_string(),
        hasdark: false,
        hasflat: false,
        removedark: false,
        computeflat: true,
        average_number_data: 1,
        average_number_dark: 10,
        average_number_flat: 10,
        has_CalidataUP: false,

    }));
}


// lazy_static! {
//     static ref DATA: Arc<Mutex<Vec<u16>>> = Arc::new(Mutex::new(Vec::new()));
// }

lazy_static! {
    static ref DATA_IS11: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
    static ref DARK_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
    static ref FLAT_DATA: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
    static ref CALIDATAUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
    static ref CALIOFFSETUP: Arc<Mutex<IS11DataStruct>> = Arc::new(Mutex::new(IS11DataStruct::default()));
}



pub fn is11_get_sensor_info() -> STRSensorInfo {
    return super::spectralbase::sensor_get_sensor_info();
}
pub fn is11_init(){
    super::spectralbase::sensor_init();
    let mut dev_stat=DEV_STAT.lock().unwrap();
   let sensorinfo= is11_get_sensor_info();
    dev_stat.sensor_info=sensorinfo;
    

}


pub fn get_shuttertime() -> i32 {
    let dev_stat=DEV_STAT.lock().unwrap();
    return dev_stat.shuttertime;
}


pub fn opt_sensor(percent: i32) -> i32 {

    

    let mut dev_stat=DEV_STAT.lock().unwrap();
    if dev_stat.stat != WorkStat::IDLE {
        return -1;
    }

    dev_stat.stat=WorkStat::OPTING;
    dev_stat.percent=0;
    dev_stat.workname="opting".to_string();
    drop(dev_stat); //释放锁
    thread::spawn(move || {

      let shuttertime=  super::spectralbase::sensor_opt_sensor(90); //多线程设置曝光时间
        let mut dev_statnow=DEV_STAT.lock().unwrap();
        dev_statnow.stat=WorkStat::IDLE;
        dev_statnow.shuttertime=shuttertime; 
        dev_statnow.workname="finish".to_string();
        dev_statnow.percent=100;
        dev_statnow.hasdark=false;
        dev_statnow.hasflat=false;
       }
    );

    
    return 0;



}

pub fn get_now_stat()->(String,String,i32){


    let dev_stat=DEV_STAT.lock().unwrap();
    match dev_stat.stat {
        WorkStat::IDLE => {
            return ("finish".to_string(),dev_stat.workname.clone(),100);
        },
        WorkStat::WOKING => {
            return ("working".to_string(),dev_stat.workname.clone(),dev_stat.percent);
        },
        WorkStat::STOP => {
            return ("finish".to_string(),dev_stat.workname.clone(),dev_stat.percent);
        },
        WorkStat::OPTING => {
            return ("opting".to_string(),dev_stat.workname.clone(),dev_stat.percent);
        },
        
    }


}

pub fn collect(shuttertime:u32,removedark:bool,computeflat:bool){
    let mut dev_stat=DEV_STAT.lock().unwrap();
    if dev_stat.stat != WorkStat::IDLE {
        return ;
    }
   
    let averagenumber=dev_stat.average_number_data;
    dev_stat.stat=WorkStat::WOKING;
    dev_stat.percent=0;

    dev_stat.workname="采集中".to_string();
    let bandsunm=dev_stat.sensor_info.BandNum  as usize;
    drop(dev_stat); //释放锁
    thread::spawn(move || {
        

        let mut datasum:Vec<u32>=vec![0;bandsunm];
        for _i in 0..averagenumber {
            let data=super::spectralbase::sensor_get_data(shuttertime as i32);
            for i in 0..bandsunm {
                datasum[i]=datasum[i]+data[i] as u32;
            }
            let mut dev_stat=DEV_STAT.lock().unwrap();
            let info=format!("采集中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
            dev_stat.workname=info;
            dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
            drop(dev_stat); //释放锁


        }
        let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();
        let mut dev_stat=DEV_STAT.lock().unwrap();
        let _lenth=data.len();
        println!("data len={}",_lenth);
        let mut tempis11data=IS11DataStruct::default();
       for i in 0.._lenth {
            tempis11data.data[i]=data[i] as f32;
        }
        // 获取当前时间
        let now = chrono::Local::now();
        tempis11data.year=(now.year()-2000) as u8;
        tempis11data.month=now.month() as u8;
        tempis11data.day=now.day() as u8;
        tempis11data.hour=now.hour() as u8;
        tempis11data.minute=now.minute() as u8;
        tempis11data.second=now.second() as u8;
        tempis11data.shutter_time=shuttertime;
        tempis11data.index=0;
        tempis11data.datatype=0;

        let mut data1=DATA_IS11.lock().unwrap();
        let darkdata=DARK_DATA.lock().unwrap();
        *data1=tempis11data;
        if removedark && dev_stat.hasdark {
           
            for i in 0.._lenth {
                data1.data[i]=data1.data[i]-darkdata.data[i];

            }          
        }

        if computeflat && dev_stat.hasflat {
            let flatdata=FLAT_DATA.lock().unwrap();
            for i in 0.._lenth {

                let temp=flatdata.data[i]-darkdata.data[i];
                if temp<=0.0 {
                    data1.data[i]=10000.0;
                }else{
                    data1.data[i]=data1.data[i]/temp*10000.0;
                }
                if data1.data[i]<0.0 {
                    data1.data[i]=0.0;
                    
                }
                if data1.data[i]>15000.0 {
                    data1.data[i]=15000.0;
                }

               // data1.data[i]=data1.data[i]/(flatdata.data[i]-darkdata.data[i])*10000.0;
            }          
        }


        dev_stat.stat=WorkStat::IDLE;
        dev_stat.percent=100;
        dev_stat.workname="finish".to_string();
    });




  
}

pub fn collcect_dark(shuttertime:u32)
{
    let mut dev_stat=DEV_STAT.lock().unwrap();
    if dev_stat.stat != WorkStat::IDLE {
        return ;
    }
    let averagenumber=dev_stat.average_number_dark;
    dev_stat.stat=WorkStat::WOKING;
    dev_stat.percent=0;
    dev_stat.workname="采集Dark中".to_string();
    let bandsunm=dev_stat.sensor_info.BandNum  as usize;
    drop(dev_stat); //释放锁
    thread::spawn(move || {
        let mut datasum:Vec<u32>=vec![0;bandsunm];
        sensor_set_shutter_open(0);
        for _i in 0..averagenumber {
       
            let data=super::spectralbase::sensor_get_data(shuttertime as i32);
            for i in 0..bandsunm {
                datasum[i]=datasum[i]+data[i] as u32;
            }
            let mut dev_stat=DEV_STAT.lock().unwrap();
            let info=format!("采集Dark中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
            dev_stat.workname=info;
            dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
            drop(dev_stat); //释放锁
        }
        sensor_set_shutter_open(1);
        let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();


        let mut dev_stat=DEV_STAT.lock().unwrap();
        let _lenth=data.len();
        println!("data len={}",_lenth);
        let mut tempis11data=IS11DataStruct::default();
       for i in 0.._lenth {
            tempis11data.data[i]=data[i] as f32;
        }
        //获取当前时间
        let now = chrono::Local::now();
        tempis11data.year=(now.year()-2000) as u8;
        tempis11data.month=now.month() as u8;
        tempis11data.day=now.day() as u8;
        tempis11data.hour=now.hour() as u8;
        tempis11data.minute=now.minute() as u8;
        tempis11data.second=now.second() as u8;
        tempis11data.shutter_time=shuttertime;
        tempis11data.index=0;
        tempis11data.datatype=0;

        let mut data1=DARK_DATA.lock().unwrap();
        *data1=tempis11data;
        dev_stat.stat=WorkStat::IDLE;
        dev_stat.percent=100;
        dev_stat.workname="finish".to_string();
        dev_stat.hasdark=true;
    });


}

pub fn collcect_flat(shuttertime:u32)
{
    let mut dev_stat=DEV_STAT.lock().unwrap();
    if dev_stat.stat != WorkStat::IDLE {
        return ;
    }
    let averagenumber=dev_stat.average_number_flat;
    dev_stat.stat=WorkStat::WOKING;
    dev_stat.percent=0;
    dev_stat.workname="采集中".to_string();
    let bandsunm=dev_stat.sensor_info.BandNum as usize;
    drop(dev_stat); //释放锁
    thread::spawn(move || {
        let mut datasum:Vec<u32>=vec![0;bandsunm];
        for _i in 0..averagenumber {
            let data=super::spectralbase::sensor_get_data(shuttertime as i32);
            for i in 0..bandsunm {
                datasum[i]=datasum[i]+data[i] as u32;
            }
            let mut dev_stat=DEV_STAT.lock().unwrap();
            let info=format!("采集白板中,{}%",_i as f32/averagenumber as f32*100 as f32*0.9);
            dev_stat.workname=info;
            dev_stat.percent=((_i+1) as f32/averagenumber as f32*100 as f32*0.9) as i32;
            drop(dev_stat); //释放锁
        }
        let data=datasum.iter().map(|x| *x as f32/averagenumber as f32).collect::<Vec<f32>>();

        let mut dev_stat=DEV_STAT.lock().unwrap();
        let _lenth=data.len();
        println!("data len={}",_lenth);
        let mut tempis11data=IS11DataStruct::default();
       for i in 0.._lenth {
            tempis11data.data[i]=data[i] as f32;
        }
        //获取当前时间
        let now = chrono::Local::now();
        tempis11data.year=(now.year()-2000) as u8;
        tempis11data.month=now.month() as u8;
        tempis11data.day=now.day() as u8;
        tempis11data.hour=now.hour() as u8;
        tempis11data.minute=now.minute() as u8;
        tempis11data.second=now.second() as u8;
        tempis11data.shutter_time=shuttertime;
        tempis11data.index=0;
        tempis11data.datatype=0;

        let mut data1=FLAT_DATA.lock().unwrap();
        *data1=tempis11data;
        dev_stat.stat=WorkStat::IDLE;
        dev_stat.percent=100;
        dev_stat.workname="finish".to_string();
        dev_stat.hasflat=true;
    });
}


pub fn get_data()->IS11DataStruct{
    let data1=DATA_IS11.lock().unwrap();
    return data1.clone();
}
pub fn get_data_flat()->IS11DataStruct{
    let data1=FLAT_DATA.lock().unwrap();
    return data1.clone();
}
pub fn get_data_dark()->IS11DataStruct{
    let data1=DARK_DATA.lock().unwrap();
    return data1.clone();
}
pub fn get_is_computeref()->bool{
    let dev_stat=DEV_STAT.lock().unwrap();
    return dev_stat.computeflat;
}

pub fn set_shutter_time(shuttertime:u32){
    let mut dev_stat=DEV_STAT.lock().unwrap();
    dev_stat.shuttertime=shuttertime as i32;
    dev_stat.hasdark=false;
    dev_stat.hasflat=false;
}


pub fn set_average_number(arverage_number_data:u32,arverage_number_dark:u32,arverage_number_flat:u32){
    let mut dev_stat=DEV_STAT.lock().unwrap();
    dev_stat.average_number_data=arverage_number_data;
    dev_stat.average_number_dark=arverage_number_dark;
    dev_stat.average_number_flat=arverage_number_flat;
}




pub fn calibrate_file(orgdata: &IS11DataStruct) -> IS11DataStruct {
    let dev_stat=DEV_STAT.lock().unwrap();
    if !dev_stat.has_CalidataUP {
        return orgdata.clone();
    }
    drop(dev_stat);
    ;
    let calidata=CALIDATAUP.lock().unwrap();
    let offsetdata=CALIOFFSETUP.lock().unwrap();

    let mut data = IS11DataStruct::default();
    let collect_gaindb = orgdata.temprature[0];
    let collect_shutter = orgdata.shutter_time;
    let cali_gaindb = calidata.temprature[0];
    let cali_shutter = calidata.shutter_time;
    //db 转系数
    let collect_gain = 10.0_f32.powf(collect_gaindb / 20.0);
    let cali_gain = 10.0_f32.powf(cali_gaindb / 20.0);
    //计算增益
    let Scale_gain = cali_gain / collect_gain;
    let Scale_shutter = cali_shutter as f32/ collect_shutter as f32;
    let SCale = Scale_gain * Scale_shutter as f32;
    let len = orgdata.data.len();
    for i in 0..len {
        data.data[i] = orgdata.data[i] * SCale * calidata.data[i]+offsetdata.data[i];
    }
    return data;
}


pub fn  load_all_calibrate_file(filepath: String) -> String {
    let file_path = Path::new(&filepath);
    if file_path.exists() {
        let mut up_gain_data=CALIDATAUP.lock().unwrap();
        *up_gain_data=load_calibrate_file(file_path.to_str().unwrap().to_string()).unwrap();
        let mut dev_stat=DEV_STAT.lock().unwrap();
        dev_stat.has_CalidataUP=true;
        return "ok".to_string();
    } else {
        println!("文件不存在: {:?}", file_path);
        return "文件不存在".to_string();
        
    }

}







fn load_calibrate_file(filepath: String) -> Result<IS11DataStruct, String> {
    let mut data = IS11DataStruct::default();
    let mut buffer = vec![0u8; mem::size_of::<IS11DataStruct>()];
    let mut file = File::open(filepath).unwrap();
    file.read_exact(&mut buffer).unwrap();
    unsafe {
        let ptr = &mut data as *mut IS11DataStruct as *mut u8;
        std::ptr::copy_nonoverlapping(buffer.as_ptr(), ptr, mem::size_of::<IS11DataStruct>());
    }
    return Ok(data);
}

pub fn set_weave_coeff(specnumber: i32, a0: f64, a1: f64, a2: f64, a3: f64) -> String {
   let vecdata=vec![a0,a1,a2,a3];
   spectralbase::set_sensor_weave_length_coeff(vecdata);
    "ok".to_string()
}

