use std::thread;
use std::time::Duration;

use gpio::{GpioOut, GpioIn, GpioValue};
use gpio::sysfs::{SysFsGpioOutput, SysFsGpioInput};

static mut STOP: bool = false;

fn main() {

    println!("Gpio Test ");
     
    set_button_event()

 }

fn set_button_event() -> ! {
    let mut gpio16 = SysFsGpioInput::open(16).expect("can not open 16 pin");
    println!("loop start");
    let mut clicked = false;
    let mut current_value: Option<GpioValue> = None;
    loop { 

        // gpio 값 가져오기 
        let rst = gpio16.read_value();
    
        match rst {
            // 오류 시 처리 
            Err(e) => println!("{}" ,e),
            // 오류가 아닌 경우 
            Ok(v) => {

                // 버튼을 계속 누르고 있으면 계속 호출 하게 된다.
                if current_value  == None {
                    current_value = Some(v);
                } else {
                    // 같은 경우에는 중지
                    if current_value.expect("current is none") ==  v {
                        thread::sleep(Duration::from_millis(100));
                        continue;
                    } else {
                        current_value = Some(v);
                    }

                }

                // High 인 경우에는 버튼을 누르면 High가 들어고 평소에는 LOW 가 들어옴
                if v == GpioValue::High {

                    // 클릭 안한 상태인 경우, 깜빡이기 시작
                    if !clicked {

                        println!("led blink start!! ");
                        clicked = true;

                        set_stop(false);

                        blink_led();

                    }else{

                        println!("led blink stop!! ");

                        clicked = false;
                        
                        set_stop(true);
                    }

                } 

            }
        };

        thread::sleep(Duration::from_millis(100));

    }
}

fn set_stop(flag: bool) {
    unsafe {
        STOP = flag
    }
}

fn blink_led() {
    let mut gpio20 = SysFsGpioOutput::open(20).expect("can not open 20 pin");
    let mut value = false;
    println!("thread start");
    let mut cnt = 0;

    thread::spawn( move || loop {

        unsafe{
            if STOP {

                gpio20.set_low().expect("can not set value to gpio 20");
                
                break;
            }
        }

         println!("gpio set : {}" , cnt);
         cnt = cnt +1;

         if value {
             // led 켜기
             gpio20.set_high().expect("can not set value to gpio 20");
         }else{
             // led 끄기
             gpio20.set_low().expect("can not set value to gpio 20");
         }

         // 1초 대기
         thread::sleep(Duration::from_millis(1000));

         value = !value;

     });
}

