<?php

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

/**
 * Description of skeleton_crud_generator
 *
 * @author Igor Ratsun
 */
class skeleton_crud_generator extends CI_Model
{

    const SPACES_BEFORE = '        ';

    protected $callbacks = array();

    public function generate()
    {
        $items = $this->input->post('item');

        if (empty($items)) {

            return FALSE;
        }

        // Load callbacks
        $callbacks = $this->load_callbacks();

        $parse = array(
            'module_folder' => $this->input->post('module_folder'),
            'columns' => '',
            'fields' => '',
            'required' => '',
            'callback' => '',
            'display_as' => '',
        );
        $parse['table'] = '\'' . $this->input->post('table_name') . '\'';

        foreach ($this->input->post('item') as $v) {
            $parse['columns'] .= (!empty($v['in_column']) ? ', ' . $v['field'] : '');
            $parse['fields'] .= (!empty($v['field']) ? ', ' . $v['field'] : '');
            $parse['required'] .= (!empty($v['not_null']) ? ', \'' . $v['field'] . '\'' : '');
            if (isset($v['callback']) && !empty($callbacks[$v['callback']])) {
                $tmp = $callbacks[$v['callback']];
                $run = $tmp->run();
                if (!($run instanceof crud_callback_chunk_run)) {
                    $run = new crud_callback_chunk_run($v['field'], $run, $v);
                } else {
                    $run->set_field($v['field']);
                    $run->set_post($v);
                }
                $parse['callback'] .= self::SPACES_BEFORE . $run->get_callback_string() . PHP_EOL;

                // Add schema
                if (!strpos($v['field'], ' as ')) {
                    $get_schema = $tmp->get_schema();
                    if (!($get_schema instanceof crud_callback_chunk_schema)) {
                        $get_schema = new crud_callback_chunk_schema();
                        $get_schema->set_type($tmp->get_schema());
                    }
                    $get_schema->set_table($this->input->post('table_name'));
                    $get_schema->set_field($v['field']);
                    $get_schema->set_not_null(!empty($v['not_null']));
                    if (empty($schema[$get_schema->get_table()])) {
                        $schema[$get_schema->get_table()] = array(
                            'fields' => '',
                            'extra_fields' => '',
                        );
                    }
                    $schema[$get_schema->get_table()]['fields'] .= $get_schema->generate() . ',' . PHP_EOL;
                    if (!empty($get_schema->get_extra_fields())) {
                        $schema[$get_schema->get_table()]['extra_fields'] = $get_schema->get_extra_fields() . ',' . PHP_EOL;
                    }
                }
            }
            if (!empty($v['display_as'])) {
                $parse['display_as'] .= self::SPACES_BEFORE
                        . '$this->crud->display_as(\'' . $v['field']
                        . '\', $this->lang->line(\'' . $v['display_as'] . '\'));'
                        . PHP_EOL;
            }
        }
        $parse['columns'] = '\'' . ltrim($parse['columns'], ', ') . '\'';
        $parse['fields'] = '\'' . ltrim($parse['fields'], ', ') . '\'';
        $parse['required'] = !empty($parse['required']) ? PHP_EOL . self::SPACES_BEFORE . '$this->crud->required_fields(' . ltrim($parse['required'], ', ') . ');' . PHP_EOL : '';
        $parse['callback'] = ltrim($parse['callback'], self::SPACES_BEFORE);
        $parse['display_as'] = ltrim($parse['display_as'], self::SPACES_BEFORE);

        $crud_file = ucfirst(strtolower($this->input->post('crud_file')));
        $crud_model = str_replace('CRUD_CLASS_NAME', $crud_file, file_get_contents($this->skeleton_model_admin->getSrcFolder() . '/models/crud.php'));
        foreach ($parse as $pItem => $pVal) {
            $crud_model = str_replace('/* ' . $pItem . ' */', $pVal, $crud_model);
        }

        $moduleFolder = FCPATH . 'application/modules/' . $this->input->post('module_folder');
        $rs['crud_model_file'] = $moduleFolder . '/models/' . $crud_file . '.php';
        $rs['crud_model_data'] = str_replace('<?php', '', $crud_model);
        $rs['crud_schema_file'] = $moduleFolder . '/data/install.sql';
        $rs['crud_schema_data'] = file_exists($rs['crud_schema_file']) ? file_get_contents($rs['crud_schema_file']) . PHP_EOL : '';
        foreach ($schema as $table => $s_data) {
            $rs['crud_schema_data'] .= 'CREATE TABLE IF NOT EXISTS `' . $table . '` ( ' . PHP_EOL
                    . '`id_' . $table . '` int(11) NOT NULL AUTO_INCREMENT,' . PHP_EOL
                    . $s_data['fields']
                    . $s_data['extra_fields']
                    . 'PRIMARY KEY (`id_' . $table . '`) ' . PHP_EOL
                    . ') ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;' . PHP_EOL;
        }
        // Create model file
        if (!$this->skeleton_model_admin->createFolder($moduleFolder . '/models') || !$this->skeleton_model_admin->createFile($rs['crud_model_file'], $crud_model)) {

            return FALSE;
        }

        // Create sql
        if (!$this->skeleton_model_admin->createFolder($moduleFolder . '/data') || !$this->skeleton_model_admin->createFile($rs['crud_schema_file'], $rs['crud_schema_data'])) {

            return FALSE;
        }

        return $rs;
    }

    public function load_callbacks()
    {
        if (empty($this->callbacks)) {
            foreach ($this->config->item('crud_callback_chunk') as $helpers) {
                $this->load->helper($helpers);
                foreach ($helpers as $k => $v) {
                    $class = str_replace('skeleton/', '', $v);
                    $this->callbacks[$class] = new $class();
                }
            }
        }

        return $this->callbacks;
    }

}
