<?
// включение плагина на /cab/setting/moduls/
// код для вывода
// $this->form_checkbox_left('<strong>FaceID</strong>','Модуль распознования по лицу','IS[plugins][faceid]',$GLOBALS['_SETTING']['plugins']['faceid'],'i_faceid') ;

$__functions['init'][]      ='_faceid_admin_vars' ;
$__functions['boot_site'][] ='_faceid_site_boot' ;


function _faceid_admin_vars() //
{
	$_SESSION['descr_clss'][3]['fields']['faceimg']=array('type'=>'int(1)','default'=>0) ;  // фото для faceimg
}

function _faceid_install_modul($DOT_root)
{
}

function _faceid_site_boot($options)
{
   ENGINE()->reg_ext('faceid','FaceID') ;
}



function FACEID() {if (is_object($GLOBALS['faceid_plugin'])) return($GLOBALS['faceid_plugin']);$GLOBALS['faceid_plugin']=new i_faceid();return($GLOBALS['faceid_plugin']);} ;

class i_faceid
{
 function __construct()
 {
 }

 function declare_menu($page)
 {
	$page->menu['/cab/setting/']['items']['/cab/faceid/settings/']=array('title'=>'FaceID') ;
 }

 function install()
 {  $descr_class[359]['name']='Журнал обработки фото faceid' ;
	$descr_class[359]['parent']=0 ;
	$descr_class[359]['fields']['personal_id']=array('type'=>'int(11)','default'=>0) ;
	$descr_class[359]['fields']['image_id']=array('type'=>'int(11)','default'=>0) ;
	$descr_class[359]['fields']['time_send']=array('type'=>'int(11)','default'=>0) ;
	$descr_class[359]['fields']['time_response']=array('type'=>'int(11)','default'=>0) ;
	$descr_class[359]['fields']['result']=array('type'=>'int(11)','default'=>0) ;
	$descr_class[359]['fields']['comment']=array('type'=>'varchar(255)') ;

	$descr_class[366]['name']='Метрики facecontrol' ;
	$descr_class[366]['parent']=0 ;
	$descr_class[366]['fields']['mo_id']=array('type'=>'int(11)','default'=>0) ;
	$descr_class[366]['fields']['ka']=array('type'=>'float(10,2)') ;
	$descr_class[366]['fields']['kd']=array('type'=>'float(10,2)') ;
	$descr_class[366]['fields']['avg_af_a']=array('type'=>'float(10,2)') ;
	$descr_class[366]['fields']['avg_af_d']=array('type'=>'float(10,2)') ;
	$descr_class[366]['fields']['avg_dr_a']=array('type'=>'float(10,2)') ;
	$descr_class[366]['fields']['avg_dr_d']=array('type'=>'float(10,2)') ;
	$descr_class[366]['fields']['a_frm_start']=array('type'=>'int(11)') ;
	$descr_class[366]['fields']['a_frm_end']=array('type'=>'int(11)') ;
	$descr_class[366]['fields']['d_frm_start']=array('type'=>'int(11)') ;
	$descr_class[366]['fields']['d_frm_end']=array('type'=>'int(11)') ;
	$descr_class[366]['fields']['count_frames']=array('type'=>'int(11)') ;
	$descr_class[366]['fields']['a_frm_count']=array('type'=>'int(11)') ;
	$descr_class[366]['fields']['d_frm_count']=array('type'=>'int(11)') ;

	$descr_class[3]['fields']['faceimg']=array('type'=>'int(11)','default'=>0) ;

    SETUP()->reg_class($descr_class) ;

	$id_sect=SETUP_add_section_to_site_setting('FaceID') ;
	SETUP_add_rec_to_site_setting($id_sect,"URL сервера FaceID",'','LS_faceid_server_url') ;
	SETUP_add_rec_to_site_setting($id_sect,"Отправлять на терминал запрос фото для FaceID",0,'LS_faceid_check_photo',array('el'=>'checkbox')) ;
	SETUP_add_rec_to_site_setting($id_sect,"Показывать в карточке сотрудника информацию по FaceID",0,'LS_faceid_view_info',array('el'=>'checkbox')) ;

	SETUP()->reg_event_lister('server_check_access_success','FACEID','on_event_server_check_access_success') ;         //
	SETUP()->reg_event_lister('examination_result_data_read','FACEID','on_event_examination_result_data_read') ;         //
	SETUP()->reg_event_lister('personal_change_photo','FACEID','on_event_personal_change_photo') ;         //

	$pattern=array() ;
	$pattern['table_title']				= 	'Лог обработки faceid' ;
	$pattern['use_clss']				= 	'359' ;
	$pattern['table_name']				= 	'log_faceid_upload_photo' ;
	create_table_by_pattern($pattern) ;

	$pattern=array() ;
	$pattern['table_title']				= 	'Метрики faceControl' ;
	$pattern['use_clss']				= 	'366' ;
	$pattern['table_name']				= 	'fc_metric' ;
	create_table_by_pattern($pattern) ;

	// добавить возможность регистрации во вложенных меню!!!
	//SETUP()->reg_menu_item('main','FaceID','/cab/faceid/') ;

	SETUP()->reg_ext('faceid','FaceID') ;
 }

 function check_faceid_photo($personal_id)
 { $result=false ;
   ob_start() ;
   $faceimg=execSQL_value('select faceimg from obj_site_personals_image where parent='.$personal_id.' order by indx limit 1',2) ;
   if ($faceimg) $result=true ;
   $text=ob_get_clean() ;
   LOG_JSON('mo_session')->reg('check_faceid_photo',$text) ;
   return($result) ;
 }

 // вызывется через
 //ENGINE()->on_event_by_pointer('server_check_access_success',$rec_member,$result) ;
 function on_event_server_check_access_success($session_info,&$result)
 {  // проверяем необходимость отправки флага faceid_photo на терминал
	if ($GLOBALS['LS_faceid_check_photo']) $result['args']['data']['faceid_photo']=($this->check_faceid_photo($session_info['personal_id']))? false:true ;
 }


 function on_event_examination_result_data_read(&$data,$rec_personal,$rec_mo)
 {   $mo_session_id=$rec_mo['pkey'] ;
	 // если сотрудник без фото - сохраняем фото в карточке персонала
     if ($data['args']['data']['faceid_photo'])
      { ob_start() ;

        include(_DIR_TO_ENGINE.'/admin/i_admin_system.php') ;
        //copy(_DIR_TO_ROOT.'/public/mo_photo/'.$mo_session_id.'_auth.jpg',_TEMP_DIR.$mo_session_id.'_auth.jpg')  ;
        $img_info=ESMO()->get_mo_img_dir_by_id($mo_session_id,'','faceid.jpg',array('check_directory'=>1,'no_check_exist_file'=>1)) ;
        if ($data['args']['data']['faceid_photo']) $this->save_send_photo($data['args']['data']['faceid_photo'],$img_info['relative']) ;
	    if (file_exists($img_info['dir']))
	      {
            // перед добавлением проверяем фото на сервера faceID
            $params['personal_id']=$rec_personal['pkey'] ;
            $this->on_event_personal_change_photo($params) ;

	          $result=PERSONAL()->personal_upload_image($rec_personal['pkey'],$img_info['dir'],array('fname'=>$mo_session_id.'_faceid.jpg','source_action'=>'Face ID')) ;

	    }

        $text=ob_get_clean() ;
        LOGS()->reg_log('Автодобавление faceid','Автоматическое добавление фото персонала с examination_result<br>'.$text.'<br>'.$mo_session_id.'_faceid.jpg',array('reffers'=>array($rec_personal['_reffer']))) ;
      }

     // считаем метрики faceconntrol и сохраняем его в базу
     if (_sizeof($data['args']['data']['face_control']['detector_data']))
     {  $result=$this->facecontrol_get_metric($data['args']['data']['face_control']['detector_data']);
	    FACEID()->save_fc_metric($mo_session_id,$result) ;
     }

     //LOGS()->reg_log('on_event_examination_result','',array('data'=>$params)) ;

 }

 function facecontrol_get_metric_from_file($mo_id)
 {   $result=array() ;
	 $fname=_DIR_TO_ROOT.'/logs/examination_result_'.$mo_id.'.html' ;
	    if (file_exists($fname))
	    {
	      $content=file_get_contents(_DIR_TO_ROOT.'/logs/examination_result_'.$mo_id.'.html') ;
	      $data=json_decode($content,true) ;


	      if ($data['args']['data']['face_control']['detector_data'])
	      { $result=$this->facecontrol_get_metric($data['args']['data']['face_control']['detector_data']) ;
	        $this->save_fc_metric($mo_id,$result) ;
	      }
	    }
	    return($result) ;
 }

 function facecontrol_get_metric($data)
 {    $result=array() ;
	  $fc_events=$data['events'] ;
	  $fc_detector_data=$data['frames'] ;
	  $result['count_frames']=_sizeof($fc_detector_data) ;

	  $result['a_frm_start']=0 ;
	  $result['a_frm_end']=0 ;
	  $result['d_frm_start']=0 ;
	  $result['d_frm_end']=0 ;

	 foreach($fc_detector_data as $i=>$rec) $fc_detector_data[$i]['af']=($rec['af'])? 1:0 ;

	  foreach($fc_events as $rec_event)
	   { if ($rec_event['n']=='alcotester_start')  $result['a_frm_start']=$rec_event['f'] ;
	     if ($rec_event['n']=='alcotester_breath') $result['a_frm_end']=$rec_event['f'] ;
	     if ($rec_event['n']=='tonometer_start')   $result['d_frm_start']=$rec_event['f'] ;
	     if ($rec_event['n']=='tonometer_done')    $result['d_frm_end']=$rec_event['f'] ;
	   }

	   $result['a_frm_count']=$result['a_frm_end']-$result['a_frm_start'] ;
	   $result['d_frm_count']=$result['d_frm_end']-$result['d_frm_start'] ;

	   // считаем коофиициенты
	   $cnt_af=0 ; $cnt_dr=0 ; $cnt=0 ;
	   if ($result['a_frm_start']<$result['a_frm_end']) for($i=$result['a_frm_start'];$i<=$result['a_frm_end'];$i++)
	   { $cnt_af+=$fc_detector_data[$i]['af'] ;
	     $cnt_dr+=$fc_detector_data[$i]['dr'] ;
	     $cnt++ ;
	   }
	   $result['ka']=round($cnt_af/$cnt_dr,5) ;
	   $result['avg_af_a']=round($cnt_af/$cnt,5) ;
	   $result['avg_dr_a']=round($cnt_dr/$cnt,5) ;

	    $cnt_af=0 ; $cnt_dr=0 ; $cnt=0  ;
	    if ($result['d_frm_start']<$result['d_frm_end']) for($i=$result['d_frm_start'];$i<=$result['d_frm_end'];$i++)
	    { $cnt_af+=$fc_detector_data[$i]['af'] ;
	      $cnt_dr+=$fc_detector_data[$i]['dr'] ;
	      $cnt++ ;
	    }
	    $result['kd']=round($cnt_af/$cnt_dr,5) ;
	    $result['avg_af_d']=round($cnt_af/$cnt,5) ;
	    $result['avg_dr_d']=round($cnt_dr/$cnt,5) ;

	    return($result) ;
 }

 function save_fc_metric($mo_id,$data)
 {  $data['mo_id']=$mo_id ;
    $id=execSQL_value('select pkey from fc_metric where mo_id='.$mo_id) ;
    if ($id) update_rec_in_table('fc_metric',$data,'pkey='.$mo_id) ;
    else     adding_rec_to_table('fc_metric',$data) ;

 }



 // обработка события загрузки нового фото сотруднику
 function on_event_personal_change_photo($params)
 { ob_start() ;
   $personal_id=$params['personal_id'] ;
   $source=$params['source'] ;
   $rec_personal=PERSONAL()->get_personal_by_id($personal_id) ;
   $rec_image=execSQL_van('select * from obj_site_personals_image where parent='.$personal_id.' and indx=1') ;
   //damp_array($rec_personal);
   //	 дает команду загрузить и обработать фото
   // POST /api/v1/photo
   // {"id": "123", "url": "https://..."}
//echo '_PATH_TO_SITE='._PATH_TO_SITE.'<br>' ;
   $data=array('id'=>$rec_personal['propusk'],'url'=>_PATH_TO_SITE.hide_server_dir($rec_personal['_image_dir'])) ;
   $url=$GLOBALS['LS_faceid_server_url'].'/api/v1/photo' ;
   $time_send=time() ;
   $result=IO()->doPut_v3($url,array('post'=>json_encode($data))) ;
   if ($result['status']>=200 and $result['status']<300)
   {
	   execSQL_update('update obj_site_personals_image set faceimg=1 where pkey='.$rec_image['pkey']) ;
	   PERSONAL()->log_personal_change($personal_id,0,0,'faceid','','Задано faceid, источник: '.$source) ;
	   $this->reg_log($rec_personal['pkey'],$rec_image['pkey'],$time_send,time(),1) ;
   }
   else
   {
	   execSQL_update('update obj_site_personals_image set faceimg=0 where pkey='.$rec_image['pkey']) ;
	   PERSONAL()->log_personal_change($personal_id,0,0,'faceid','','Сброшено faceid, источник: '.$source) ;
	   $this->reg_log($rec_personal['pkey'],$rec_image['pkey'],$time_send,time(),2) ;
   }
   damp_array($result,1,-1);
   $text=ob_get_clean() ;
   LOGS()->reg_log('on_event_personal_change_photo',$text) ;
 }

  function save_send_photo(&$data,$img_name,$options=array())
	{ $arr=explode(';',$data) ; // ([0] => data:image/png [1] => base64,iVBOR......==)
	  if (_sizeof($arr)==1) $img_string=base64_decode($data) ;  //echo $img_string ;
	  else
	  { $arr2=explode(',',$arr[1]) ; // ([0] => base64 [1] => iVBOR......==)
	    $img_string=base64_decode($arr2[1]) ;
	  }
	  $img_dir=$img_name ;
	  file_put_contents(_DIR_TO_ROOT.$img_dir,$img_string) ;

	  // коррекция изображения с аклотестера
	  if ($options['img_rotare']) ENGINE()->rotare_image(_DIR_TO_ROOT.$img_dir,_DIR_TO_ROOT.$img_dir,$options['img_rotare']) ;

	  $data="<img width=150 zoom src='"._MAIN_PROTOCOL._MAIN_DOMAIN.$img_dir."'>" ; // ддя сохранения в журнале
	}

	function reg_log($personal_id,$image_id,$time_send=0,$time_response=0,$result=0)
	{   if (!$time_send) $time_send=time() ;
		$data=array('clss'=>359,'personal_id'=>$personal_id,'image_id'=>$image_id,'time_send'=>$time_send,'time_response'=>$time_response,'result'=>$result) ;
        adding_rec_to_table('log_faceid_upload_photo',$data) ;
	}

	function update_log($last_log_id,$data)
	{
	    update_rec_in_table('log_faceid_upload_photo',$data,'pkey='.$last_log_id) ;
	}



}

?>
