
use libc::{c_uchar,c_char,c_long,c_float, size_t};
type SerialWrite = Option<unsafe extern "C" fn(data: *mut c_uchar, length: size_t) -> size_t>;
use lazy_static::lazy_static;
use std::{
    sync::{Arc, Mutex}, 
};
mod IS3_sensor;
mod IS11_sensor;
// 定义emun 不同光谱仪
#[derive(Copy, Clone)]
pub enum Senortype {
    IS11,
    IS1,
    IS2,
    OSIF,
    IS3
    
}

//全局变量 传感器类型 用lazy_static宏定义 原子变量
lazy_static! {
    static ref SENSORTYPE: Arc<Mutex<Senortype>> = Arc::new(Mutex::new(Senortype::IS3));
   
}


#[repr(C)]
#[derive(Copy, Clone)]
pub struct STRSensorInfo {
 pub   SensorName: [c_char; 100],
 pub  maxValue: c_long,
 pub   BandNum: c_long,
 pub   serialnumber: [c_char; 100],
 pub  a1: c_float,
 pub a2: c_float,
 pub  a3: c_float,
 pub  a4: c_float,
 pub  issensorinit: c_uchar,
}

impl Default for STRSensorInfo {
    fn default() -> Self {
        STRSensorInfo {
            SensorName: [0; 100],
            maxValue: 0,
            BandNum: 0,
            serialnumber: [0; 100],
            a1: 0.0,
            a2: 0.0,
            a3: 0.0,
            a4: 0.0,
            issensorinit: 0,
        }
    }
    
}

lazy_static! {
    static ref SENSOR_INFO: Arc<Mutex<STRSensorInfo>> = Arc::new(Mutex::new(STRSensorInfo::default()));
   
}

pub fn sensor_set_sensor_type(senortype:String)
{
    let mut data = SENSORTYPE.lock().unwrap();
    match senortype.as_str() {
        "IS11" => *data = Senortype::IS11,
        "IS1" => *data = Senortype::IS1,
        "IS2" => *data = Senortype::IS2,
        "OSIF" => *data = Senortype::OSIF,
        "IS3" => *data = Senortype::IS3,
        _ => *data = Senortype::IS11,
    }
}




pub fn abs1(input: i32) -> i32
{
    return 0;

}
pub fn test()
{

}
pub fn sensor_init() -> i32
{   
    let senortype = SENSORTYPE.lock().unwrap();
    match *senortype {
        Senortype::IS11 => {
            unsafe {
                IS11_sensor::Set_Serial_FUN(Some(IS11_sensor::serialsenddata), Some(IS11_sensor::serialreaddate));
                return IS11_sensor::IS11SensorInit();
            }

        },
        Senortype::IS3 => {
            unsafe {
                IS3_sensor::IS3Set_Serial_FUN(Some(IS3_sensor::serialsenddata), Some(IS3_sensor::serialreaddate));
                return IS3_sensor::IS3SensorInit();
            }

        },
        _ => {
            return 0;
        },

    }




}
pub  fn sensor_get_sensor_info() -> STRSensorInfo{
    let senortype = SENSORTYPE.lock().unwrap();
    let mut Sensorinfo= SENSOR_INFO.lock().unwrap();
    match *senortype {
        Senortype::IS11 => {
            unsafe {
                let info = IS11_sensor::Get_SensorInfo();
                *Sensorinfo = info.clone();
                return info;
            }

        },
        Senortype::IS3 => {
            unsafe {
                let info = IS3_sensor::IS3Get_SensorInfo();
                *Sensorinfo = info.clone();
                return info;
               
            }

        },
        _ => {
            return STRSensorInfo::default();
        },
    }
    
}
pub fn sensor_opt_sensor(percent:i32) -> i32{
    let senortype = SENSORTYPE.lock().unwrap();
    match *senortype {
        Senortype::IS11 => {
            unsafe {
                return IS11_sensor::IS11OptSnenser(percent);
            }

        },
        Senortype::IS3 => {
            unsafe {
                return IS3_sensor::IS3OptSnenser(percent);
            }

        },
        _ => {
            return 0;
        },
    }
  
}
pub fn sensor_get_data_base(outdata: *mut u16, shuttertime: i32) -> i32
{
    let senortype = SENSORTYPE.lock().unwrap();
    match *senortype {
        Senortype::IS11 => {
            unsafe {
                return IS11_sensor::IS11GetData(outdata, shuttertime);
            }

        },
        Senortype::IS3 => {
            unsafe {
                return IS3_sensor::IS3GetData(outdata, shuttertime);
            }

        },

        _ => {
            return 0;
        },
    }
}











pub fn sensor_get_data(shuttertime: i32) -> Vec<u16> {
    let sensor_info= SENSOR_INFO.lock().unwrap();
    let bandSum = sensor_info.BandNum as usize;
    let mut outdata: Vec<u16> = vec![0; bandSum];

    unsafe {

        let len = sensor_get_data_base(outdata.as_mut_ptr(), shuttertime);
       outdata.truncate(len as usize);
        


    }
   // polynomial_smooth_u16( outdata ,7)
    outdata
}

pub fn set_sensor_weave_length_coeff(a: Vec<f64>) -> i32 {
    let senortype = SENSORTYPE.lock().unwrap();
    match *senortype {
        Senortype::IS11 => {
            
            0

        },
        Senortype::IS3 => {
            IS3_sensor::is3_set_weave_length_coeff(a);
            0
          

        },
        _ => {
            return 0;
        },
    }
}

pub fn sensor_set_shutter_open(isopen:i32) {
    let senortype = SENSORTYPE.lock().unwrap();
    match *senortype {
        Senortype::IS11 => {
            unsafe {
               
            }

        },
        Senortype::IS3 => {
            unsafe {
                IS3_sensor::IS3SetShutterOpen(isopen);
                
            }

        },
        _ => {
            
        },
    }
}