<?php


/**
 * Логическо действие за подаване сигнал към изход на контролер
 *
 *
 * @category  bgerp
 * @package   sens2
 *
 * @author    Milen Georgiev <milen@download.bg>
 * @copyright 2006 - 2012 Experta OOD
 * @license   GPL 3
 *
 * @since     v 0.1
 */
class sens2_script_ActionSignal
{
    public $oldClassName = 'sens2_ScriptActionSignal';
    
    
    /**
     * Поддържани интерфейси
     */
    public $interfaces = 'sens2_script_ActionIntf';
    
    
    /**
     * Наименование на действието
     */
    public $title = 'Изходящ сигнал';
    
    
    /**
     * Подготвя форма с настройки на контролера, като добавя полета с $form->FLD(....)
     *
     * @param core_Form форма на която трябва да се поставят полетата с конфигурацията на контролера (IP, port, pass, ...)
     */
    public function prepareActionForm(&$form)
    {
        $form->FLD('output', 'varchar', 'caption=Изход,mandatory');
        $form->FLD('expr', 'text(rows=2,maxOptionsShowCount=20)', 'caption=Израз,width=100%,mandatory');
        $form->FLD('cond', 'text(rows=2,maxOptionsShowCount=20)', 'caption=Условие,width=100%');
        $form->FLD('onlyDifferent', 'enum(,no=Не,yes=Да)', 'caption=Условия за да се зададе изхода->Различна ст-ст,autohide');
        $form->FLD('minAttempts', 'int', 'caption=Условия за да се зададе изхода->Мин. брой опити,placeholder=1,autohide');
        $form->FLD('minInterval', 'time', 'caption=Условия за да се зададе изхода->Мин. период,autohide');

        $opt = self::getOutputOpts();
        
        if (!countR($opt)) {
            redirect(array('sens2_Controllers'), false, '|Моля, въведете поне един контролер с изход');
        }
        $form->setOptions('output', array('' => '') + $opt);

        $suggestions = sens2_script_Helper::getSuggestions($form->rec->scriptId);
        $form->setSuggestions('expr', $suggestions);
        $form->setSuggestions('cond', $suggestions);
    }
    
    
    /**
     * Връща масив с опциите за изходите
     */
    public static function getOutputOpts()
    {
        $cQuery = sens2_Controllers::getQuery();
        while ($cRec = $cQuery->fetch("#state = 'active'")) {
            $ports = sens2_Controllers::getActivePorts($cRec->id, 'outputs');
            foreach ($ports as $port => $pObj) {
                $opt[$pObj->title] = $pObj->title;
            }
        }
        
        return $opt;
    }
    
    
    /**
     * Проверява след  субмитване формата с настройки на контролера
     * Тук контролера може да зададе грешки и предупреждения, в случай на
     * некоректни конфигурационни данни използвайки $form->setError() и $form->setWarning()
     *
     * @param core_Form   форма с въведени данни от заявката (след $form->input)
     */
    public function checkActionForm($form)
    {
    }
    
    public function toVerbal($rec)
    {
        $opt = self::getOutputOpts();
        $output = sens2_Scripts::highliteExpr($rec->output, $rec->scriptId);
        if (!isset($opt[$rec->output])) {
            $output = "<span style='border-bottom:dashed 1px red;'>{$output}</span>";
        }
        
        $expr = sens2_Scripts::highliteExpr($rec->expr, $rec->scriptId);
        $cond = sens2_Scripts::highliteExpr($rec->cond, $rec->scriptId);
        
        $res = "{$output} = {$expr}";
        if ($rec->cond) {
            $res .= ", ако {$cond}";
        }
        
        return $res;
    }
    
    
    /**
     * Извършва действието, с параметрите, които са в $rec
     */
    public function run($rec)
    {
        // Ако има условие и то не е изпълнено - не правим нищо
        if (trim($rec->cond)) {
            $cond = sens2_Scripts::calcExpr($rec->cond, $rec->scriptId);
            if ($cond === sens2_Scripts::CALC_ERROR) {
                
                return 'stopped';
            }
            if (!$cond) {
                
                return 'closed';
            }
        }
        
        // Изчисляваме израза
        $value = sens2_Scripts::calcExpr($rec->expr, $rec->scriptId);
        if ($value === sens2_Scripts::CALC_ERROR) {
            
            return 'stopped';
        }

        // Проверяваме дали семафора позволява да се зададе изхода
        if(!sens2_Semaphores::check($rec->id, $value, $rec->onlyDifferent, $rec->minInterval, $rec->minAttempts)) {

            return 'closed';
        }

        // Задаваме го на изхода
        $res = sens2_Controllers::setOutput($rec->output, $value);
        
        if ($res === true) {
            
            sens2_script_Logs::add('setOut', $rec->scriptId, $rec->id, $rec->output, $value);

            return 'active';
        } else {
            sens2_script_Logs::add('setOut', $rec->scriptId, $rec->id, $rec->output, $value, $res);
        }
        
        return 'stopped';
    }
}
