<?php  if (!defined('BASEPATH')) { exit('No direct script access allowed'); }
/**
 * CodeIgniter helper
 *
 * @category CodeIgniter
 * @license /_licenses/untermStrich/agb_normal.pdf
 * @author Christian Koller
 * @copyright 2009 untermStrich
 * @package helpers
 * @version $Id$
*/

/**
 * The class holds global output informations for DB info
 */
interface Report_output_fordb
{
    /**
     * Set DB id
     *
     * @param   integer $db_id          ID in the DB
     * @param   integer $company_id     Company ID
     * @return  void
     */
    public function set_for_db($db_id, $company_id);
    
    /**
     * Get DB ID
     *
     * @return  integer
     */
    public function get_db_id();
    
    /**
     * Get company ID
     *
     * @return  integer
     */
    public function get_company_id();
    
    /**
     * Is from a preset (XML) output template
     *
     * @return  boolean
     */
    public function is_preset();
}

/**
 * Report result settings
 */
class Report_result
{
    protected $action_object = null;
    protected $can_edit = null;
    protected $outputtypes = array();
    
    /**
     * Constructor
     *
     * @param   string  $action         Optional Javascript action object to call
     * @param   boolean $can_edit       Optional Can edit
     */
    public function __construct($action=null, $can_edit=false)
    {
        $this->action_object = (string)$action;
        
        $this->can_edit = ($can_edit==='true') ? true : false;
    }
    
    /**
     * Add an outputtype
     *
     * @param   object  $outputtype     Report_result_outputtype
     * @return  void
     */
    public function add_outputtype(Report_result_outputtype $outputtype)
    {
        array_push($this->outputtypes, $outputtype);
    }
    
    /**
     * Get outputtypes
     * 
     * Restricts right
     *
     * @return  array 
     */
    public function get_outputtypes()
    {
        $reply = array();
        foreach ($this->outputtypes as $type) {
            if ($type->has_right() && !$type->get_inactive()) {
                array_push($reply, $type);
            }
        }
        
        return $reply;
    }
    
    /**
     * Get all outputtypes
     *
     * @return  array 
     */
    public function get_all_outputtypes()
    {
        return $this->outputtypes;
    }
    
    /**
     * Get Javascript action to call
     *
     * @return  string 
     */
    public function get_action()
    {
        if (!empty($this->action_object)) {

            $CI = CI_Controller::get_instance();
            $CI->load->library('user_agent');
            $refferer = $CI->agent->referrer();

            if (US_MAJOR_VERSION>=15 && !empty($refferer) && stripos($refferer, '/q/')!==false) { //@todo: Change this to real fallback for x4 mode
                return 'qplan.'.$this->action_object.'.load_report';
            } else {
                return $this->action_object.'.load_report';
            }
        } else {
            return 'evaluation.load';
        }
    }
    
    /**
     * Get Javascript action to call to view the main report interface
     *
     * @return  string 
     */
    public function get_view()
    {
        if (!empty($this->action_object)) {
            return $this->action_object.'.view_report';
        } else {
            return 'evaluation.view';
        }
    }

    /**
     * Get can edit?
     *
     * @return  boolean
     */
    public function get_can_edit()
    {
        return $this->can_edit;
    }
    
    /**
     * Sort outputtypes using sort info array
     * 
     * @param   array   $sort_infos     Sort info array
     * @return  void
     */
    public function sort_using_sort_infos(array $sort_infos)
    {
        $tmp_outputtypes = $this->outputtypes;
        $this->outputtypes = array();
        
        foreach ($sort_infos as $sort_info) {
            $tmp_outputtypes_curr = array(); //Uset to save the not sorted in
            foreach ($tmp_outputtypes as $outputtype) {
                if ($outputtype->get_output_template()==$sort_info->output_template_id) {
                    $outputtype->set_inactive($sort_info->inactive);
                    array_push($this->outputtypes, $outputtype);
                } else {
                    array_push($tmp_outputtypes_curr, $outputtype);
                }
            }
            $tmp_outputtypes = $tmp_outputtypes_curr;
        }
        
        foreach ($tmp_outputtypes as $outputtype) {
            array_push($this->outputtypes, $outputtype);
        }
    }
}

/**
 * Result output type
 */
class Report_result_outputtype implements Serializable, Report_output_fordb
{
    const T_TAB = 'tab';
    const T_TABTREE = 'tabtree';
    const T_SMARTY = 'smarty';
    const T_SMARTYTREE = 'smartytree';
    
    protected $type = null;
    protected $title = null;
    protected $output_template = null;
    protected $minright = null;
    protected $rightmodule = null;
    
    protected $db_id = false; //Not serialized
    protected $company_id = null; //Not serialized
    protected $inactive = false; //Not serialized

    /**
     * On serialize
     * 
     * @return  string 
     */
    public function serialize()
    {
        return serialize($this->__serialize());
    }
    
    /**
     * Serialize all vars_to_serialize
     * 
     * @return array
     */
    public function __serialize(): array
    {
        return array(
            'type'              => $this->type,
            'title'             => $this->title,
            'output_template'   => $this->output_template,
            'minright'          => $this->minright,
            'rightmodule'       => $this->rightmodule,
        );
    }

    /**
     * On unserialize
     *
     * @param   string  $serialized     Serialized string
     * @return  void
     */
    public function unserialize($serialized)
    {
        $this->__unserialize(@unserialize($serialized));
    }
    
    /**
     * Unserialize all vars_to_serialize
     * 
     * @param   array   $data   Data array
     * @return  void
     */
    public function __unserialize(array $data): void
    {
        log_error_unserialize();
        $this->type             = $data['type'];
        $this->title            = $data['title'];
        $this->output_template  = $data['output_template'];
        $this->minright         = $data['minright'];
        $this->rightmodule      = $data['rightmodule'];
    }
    
    /**
     * Constructor
     *
     * @param   string  $title              Title
     * @param   string  $type               Result type
     * @param   string  $output_template    Output template to use
     * @param   string  $minright           XML min right
     * @param   string  $rightmodule        Modul to check right against
     */
    public function __construct($title, $type, $output_template, $minright, $rightmodule=null)
    {
        if (empty($title)) {
            throw new Exception('Title is missing');
        }
        if (empty($type)) {
            throw new Exception('Type is missing');
        }
        if (empty($output_template)) {
            throw new Exception('Output template is missing');
        }
        
        $this->title = (string)$title;
        $this->type = (string)$type;
        $this->output_template = (string)$output_template;
        
        if (!empty($minright)) {
            $this->minright = $minright;
        } else {
            $this->minright = 'admin';
        }
        
        if (!empty($rightmodule)) {
            $this->rightmodule = $rightmodule;
        } else {
            $this->rightmodule = Login_model::R_PROJECTEVALUATION;
        }
    }
    
    /**
     * Create a Report_result_outputtype using a language key (trans)
     *
     * @param   string  $trans              Translation key
     * @param   string  $type               Result type
     * @param   string  $output_template    Output template to use
     * @param   string  $minright           Optional XML min right
     * @param   string  $accesskey          Optional Access key (module name)
     * @return  Report_result_outputtype 
     */
    public static function init_from_xml($trans, $type, $output_template, $minright=null, $accesskey=null)
    {
        $CI = CI_Controller::get_instance();
        
        $title = $CI->lang->line('reporting_res_x_'.$trans);
        if (empty($trans)) {
            $title = str_replace('_', ' ', $trans);
        }
        
        if (!empty($accesskey)) {
            $rightmodule = Login_model::get_module_id_for_accesskey($accesskey);
        } else {
            $rightmodule = null;
        }
        
        return new Report_result_outputtype($title, $type, $output_template, $minright, $rightmodule);
    }
    
    /**
     * Get result type
     *
     * @return  string 
     */
    public function get_type()
    {
        return $this->type;
    }
    
    /**
     * Get title
     *
     * @return  string 
     */
    public function get_title()
    {
        return $this->title;
    }
    
    /**
     * Get title for edit
     *
     * @return  string 
     */
    public function get_title_edit()
    {
        if ($this->is_preset()) {
            $now = new UsDate('now');
            return $this->title.' - '.$now->us_date();
        } else {
            return $this->title;
        }
    }

    /**
     * Get output template
     *
     * @return  string 
     */
    public function get_output_template()
    {
        return $this->output_template;
    }

    /**
     * Get output template for edit
     *
     * @return  string 
     */
    public function get_output_template_edit()
    {
        if ($this->is_preset()) {
            return us_uniqid($this->output_template.'__', true);
        } else {
            return $this->output_template;
        }
    }
    
    /**
     * Get buttons
     *
     * @param   string  $report_id      Optional Unique id (name) of the report
     * @return  array   Array with SimpleXMLElement
     */
    public function get_buttons($report_id=false)
    {
        $types = Report_config::get_types_settings();
        
        $buttons_xml = $types->xpath('type[@name="'.$this->type.'"]/btn');
        if (count($buttons_xml)<=0) {
            basic_error('The report result has an invalid type "'.$this->type.'". No buttons defined.', null, __CLASS__.'::'.__FUNCTION__);
        }
        
        $reply = array();
        foreach ($buttons_xml as $button) {
            $btn_view = (string)$button['view'];
            $info = new Report_result_button($btn_view, (string)$button['icon'], (string)$button['target'], (string)$button['trans']);
            
            if ($report_id!=='addresses_shortlist' && $btn_view==='tab-avcsv') {
                continue;
            }
            if ($report_id!=='b_timekeyword' && $btn_view==='tab-usxml') {
                continue;
            }
            array_push($reply, $info);
        }
        
        return $reply;
    }
    
    /**
     * Min XML right
     * 
     * @return  string
     */
    public function get_minright()
    {
        return $this->minright;
    }
    
    /**
     * Modul to check right against
     *
     * @return  integer
     */
    public function get_rightmodule()
    {
        return $this->rightmodule;
    }
        
    /**
     * Does the user have to right to gain access
     *
     * @return  boolean
     */
    public function has_right()
    {
        $right = CI_Controller::get_instance()->login->get_full_right($this->rightmodule);
        return Login_model::check_right_xml($right, $this->minright);
    }
    
    /**
     * Set DB id
     *
     * @param   integer $db_id          ID in the DB
     * @param   integer $company_id     Company ID
     * @return  void
     */
    public function set_for_db($db_id, $company_id)
    {
        $this->db_id = $db_id;
        $this->company_id = $company_id;
    }
    
    /**
     * Get DB ID
     *
     * @return  integer
     */
    public function get_db_id()
    {
        if ($this->db_id===false) {
            basic_error('Cannot read DB ID from result type - DB settings not set.', null, __CLASS__.'::'.__FUNCTION__);
        }
        return $this->db_id;
    }
    
    /**
     * Get company ID
     *
     * @return  integer
     */
    public function get_company_id()
    {
        if ($this->db_id===false) {
            basic_error('Cannot read Company ID from result type - DB settings not set.', null, __CLASS__.'::'.__FUNCTION__);
        }
        return $this->company_id;
    }

    /**
     * Is from a preset (XML) output template
     *
     * @return  boolean
     */
    public function is_preset()
    {
        if ($this->db_id!==false) {
            return false;
        } else {
            return true;
        }
    }
    
    /**
     * Get inactive state
     * 
     * @return  boolean
     */
    public function get_inactive()
    {
        return $this->inactive;
    }

    /**
     * Set inactive state
     * 
     * @param   boolean     $inactive   Inactive state
     * @return  void
     */
    public function set_inactive($inactive)
    {
        $this->inactive = $inactive;
    }
    
}

/**
 * A result button
 */
class Report_result_button
{
    protected $view = null;
    protected $icon = null;
    protected $target = null;    
    protected $title = null;    
    
    /**
     * Constructor
     *
     * @param   string  $view   View
     * @param   string  $icon   Icon
     * @param   string  $target Target
     * @param   string  $trans  Optional Translation key
     */
    public function __construct($view, $icon, $target, $trans=null)
    {
        if (empty($view)) {
            throw new Exception('View is missing');
        }
        if (empty($icon)) {
            throw new Exception('Icon is missing');
        }
        if (empty($target)) {
            throw new Exception('Target is missing');
        }
        
        $CI = CI_Controller::get_instance();
        
        $this->view = (string)$view;
        $this->icon = (string)$icon;
        $this->target = ($target=='newwin') ? 'newwin' : 'object';
        if (!empty($trans)) {
            $this->title = $CI->lang->line('reporting_res_x_'.$trans);
        } else {
            $this->title = $CI->lang->line('reporting_res_'.$this->view);
        }
        if (empty($this->title)) {
            $this->title = str_replace('_', ' ', $this->view);
        }
   }
    
    /**
     * Get result view
     *
     * @return  string 
     */
    public function get_view()
    {
        return $this->view;
    }
    
    /**
     * Get result icon
     *
     * @return  string 
     */
    public function get_icon()
    {
        return $this->icon;
    }
    
    /**
     * Get result target
     *
     * @return  string 
     */
    public function get_target()
    {
        return $this->target;
    }
    
    /**
     * Get title
     *
     * @return  string 
     */
    public function get_title()
    {
        return $this->title;
    }

}
