<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

// Load simple types
require_once __DIR__ . '/rtgrid_simple_types.php';

/**
 * Description of rtgrid_edit_model
 *
 * @author Igor Ratsun
 */
class rtgrid_edit_model extends CI_Model implements SplSubject
{

    /**
     * Current action
     * @var string
     */
    public $current_action = '';

    /**
     * Callback of action
     * @var mixed
     */
    public $current_action_return;

    /**
     * Primery key
     * @var string
     */
    public $_primery_key;

    /**
     * Primery key value
     * @var int
     */
    public $_primery_key_value = 0;

    /**
     * Data from $_POST
     * @var array
     */
    public $post = array();

    /**
     * Url to redirect after render method
     * @var string
     */
    public $redirect_url = '';
    protected $_table;
    protected $_unique;
    protected $_fields;
    protected $_fields_array = array();
    protected $_display_as;
    protected $_callback_field;
    protected $_callback_before_edit = NULL;
    protected $_callback_after_edit = NULL;
    protected $_where = array();
    protected $_where_in = array();
    protected $_join = array();
    protected $_actions = array();
    protected $observers = array();
    protected $_multilang = array();
    protected $_tabs = array();
    protected $_readonly = array();
    protected $_hidden = array();
    protected $_required_fields = array();
    protected $_unique_fields = array();
    protected $_multifield = array();
    protected $tooltip = array();
    protected $xss_clean = true;

    public function __construct()
    {
        // Load default field callbacks
        $this->load->model('rtgrid/rtgrid_field_callback');
    }

    public function set_table($table = '')
    {
        $this->_table = $table;
        $this->_unique = substr(md5($table . $this->config->item('encryption_key')), 0, 8);
    }

    public function get_table()
    {
        return $this->_table;
    }

    public function set_primery_key($primery_key = '')
    {
        $this->_primery_key = $primery_key;
    }

    public function set_primery_key_value($primery_key_value = 0)
    {
        $this->_primery_key_value = intval($primery_key_value);
    }

    public function fields($fields = '')
    {
        $this->_fields_array = array();

        foreach (explode(',', $fields) as $value) {
            $value = trim($value);
            $key = $this->_field_alias($value);
            $this->_fields_array[$key] = preg_replace('/(.*\sas\s)?(.*\.)?/', '', $value);
        }

        $this->_fields = $fields;
    }

    public function get_fields()
    {
        return $this->_fields;
    }

    public function display_as($field, $value)
    {
        $this->_display_as[$field] = $value;
    }

    /**
     * Set tooltip to column/field
     * @param string $field column/field name
     * @param string $html html or text
     * @param bool $grid show in grid or not
     * @return void
     */
    public function tooltip($field, $html)
    {
        $this->tooltip[$field] = $html;
    }

    public function callback_field($field, $callback)
    {
        $this->_callback_field[$field] = $callback;
    }

    public function callback_before_edit($callback)
    {
        $this->_callback_before_edit[] = $callback;
    }

    public function callback_after_edit($callback)
    {
        $this->_callback_after_edit[] = $callback;
    }

    public function where($key, $value = NULL, $escape = TRUE)
    {
        $where = new stdClass();
        $where->key = $key;
        $where->value = $value;
        $where->escape = $escape;

        $this->_where[] = $where;
    }

    public function where_in($key, $value = NULL, $escape = TRUE)
    {
        $where_in = new stdClass();
        $where_in->key = $key;
        $where_in->value = $value;
        $where_in->escape = $escape;

        $this->_where_in[] = $where_in;
    }

    public function join($table, $cond, $type = '')
    {
        $join = new stdClass();
        $join->table = $table;
        $join->cond = $cond;
        $join->type = $type;

        $this->_join[] = $join;
    }

    public function add_action(rtgrid_edit_action $rtgrid_edit_action)
    {
        $this->_actions[$rtgrid_edit_action->get_name()] = $rtgrid_edit_action;
    }

    public function unset_action($name)
    {
        $data = new rtgrid_edit_action($name);

        unset($this->_actions[$data->get_name()]);
    }

    /**
     * Add observer
     * @param SplObserver $obs
     */
    public function attach(SplObserver $obs)
    {
        $id = spl_object_hash($obs);
        $this->observers[$id] = $obs;
    }

    /**
     * Remove observer
     * @param SplObserver $obs
     */
    public function detach(SplObserver $obs)
    {
        $id = spl_object_hash($obs);
        unset($this->observers[$id]);
    }

    /**
     * Notify observers
     */
    public function notify()
    {
        foreach ($this->observers as $obs) {
            $obs->update($this);
        }
    }

    /**
     * Add multilang field
     * @param multilang $multilang
     * @return boolean
     */
    public function multilang(multilang $multilang)
    {
        // Remove multilang fields from fields list if any
        $this->fields(preg_replace('/' . $multilang->get_data('field') . '\s*\,?/', '', $this->_fields));

        $this->_multilang[$multilang->get_data('lang_table')][] = $multilang;
    }

    public function add_tab($name = '', $data = '', $position = 0)
    {
        if (!empty($name)) {
            if (!empty($this->_tabs[$position])) {
                $position = count($this->_tabs) + 1;
            }
            $this->_tabs[$position] = array(
                'name' => $name,
                'data' => $data
            );

            return FALSE;
        }

        return TRUE;
    }

    public function set_relation($field_name, $related_table, $related_title_field, $where, $order_by)
    {
        // Get table pkey
        $db = clone $this->db;
        $fields = $db->list_fields($related_table);
        $pkey_array = array(
            $field_name,
            'id',
            'id_' . $related_table,
            $related_table . '_id',
            'id_' . $field_name,
            $field_name . '_id',
        );
        foreach ($fields as $field) {
            $key = array_search($field, $pkey_array);
            if ($key !== FALSE) {
                $primery_field = $pkey_array[$key] . ' as ' . $field_name;
                break;
            }
        }

        if (empty($primery_field)) {
            $message = $this->lang->line('Primary key of table %s not found. Method set_relation()');
            show_error(sprintf($message, $related_table));
        }

        if (!is_null($where)) {
            if (is_string($where)) {
                $this->db->where($where, '', FALSE);
            } else {
                $this->db->where($where);
            }
        }

        if (!is_null($order_by)) {
            $this->db->order_by($related_title_field, $order_by);
        }

        $data = $this->db->
                        select($primery_field . ', ' . $related_title_field)->
                        get($related_table)->result_array();

        if (!empty($data)) {
            $this->load->model('rtgrid/rtgrid_field_callback');
            $key = $this->_field_alias($field_name);
            $this->rtgrid_field_callback->buffer[$key][0] = '---';
            foreach ($data as $v) {
                $this->rtgrid_field_callback->buffer[$key][$v[$field_name]] = $v[$related_title_field];
            }

            $this->callback_field($field_name, array($this->rtgrid_field_callback, 'dropdown'));
        }
    }

    public function set_relation_n_n($field_name, $mapping_table, $selected_table, $selected_table_alias_field, $selected_table_where = array())
    {
        $this->fields(str_replace($field_name, $this->_table . '.' . $this->_primery_key . ' as ' . $field_name, $this->_fields));

        $this->load->library('rtgrid/callback/rtgc_set_relation_n_n');
        $rtgc_set_relation_n_n = new rtgc_set_relation_n_n($field_name, $this->_table, $this->_primery_key_value, $mapping_table, $selected_table, $selected_table_alias_field, $selected_table_where);
        $this->callback_field($field_name, array($rtgc_set_relation_n_n, 'field'));
        $this->callback_before_edit(array($rtgc_set_relation_n_n, 'callback_before_edit'));
        $this->callback_after_edit(array($rtgc_set_relation_n_n, 'callback_after_edit'));

        // Pluggin
        $this->ciext->load_jquery_ui();
        $plugin_folder = '/' . $this->config->item('assets_folder') . '/plugins/multiselect';
        $this->js_css->add_js($plugin_folder . '/js/ui.multiselect.js');
        //$this->js_css->add_js($plugin_folder . '/js/locale/ui-multiselect-' . $this->config->item('language_short'). '.js');
        $this->js_css->add_css($plugin_folder . '/css/common.css');
        $this->js_css->add_css($plugin_folder . '/css/ui.multiselect.css');
        $this->js_css->add_js_string('$(function(){$(\'.multiselect\').css(\'width\', \'600px\').css(\'height\', \'200px\').multiselect();});');
    }

    public function add_photogallery(photogallery $photogallery)
    {
        $this->load->module('alphagallery/alphagallery_admin');

        $config['main_table'] = $photogallery->get_table();
        $config['foreign_key'] = $this->_primery_key;
        $config['foreign_key_value'] = $this->_primery_key_value;
        $config['photo_path'] = $photogallery->get_photo_path();
        $config['photo_width'] = $photogallery->get_photo_width();
        $config['photo_height'] = $photogallery->get_photo_height();
        $translate_fields = $photogallery->get_translate_fields();
        if (!empty($translate_fields)) {
            $config['lang_db_data'] = array();
            foreach ($translate_fields as $field => $length) {
                $config['lang_db_data'][] = $field;
                if (!empty($length)) {
                    $config['lang_db_data_length'][$field] = $length;
                }
            }
        }

        if ($photogallery->create_tables_when_run) {
            $this->alphagallery_admin->create_tables($config);
        }

        if (empty($this->_primery_key_value)) {
            $pk = $this->_primery_key;
            $table = $photogallery->get_table();
            $this->callback_after_edit(function($post, $pkey) use ($pk, $table) {
                $CI = & get_instance();
                $CI->db->
                        where($pk, 0)->
                        update($table, array($pk => $pkey));
            });
        }

        $this->add_tab($this->lang->line('Photos'), $this->alphagallery_admin->render($config), -1);
    }

    public function readonly($field)
    {
        $this->_readonly[] = $field;
        $this->callback_field($field, array($this->rtgrid_field_callback, 'readonly'));
    }

    public function hidden($field, $value = 0)
    {
        $this->_hidden[$field] = $value;
    }

    public function required_fields($array = array())
    {
        $this->_required_fields = $array;
    }

    public function unique_fields($array = array())
    {
        $this->_unique_fields = array_merge($this->_unique_fields, $array);
    }

    public function render()
    {
        $fields = array();
        $content = array(
            'message'      => '',
            'tabs_control' => array(),
            'tabs'         => array()
        );

        // If action
        if (!empty($_POST)) {
            foreach ($this->_actions as $action_name => $callback) {
                if (isset($_POST[$action_name])) {
                    $this->current_action = $action_name;
                    $this->post = array();
                    foreach ($this->_fields_array as $alies => $field) {
                        $xss_clean = true;
                        // Ignore xss clean if needed
                        if (isset($this->_callback_field[$field])) {
                            if ($this->_callback_field[$field] instanceof \Abstract_rtgc_callback) {
                                $xss_clean = $this->_callback_field[$field]->get_field_xss_clean();
                            } elseif (is_array($this->_callback_field[$field]) && isset($this->_callback_field[$field][0]) && $this->_callback_field[$field][0] instanceof \Abstract_rtgc_callback) {
                                $xss_clean = $this->_callback_field[$field][0]->get_field_xss_clean();
                            }
                        }
                        $this->post[$field] = $this->input->post($alies, $xss_clean);
                    }

                    // Callback before edit
                    if (!is_null($this->_callback_before_edit)) {
                        foreach ($this->_callback_before_edit as $item) {
                            $this->post = call_user_func($item, $this->post, $this->_primery_key_value);
                        }
                    }

                    // Required check
                    $required = '';
                    foreach ($this->_required_fields as $r_field) {
                        $req_check = $this->input->post($this->_field_alias($r_field));
                        if (is_array($req_check)) {
                            $req_check = reset($req_check);
                        }
                        $required .= (empty($req_check)) ? ' - ' . $this->_get_display_as($r_field) . '<br />' : '';
                    }
                    if (!empty($required)) {
                        $content['message'] = $this->_alert($this->lang->line('Data not saved') . '<br />' . $this->lang->line('Required fields:<br />') . $required, 'error');
                        break;
                    }

                    // Unique check
                    if (!empty($this->_unique_fields)) {
                        $db = clone $this->db;
                        $unique = '';
                        foreach ($this->_unique_fields as $u_field) {
                            if (!empty($this->post[$u_field])) {
                                $u_check = $db
                                        ->select($this->_primery_key)
                                        ->where($u_field, $this->post[$u_field])
                                        ->get($this->_table)
                                        ->row_array();
                                if (!empty($u_check) && $u_check[$this->_primery_key] != $this->_primery_key_value) {
                                    $unique .= $this->_get_display_as($u_field)
                                            . ' "' . $this->post[$u_field] . '" '
                                            . $this->lang->line('already exist')
                                            . '<br />';
                                }
                            }
                        }
                        if (!empty($unique)) {
                            $content['message'] = $this->_alert($unique, 'error');
                            break;
                        }
                    }

                    if (!empty($this->_readonly)) {

                        foreach ($this->_readonly as $readonly_field) {
                            if (isset($this->post[$readonly_field])) {
                                unset($this->post[$readonly_field]);
                            }
                        }
                    }

                    // Add hidden fields
                    if (!empty($this->_hidden)) {
                        $this->post = array_merge($this->post, $this->_hidden);
                    }

                    $func = $callback->get_callback();
                    if (!empty($func)) {
                        $this->current_action_return = call_user_func($func, $this->_table, $this->_primery_key, $this->_primery_key_value, $this->post);

                        // Update primery key value if saved
                        if ($this->current_action_return && empty($this->_primery_key_value)) {
                            $this->_primery_key_value = $this->db->insert_id();
                            $clear_fields = TRUE;
                        }

                        // If action 'save' and is multilang then update multilang
                        if (!empty($this->_multilang)) {
                            $id = empty($this->_primery_key_value) ? $this->db->insert_id() : $this->_primery_key_value;
                            $rs = $this->_multilang_save($id);
                            $this->current_action_return = ($this->current_action_return) ? $this->current_action_return : $rs;
                        }

                        // Clear $_POST if saved
                        if (!empty($clear_fields)) {
                            $_POST = array();
                        }

                        // Set message
                        $content['message'] = ($this->current_action_return) ? $this->_alert($this->lang->line('Saved'), 'success') : $this->_alert($this->lang->line('Data not saved'), 'error');
                    }

                    if (!is_null($this->_callback_after_edit) && !empty($this->_primery_key_value)) {
                        $after_edit_return = FALSE;
                        foreach ($this->_callback_after_edit as $item) {
                            $after_edit_return = call_user_func($item, $this->post, $this->_primery_key_value);
                        }
                        if (!$this->current_action_return && $after_edit_return) {
                            // Set message
                            $content['message'] = $this->_alert($this->lang->line('Saved'), 'success');
                            $this->current_action_return = TRUE;
                        }
                    }
                    break;
                }
            }

            // Redirect if any
            if (!empty($this->redirect_url) && $this->current_action_return) {
                // Notify observers
                $this->notify();

                $this->load->helper('url');
                redirect($this->redirect_url);
            }

            // Set flash message if data saved and refresh page
            if ($this->current_action_return && !empty($content['message'])) {
                $this->session->set_flashdata('rtgrid_edit_flash_message', $content['message']);
                redirect($this->uri->uri_string());
            }
        }

        // Select data
        if (!empty($this->_where)) {
            foreach ($this->_where as $where) {
                $this->db->where($where->key, $where->value, $where->escape);
            }
        }
        if (!empty($this->_where_in)) {
            foreach ($this->_where_in as $where_in) {
                $this->db->where_in($where_in->key, $where_in->value, $where_in->escape);
            }
        }
        if (!empty($this->_join)) {
            foreach ($this->_join as $join) {
                $this->db->join($join->table, $join->cond, $join->type);
            }
        }

        // If add new then empty fields
        $id = (!empty($clear_fields)) ? 0 : $this->_primery_key_value;

        $data = $this->db->
                        select($this->_fields)->
                        where($this->_table . '.' . $this->_primery_key, $id)->
                        get($this->_table)->row();

        // Check
        if (empty($data) && $id != 0) {
            show_404();
        }

        foreach (explode(',', $this->_fields) as $field) {
            $field = trim($field);
            $field_alias = $this->_field_alias($field);
            $field_value = (isset($data->{$this->_fields_array[$field_alias]})) ? $data->{$this->_fields_array[$field_alias]} : $this->input->post($field_alias);
            // Prepare value
            if (is_array($field_value)) {
                $field_value = array_map('htmlspecialchars', $field_value);
            } else {
                $field_value = htmlspecialchars($field_value);
            }
            $callback = !empty($this->_callback_field[$this->_fields_array[$field_alias]]) ?
                    $this->_callback_field[$this->_fields_array[$field_alias]] :
                    array($this->rtgrid_field_callback, 'default_field');

            $fields['field'][] = array(
                'name'    => $this->_get_display_as($this->_fields_array[$field_alias]) . (in_array($this->_fields_array[$field_alias], $this->_required_fields) ? '*' : ''),
                'value'   => (empty($this->_multifield[$field])) ? call_user_func($callback, $field_alias, $field_value) : $this->_multifield_build($field_alias, $field_value, $callback),
                'tooltip' => $this->render_tooltip($field, $this->_get_display_as($this->_fields_array[$field_alias])),
            );
        }

        // add multilang if any
        if (!empty($this->_multilang)) {
            $this->_multilang_build_tabs($id);
        }

        // Add home tab
        $this->add_tab($this->lang->line('Attributes'), $this->parser->parse('rtgrid/edit/fields_item', $fields, TRUE));

        // Build tabs
        if (!empty($this->_tabs)) {
            ksort($this->_tabs);
            foreach ($this->_tabs as $tab) {
                $id = 'id_' . substr(md5($tab['name']), 0, 6);
                $content['tabs_control'][] = array(
                    'id'     => $id,
                    'name'   => $tab['name'],
                    'active' => (empty($content['tabs_control'])) ? 'class="active"' : ''
                );
                $content['tabs'][] = array(
                    'id'     => $id,
                    'data'   => $tab['data'],
                    'active' => (empty($content['tabs'])) ? 'active' : ''
                );
            }
        }

        $content['actions'] = $this->_get_actions_html();

        $this->load->helper('form');
        $content['form_open'] = form_open_multipart('', array('class' => 'form-horizontal'));
        $content['form_close'] = form_close();

        // Notify observers
        $this->notify();

        return $this->parser->parse('rtgrid/edit/template', $content, TRUE);
    }

    public function set_xss_clean($xss_clean = true)
    {
        $this->xss_clean = $xss_clean;
        return $this;
    }

    protected function _alert($msg = '', $type_class = 'success')
    {
        $template = '<div class="alert alert-%s"><a class="close" data-dismiss="alert">×</a>%s</div>';

        return sprintf($template, $type_class, $msg);
    }

    protected function _get_actions_html()
    {
        $rs = array();
        foreach ($this->_actions as $action) {
            $rs[] = array(
                'action' => $action->get_template()
            );
        }

        return $rs;
    }

    public function _field_alias($field_name)
    {
        return 'f' . substr(md5($this->_unique . $field_name), 0, 8);
    }

    protected function _get_display_as($field_name = '')
    {
        return !empty($this->_display_as[$field_name]) ? $this->_display_as[$field_name] : ucfirst(preg_replace('/[\_\-]/', ' ', $field_name));
    }

    protected function _multilang_build_tabs($id = 0)
    {
        $select = '';
        $join = array();
        $callbacks = array();
        foreach ($this->_multilang as $value) {
            foreach ($value as $obj) {
                $select .= $obj->get_data('lang_table') . '.' . $obj->get_data('lang_table_field') . ' as ' . $obj->get_data('field') . ', ';
                if (!in_array($obj->get_data('lang_table'), $join)) {
                    $join[] = $obj->get_data('lang_table');
                    $this->db->join($obj->get_data('lang_table'), $obj->get_data('lang_table') . '.id_lan=lan.id_lan AND ' . $obj->get_data('lang_table') . '.' . $this->_primery_key . '=' . $id, 'left');
                }
                $callbacks[$obj->get_data('field')] = $obj->get_data('callback_field');
            }
        }

        $q = $this->db->
                        select($select . ', lan.name as lan_name, lan.id_lan as lan_id_lan')->
                        where('lan.active', TRUE)->
                        order_by('lan.name', 'ASC')->
                        get('lan')->result_array();

        foreach ($q as $row) {
            $content = array();
            foreach ($row as $field => $value) {
                $value = htmlspecialchars($value);
                if ($field == 'lan_name' || $field == 'lan_id_lan') {
                    continue;
                }
                $field_alias = $this->_field_alias($field) . '[' . $row['lan_id_lan'] . ']';
                $post = $this->input->post($this->_field_alias($field));
                $value = (!empty($post[$row['lan_id_lan']])) ? $post[$row['lan_id_lan']] : $value;

                $content['field'][] = array(
                    'name'    => $this->_get_display_as($field),
                    'value'   => (!empty($callbacks[$field])) ? call_user_func($callbacks[$field], $field_alias, $value) : $this->rtgrid_field_callback->default_field($field_alias, $value),
                    'tooltip' => ''
                );
            }
            $this->add_tab($row['lan_name'], $this->parser->parse('rtgrid/edit/fields_item', $content, TRUE));
        }
    }

    protected function _multilang_save($reletad_id = 0)
    {
        if (empty($reletad_id)) {

            return FALSE;
        }

        // Prepare data
        $save_arr = array();
        foreach ($this->_multilang as $items) {
            foreach ($items as $item) {
                // Get data from post
                $post = $this->input->post($this->_field_alias($item->get_data('field')));
                if (!empty($post)) {
                    foreach ($post as $id_lan => $value) {
                        $id_lan = intval($id_lan);
                        if (!empty($id_lan)) {
                            $save_arr[$item->get_data('lang_table')][$id_lan][$item->get_data('lang_table_field')] = $value;
                        }
                    }
                }
            }
        }
        // Save data
        foreach ($save_arr as $table => $data) {
            foreach ($data as $id_lan => $row) {
                $row[$this->_primery_key] = $reletad_id;
                $row['id_lan'] = $id_lan;
                // Save data
                $exists = $this->db->
                                select(array_keys($row))->
                                where(array(
                                    $this->_primery_key => $reletad_id,
                                    'id_lan'            => $id_lan
                                ))->
                                get($table)->row_array();
                // Update or insert
                if (!empty($exists)) {
                    $this->db->
                            where(array(
                                $this->_primery_key => $reletad_id,
                                'id_lan'            => $id_lan
                            ))->
                            update($table, $row);
                } else {
                    $this->db->insert($table, $row);
                }
            }
        }

        return TRUE;
    }

    public function set_image_upload(image_upload $data)
    {
        if (!is_dir(FCPATH . $data->get_path())) {
            show_error(sprintf($this->lang->line('Folder %s for field %s does not exist. Please create a new folder and try again.'), FCPATH . $data->get_path(), $data->get_field()));
        }

        $image = new Rtgc_upload_image([
            'upload_path' => './' . trim(ltrim($data->get_path(), '.'), '/'),
        ]);

        // Set Resizer if needed
        if ($data->get_width() && $data->get_height()) {
            $this->load->library('image');
            $image->merge_config([
                'callback_after_upload' => function($file) use ($data) {
                    $path = trim(ltrim($data->get_path(), '.'), '/') . '/' . $file;
                    return (new Image())->resize($path, $path, $data->get_width(), $data->get_height());
                }
            ]);
        }

        $field_alias = $this->_field_alias($data->get_field());
        $this->callback_field($data->get_field(), function($name, $value) use ($image, $data) {
            // Set assets
            $this->js_css->add_js_string($image->get_config()['js_string']);
            $this->js_css->parse_css('rtgrid/edit/image_upload/css/photo.css');

            $content = [
                'img_box' => $image->field($name, $value),
                'width'   => $data->get_width(),
                'height'  => $data->get_height(),
            ];

            return get_instance()->parser->parse('rtgrid/edit/image_upload/template', $content, true);
        });
        $this->callback_before_edit(function($post) use ($image, $data, $field_alias) {
            if ($image->do_upload($field_alias)) {
                $post[$data->get_field()] = $_POST[$field_alias];
            }
            return $post;
        });
    }

    public function multifield($field)
    {
        $this->_multifield[$field] = $field;
    }

    protected function _multifield_build($field_alias, $field_value, $callback)
    {
        $this->js_css->parse_js('rtgrid/edit/multifield/js/multifield.js');

        $field_data = json_decode(htmlspecialchars_decode($field_value));
        $content['field'] = array();
        $content['alias'] = $field_alias;
        $content['value'] = $field_value;
        if (!empty($field_data) && is_array($field_data)) {
            foreach ($field_data as $key => $value) {
                $content['field'][] = array(
                    'value' => (!empty($callback)) ? call_user_func($callback, $field_alias, $value) : $this->rtgrid_field_callback->default_field($field_alias, $value),
                    'btn'   => ($key == 0) ? 'icon-plus' : 'icon-remove',
                    'class' => ($key == 0) ? 'add' : 'remove'
                );
            }
        } else {
            $content['field'][] = array(
                'value' => (!empty($callback)) ? call_user_func($callback, $field_alias, $field_value) : $this->rtgrid_field_callback->default_field($field_alias, $field_value),
                'btn'   => 'icon-plus',
                'class' => 'add'
            );
        }

        return $this->parser->parse('rtgrid/edit/multifield/multifield', $content, TRUE);
    }

    /**
     * Render tooltip
     * 
     * @param string $field
     * @param string $name
     * @return string
     */
    protected function render_tooltip($field, $name)
    {
        $result = '';

        if (!empty($this->tooltip[$field])) {
            $rtgrid_tooltip = $this->load->library('rtgrid/rtgrid_tooltip');
            $result = $rtgrid_tooltip->render_tooltip($field, $name, $this->tooltip[$field]);
        }

        return $result;
    }

}
