<?php

/*
 * 2007-2012 PrestaShop
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 *         DISCLAIMER   * 
 * *************************************** */
/* Do not edit or add to this file if you wish to upgrade Prestashop to newer
 * versions in the future.
 * ****************************************************
 * @category   Belvg
 * @package    Belvg_Background
 * @author    Alexander Simonchik <support@belvg.com>
 * @site    http://module-presta.com
 * @copyright  Copyright (c) 2010 - 2012 BelVG LLC. (http://www.belvg.com)
 * @license    http://store.belvg.com/BelVG-LICENSE-COMMUNITY.txt
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

define('BBP_PATTERNS_DIR', dirname(__FILE__) . '/patterns/');
define('BBP_PATTERNS_URL', __PS_BASE_URI__ . 'modules/belvg_backgroundpages/patterns/');

class Belvg_BackgroundPages extends Module {

    const MODULE_PREFIX = 'BBP_';

    protected $_moduleParams = array(
        'USE_IN_FRONTEND' => 1,
        'DEFAULT_PATTERN' => 'blank',
    );

    public function __construct() {
        $this->name = 'belvg_backgroundpages';
        $this->tab = 'front_office_features';
        $this->version = '1.0.0';
        $this->author = 'BelVG';
        $this->need_instance = 0;
        $this->module_key = '115fe0a943ac49ede82dd779741b66c5';

        parent::__construct();

        $this->displayName = $this->l('Background Switcher');
        $this->description = $this->l('Tools for making a great first impression on your customers by vivid and meaningful store design');

        $this->ignore_array = array('..', '.', 'products', 'categories', 'default');
    }

    public function install() {
        foreach ($this->_moduleParams as $param => $value) {
            $this->_setModuleParam($param, $value);
        }
        
        $this->copyDefaultPatterns();

        if (!parent::install() OR
                !$this->registerHook('displayHeader') OR
                !$this->registerHook('displayBackOfficeHeader') OR
                //!$this->registerHook('displayFooterProduct') OR
                !$this->registerHook('displayAdminProductsExtra') OR
                !$this->registerHook('displayBackOfficeHome') OR
                !$this->registerHook('actionProductUpdate')
        ) {
            return FALSE;
        }

        return TRUE;
    }

    public function uninstall() {
        $this->deleteCustomPatterns();

        return parent::uninstall();
    }

    protected function _setModuleParam($param, $value) {
        return Configuration::updateValue(Belvg_BackgroundPages::MODULE_PREFIX . $param, $value);
    }

    protected function _getModuleParam($param) {
        return Configuration::get(Belvg_BackgroundPages::MODULE_PREFIX . $param);
    }

    protected function _postProcess() {
        if (Tools::isSubmit('submitUpdate')) {
            $errors = '';
            $data = $_POST;
            if (is_array($data)) {
                foreach ($data as $key => $value) {
                    if (array_key_exists($key, $this->_moduleParams)) {
                        $this->_setModuleParam($key, $value);
                    }
                }
            }

            /* upload the image */
            if (isset($_FILES['new_pattern_name']) && isset($_FILES['new_pattern_name']['tmp_name']) && !empty($_FILES['new_pattern_name']['tmp_name'])) {
                $unic_filename = $this->generateUnicName($_FILES['new_pattern_name']['name']);
                if (file_exists(BBP_PATTERNS_DIR . $unic_filename)) {
                    $errors .= $this->displayError($this->l('File with the same name is exists, change file name or delete it.'));
                }

                if ($error = ImageManager::validateUpload($_FILES['new_pattern_name'])) {
                    $errors .= $this->displayError($error);
                } elseif (!($tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS')) || !move_uploaded_file($_FILES['new_pattern_name']['tmp_name'], $tmpName)) {
                    return FALSE;
                } elseif (!ImageManager::resize($tmpName, BBP_PATTERNS_DIR . $unic_filename)) {
                    $errors .= $this->displayError($this->l('An error occurred during the image upload.'));
                }

                if (isset($tmpName)) {
                    unlink($tmpName);
                }
            }

            $delete_items = Tools::getValue('delete');
            if (!empty($delete_items)) {
                foreach ($delete_items as $item) {
                    unlink(BBP_PATTERNS_DIR . $item);
                }
            }

            if (empty($errors)) {
                Tools::redirectAdmin('index.php?tab=AdminModules&conf=4&configure=' . $this->name . '&token=' . Tools::getAdminToken('AdminModules' . (int) (Tab::getIdFromClassName('AdminModules')) . (int) $this->context->employee->id));
            }

            $this->_html .= $errors;
        }
    }

    private function initToolbar() {
        $this->toolbar_btn['save'] = array(
            'href' => '#',
            'desc' => $this->l('Save')
        );

        return $this->toolbar_btn;
    }

    private function initForm() {
        $helper = new HelperForm();
        $helper->module = $this;
        $helper->name_controller = $this->name;
        $helper->identifier = $this->identifier;
        $helper->token = Tools::getAdminTokenLite('AdminModules');
        $helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
        $helper->toolbar_scroll = TRUE;
        $helper->toolbar_btn = $this->initToolbar();
        $helper->title = $this->displayName;
        $helper->submit_action = 'submitUpdate';
        $helper->override_folder = 'override/';

        $patterns = $this->getAvailablePatterns();
        $available_patterns = array();
        foreach ($patterns as $key => $pattern) {
            $available_patterns[] = array(
                'pattern_link' => __PS_BASE_URI__ . 'modules/' . $this->name . '/controllers/admin/index.php?pattern_name=' . $pattern,
                //preg_replace('/\..+$/','',$pattern)
                'pattern_name' => $pattern,
                'DEFAULT_PATTERN' => $pattern,
            );
        }

        $this->checkExistsDefaultPattern();

        $this->context->smarty->assign(array(
            'base_url' => __PS_BASE_URI__,
            'belvg_background_use_default_link' => __PS_BASE_URI__ . 'modules/' . $this->name . '/controller/admin/index.php',
            'empty_pattern_link' => __PS_BASE_URI__ . 'modules/' . $this->name . '/controllers/admin/index.php?pattern_name=blank',
            'belvg_background_changer_url' => __PS_BASE_URI__ . 'modules/' . $this->name . '/controllers/admin/index.php',
            'context_shop_id' => Shop::getContextShopID(TRUE),
            'context_shop_group_id' => Shop::getContextShopGroupID(TRUE),
            'used_pattern' => Configuration::get('BBP_DEFAULT_PATTERN'),
        ));

        $this->fields_form[0]['form'] = array(
            'tinymce' => TRUE,
            'legend' => array(
                'title' => $this->displayName,
                'image' => $this->_path . 'logo.gif'
            ),
            'submit' => array(
                'name' => 'submitUpdate',
                'title' => $this->l('   Save   '),
                'class' => 'button'
            ),
            'input' => array(
                /*array(
                    'type' => 'categories_select',
                    'category_tree' => $this->renderProductSelect(),
                    'label' => $this->l('http://module-presta.com'),
                    'name' => 'module-presta',
                    'display_image' => FALSE
                ),*/
                array(
                    'type' => 'radio',
                    'values' => array(
                        array('label' => $this->l('Yes'), 'value' => 1, 'id' => 'showblock_frontend'),
                        array('label' => $this->l('No'), 'value' => 0, 'id' => 'showblock_frontend'),
                    ),
                    'is_bool' => TRUE,
                    'class' => 't',
                    'label' => $this->l('Enable the background switcher'),
                    'name' => 'USE_IN_FRONTEND'
                ),
                array(
                    'type' => 'smart_select',
                    'label' => $this->l('Available patterns:'),
                    'name' => 'DEFAULT_PATTERN',
                    'id' => 'pattern_name',
                    'default_value' => Configuration::get('BBP_DEFAULT_PATTERN'),
                    'patterns_dir' => BBP_PATTERNS_URL,
                    'options' => array(
                        'query' => $available_patterns,
                        'name' => 'DEFAULT_PATTERN',
                        'id' => 'pattern_name',
                    ),
                ),
                array(
                    'type' => 'file',
                    'label' => $this->l('New pattern'),
                    'name' => 'new_pattern_name',
                    'display_image' => FALSE
                ),
            ),
        );

        return $helper;
    }

    public function getContent() {
        $this->_postProcess();
        $helper = $this->initForm();
        foreach ($this->fields_form[0]['form']['input'] as $input) {
            if ($input['name'] != 'image') {
                $helper->fields_value[$input['name']] = $this->_getModuleParam($input['name']);
            }
        }

        $this->_html .= $this->display(__FILE__, 'views/templates/admin/iframe.tpl');
        $this->_html .= $helper->generateForm($this->fields_form);

        return $this->_html;
    }

    public function hookDisplayAdminProductsExtra($params) {
        $id_product = Tools::getValue('id_product');
        $template_path = dirname(__FILE__) . '/views/templates/admin/_configure/admin_products.tpl';
        $data = $this->context->smarty->createTemplate($template_path);
        $img_dir = BBP_PATTERNS_DIR . 'products/' . $id_product;
        $data->assign(array(
            'PS_ATTACHMENT_MAXIMUM_SIZE' => Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE'),
            'belvg_bg_errors' => ((isset($this->context->cookie->belvg_bg_errors) && !empty($this->context->cookie->belvg_bg_errors)) ? $this->context->cookie->belvg_bg_errors : ''),
        ));
        $this->context->cookie->belvg_bg_errors = NULL;
        if (!$this->dir_is_empty($img_dir)) {
            $data->assign(array(
                'product_background_img' => BBP_PATTERNS_URL . 'products/' . $id_product . '/' . $this->getBackgroundImgByProductId($id_product),
            ));
        }

        return $data->fetch();
    }

    public function hookActionProductUpdate($params) {
        $id_product = Tools::getValue('id_product');
        $dir = BBP_PATTERNS_DIR . 'products/' . $id_product;
        $delete_current_img = Tools::getValue('delete_current_img');
        $errors = '';
        /* delete image */
        if ($delete_current_img) {
            $this->deleteImgByProductId($id_product);
        }

        /* upload the image */
        if (isset($_FILES['background_file']) && isset($_FILES['background_file']['tmp_name']) && !empty($_FILES['background_file']['tmp_name'])) {
            $extension = substr($_FILES['background_file']['name'], strrpos($_FILES['background_file']['name'], "."));
            $unic_filename = $id_product . '.' . $extension;
            if (!file_exists($dir)) {
                mkdir($dir, 0777);
            }

            if ($error = ImageManager::validateUpload($_FILES['background_file'])) {
                $errors .= $this->displayError($error);
            } elseif (!($tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS')) || !move_uploaded_file($_FILES['background_file']['tmp_name'], $tmpName) || !$this->deleteImgByProductId($id_product)) {
                return FALSE;
            } elseif (!ImageManager::resize($tmpName, BBP_PATTERNS_DIR . 'products/' . $id_product . '/' . $unic_filename)) {
                $errors .= $this->displayError($this->l('An error occurred during the image upload.'));
            }

            $this->context->cookie->belvg_bg_errors = $errors;

            if (isset($tmpName)) {
                unlink($tmpName);
            }
        }
    }

    public function hookBackOfficeHome() {
        return ($this->display(__FILE__, 'views/templates/admin/iframe.tpl'));
    }

    public function hookHeader() {
        $this->context->controller->addCSS(($this->_path) . 'css/bg_frontend.css', 'all');
        $this->context->controller->addJS(($this->_path) . 'js/jquery.cookie.js');
        $this->context->controller->addJS(($this->_path) . 'js/jquery.tinyscrollbar.min.js');
        $this->context->controller->addJS(($this->_path) . 'js/jquery.belvg_backgroundpages.js');
        
        $this->checkExistsDefaultPattern();

        $specific_img = NULL;
        $controller = Dispatcher::getInstance()->getController();
        if (in_array($controller, array('product', 'category'))) {
            $id_product = Tools::getValue('id_product');
            $id_category = Tools::getValue('id_category');
            if (!empty($id_product)) {
                $img = $this->getBackgroundImgByProductId($id_product);
                if (!empty($img)) {
                    $specific_img = BBP_PATTERNS_URL . 'products/' . $id_product . '/' . $img;
                }
            } elseif (!empty($id_category)) {
                $img = $this->getBackgroundImgByCategoryId($id_category);
                if (!empty($img)) {
                    $specific_img = BBP_PATTERNS_URL . 'categories/' . $id_category . '/' . $img;
                }
            }
        }

        $settings = array(
            'specific_img' => $specific_img,
            'allow_colorchanger' => Configuration::get('BBP_USE_IN_FRONTEND'),
            'preselected_pattern' => BBP_PATTERNS_URL . Configuration::get('BBP_DEFAULT_PATTERN'),
            'patterns_collection' => $this->getAvailablePatterns(TRUE, TRUE),
            'active_bg' => isset($_COOKIE['bg_pattern']) ? $_COOKIE['bg_pattern'] : BBP_PATTERNS_URL . Configuration::get('BBP_DEFAULT_PATTERN'),
            'empty_bg' => (Configuration::get('BBP_DEFAULT_PATTERN') == 'blank' && !isset($_COOKIE['bg_pattern'])) || $_COOKIE['bg_pattern'] == "none"
        );

        $this->context->smarty->assign(
                'belvg_bg_settings', $settings
        );

        return ($this->display(__FILE__, 'views/templates/front/themesettings.tpl'));
    }

    private function getAvailablePatterns($full_path = FALSE, $image_size = FALSE) {
        $patterns = array();
        if (is_dir(BBP_PATTERNS_DIR)) {
            $patterns = array_diff(scandir(BBP_PATTERNS_DIR), $this->ignore_array);
        }

        if ($full_path || $image_size) {
            $ext_patterns = array();
            $i = 0;
            foreach ($patterns as $pattern) {
                $ext_patterns[$i]['path'] = BBP_PATTERNS_DIR . $pattern;
                if ($full_path) {
                    $ext_patterns[$i]['url'] = BBP_PATTERNS_URL . $pattern;
                }
                
                if ($image_size) {
                    $ext_patterns[$i]['size_info'] = getimagesize($ext_patterns[$i]['path']);
                }
                
                $i++;
            }
            
            return $ext_patterns;
        }
        
        return $patterns;
    }

    private function dir_is_empty($dir) {
        if (!file_exists($dir)) {
            return TRUE;
        }

        return (count(scandir($dir)) == 2);
    }

    private function deleteImgByProductId($id_product) {
        $dir = BBP_PATTERNS_DIR . 'products/' . $id_product;
        $imgs = array_diff(scandir($dir), $this->ignore_array);
        foreach ($imgs as $img) {
            if (!unlink($dir . '/' . $img)) {
                return FALSE;
            }
        }

        return TRUE;
    }

    public function getBackgroundImgByProductId($id_product) {
        $dir = BBP_PATTERNS_DIR . 'products/' . $id_product;
        if (!file_exists($dir)) {
            return FALSE;
        }

        $img = array_diff(scandir($dir), $this->ignore_array);

        if (!empty($img)) {
            return array_shift(array_values($img));
        }
    }

    public function getBackgroundImgByCategoryId($id_category) {
        $dir = BBP_PATTERNS_DIR . 'categories/' . $id_category;
        if (!file_exists($dir)) {
            return FALSE;
        }

        $img = array_diff(scandir($dir), $this->ignore_array);

        if (!empty($img)) {
            return array_shift(array_values($img));
        }
    }

    public function generateUnicName($orig_name) {
        $patterns = $this->getAvailablePatterns();
        $max = 0;
        foreach ($patterns as $pattern) {
            $pattern_index = substr($pattern, 0, strpos($pattern, "_"));
            if ($max < $pattern_index) {
                $max = $pattern_index;
            }
        }
        
        $extension = substr($orig_name, strrpos($orig_name, "."));
        $new_name = substr($orig_name, 0, strrpos($orig_name, "."));

        return ($max + 1) . "_" . preg_replace("/[^\p{L}\p{N}]/u", '-', pSQL($new_name)) . $extension;
    }
    
    public function copyDefaultPatterns() {
        //categories
        $categories_dir = BBP_PATTERNS_DIR . 'categories/';
        if (!file_exists($categories_dir)) {
            mkdir($categories_dir, 0777);
        }
        
        //products
        $products_dir = BBP_PATTERNS_DIR . 'products/';
        if (!file_exists($products_dir)) {
            mkdir($products_dir, 0777);
        }
        
        $dir = BBP_PATTERNS_DIR . 'default/';
        $patterns = array_diff(scandir($dir), $this->ignore_array);
        foreach ($patterns as $pattern) {
            copy($dir . $pattern, BBP_PATTERNS_DIR . $pattern);
        }
    }

    public function deleteCustomPatterns() {
        if (!$this->removeDir(BBP_PATTERNS_DIR . 'products/')) {
            return FALSE;
        } else {
            if (!$this->removeDir(BBP_PATTERNS_DIR . 'categories/')) {
                return FALSE;
            } else {
                if (!$this->removeDir(BBP_PATTERNS_DIR)) {
                    return FALSE;
                }
            }
        }
    }

    protected function removeDir($path) {
        if (file_exists($path) && is_dir($path)) {
            $dirHandle = opendir($path);
            while (FALSE !== ($file = readdir($dirHandle))) {
                if (!in_array($file, $this->ignore_array)) {
                    $tmpPath = $path . '/' . $file;
                    @chmod($tmpPath, 0777);
                    if (is_dir($tmpPath)) {
                        $this->removeDir($tmpPath);
                    } else {
                        if (!unlink($tmpPath)) {
                            return FALSE;
                        }
                    }
                }
            }

            closedir($dirHandle);
        } else {
            return FALSE;
        }
        
        return TRUE;
    }
    
    protected function checkExistsDefaultPattern() {
        $default_pattern = Configuration::get('BBP_DEFAULT_PATTERN');
        if (!file_exists(BBP_PATTERNS_DIR . $default_pattern) && $default_pattern) {
            Configuration::updateValue('BBP_DEFAULT_PATTERN', 'blank');
        }
    }

}
