<?php
if (!defined('_PS_VERSION_')) exit;



if (phpversion() <= "5.4") {
	echo "<b>Error:</b> CraftShirt Online Product Designer module<br /><b>Module requires PHP 5.4 or higher version.</b><br><hr><br>";
} else {


	require_once __DIR__ . '/require.php';
	/**
	 * Class Styleswiss
	 * @property Context $context
	 */

	class MySwissStyle extends Module
	{

		private static $config = null;

		private static $cms = null;

		public function __construct()
		{
			if (self::$config == null) {
				self::$config = SwissStyle\Glob\Controller\Glob::getConfig();
			}

			if (self::$cms == null) {
				self::$cms = \SwissStyle\CMS\Controller\CMS::init()->prestashop;
			}

			if (self::$config->core->dev_mode == true) {
				error_reporting(E_ERROR);
				ini_set('display_errors', 1);
			}

			$this->name = self::$config->meta->name;
			$this->tab = self::$config->meta->tab;
			$this->version = self::$config->meta->version;
			$this->author = self::$config->meta->author;
			$this->need_instance = self::$config->meta->need_instance;
			$this->module_key = '';
			$this->ps_versions_compliancy = array(
				'min' => self::$config->meta->ps_versions_compliancy_min,
				'max' => self::$config->meta->ps_versions_compliancy_max ?: _PS_VERSION_
			);

			$this->dependencies = array('blockcart'); // the module needs another module

			parent::__construct();

			/*
			if (
				$this->id
				&&
				self::$cms->getParam('SWISSSTYLE_SHOP_ID') == ''
			) {
				$this->warning = $this->l(self::$config->meta->warning_not_provided_id);
			}
			/**/

			$this->displayName = $this->l(self::$config->meta->displayName);
			$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
			$this->description = $this->l(self::$config->meta->displayName);


			if (!self::$cms->getParam('SWISSSTYLE'))
				$this->warning = $this->l(self::$config->meta->warning_not_name_provided_id);

		}


		/* Install and uninstall */

		public function install()
		{
			if (Shop::isFeatureActive())
				Shop::setContext(Shop::CONTEXT_ALL);

			self::$cms->setParam('SWISSSTYLE', 'StyleSwiss Module');
			self::$cms->setParam('SWISSSTYLE_DB_VERSION', '0');

			self::$cms->initDB();

			SwissStyle\DB\Controller\DB::updateDB();

			if (
				$this->adminInstall() && parent::install() && $this->registerHooks()
			) {
				$this->createModuleCatalogues();
				return true;
			}
			return false;
		}

		public function __call($method, $args)
		{

			switch (true) {
				case preg_match('!^hook(.+)!', $method):
					$hooks = SwissStyle\Hook\Controller\Hook::getAvailableHooks();

					$hook_name = str_replace('hook', '', $method);
					$hook_name[0] = strtolower($hook_name[0]);

					if (in_array($hook_name, $hooks)) {
						return SwissStyle\Hook\Controller\Hook::fire($hook_name, $args);
					} else {
						throw new \Exception(sprintf('The required method "%s" does not exist for %s', $method, __CLASS__));
					}
					break;

				case method_exists($this, $method):
					return call_user_func_array(array($this, $method), $args);
					break;

				default:
					throw new \Exception(sprintf('The required method "%s" does not exist for %s', $method, __CLASS__));
			}
		}

		public function uninstall()
		{

			self::$cms->clearDB();

			if (!parent::uninstall() ||
				!self::$cms->deleteParam('SWISSSTYLE_LICENSE_KEY') ||
				!self::$cms->deleteParam('SWISSSTYLE_DB_VERSION') ||
				!self::$cms->deleteParam('SWISSSTYLE_ACCOUNT_NAME') ||
				!self::$cms->deleteParam('STYLESWISS_CURRENT_DB_VERSION') ||
				!self::$cms->deleteParam('SWISSSTYLE')
			) {
				return false;
			}
			$this->adminUninstall();
			return true;
		}

		private function adminInstall()
		{
			$this->addAdminTab('AdminDesignCategories', $this->l('Clipart Categories'), 9);
			$this->addAdminTab('AdminDesigns', $this->l('Cliparts'), 9);
			return true;
		}

		private function createModuleCatalogues()
		{
			$builder_config = self::$config->builder;

			if (file_exists($builder_config->clipart_original_path) === false) {
				@mkdir($builder_config->clipart_original_path, 0777, true);
			}

			if (file_exists($builder_config->clipart_thumb_path) === false) {
				@mkdir($builder_config->clipart_thumb_path, 0777, true);
			}

			if (file_exists($builder_config->clipart_fs_cache_path) === false) {
				@mkdir($builder_config->clipart_fs_cache_path, 0777, true);
			}

			if (file_exists($builder_config->preview_path) === false) {
				@mkdir($builder_config->preview_path, 0777, true);
			}

			if (file_exists($builder_config->print_out_path) === false) {
				@mkdir($builder_config->print_out_path, 0777, true);
			}

			if (file_exists($builder_config->print_out_archive_path) === false) {
				@mkdir($builder_config->print_out_archive_path, 0777, true);
			}

			if (file_exists($builder_config->pdf_cache_path) === false) {
				@mkdir($builder_config->pdf_cache_path, 0777, true);
			}

			if (file_exists($builder_config->upload_cache_path) === false) {
				@mkdir($builder_config->upload_cache_path, 0777, true);
			}

			if (file_exists($builder_config->image_generation_cache_path) === false) {
				@mkdir($builder_config->image_generation_cache_path, 0777, true);
			}
		}

		private function addAdminTab($class_name, $title, $parent_id = 0)
		{
			$tab = new Tab();
			$tab->active = 1;
			$tab->class_name = $class_name;
			$tab->module = $this->name;
			$tab->id_parent = $parent_id;
			$languages = Language::getLanguages(true);
			foreach ($languages as $lang)
				$tab->name[$lang['id_lang']] = $title;
			$tab->add();
			//			$res &= $tab->save();
			//			$tab->name[(int)(self::$cms->getParam('PS_LANG_DEFAULT'))] = $this->l('Designs');
		}

		private function adminUninstall()
		{
			$tab = new Tab(Tab::getIdFromClassName('AdminDesigns'));
			$tab->delete();
			$tab = new Tab(Tab::getIdFromClassName('AdminDesignCategories'));
			$tab->delete();
		}

		protected function registerHooks()
		{
			$hooks = SwissStyle\Hook\Controller\Hook::getAvailableHooks();
			foreach ($hooks as $hook) {
				if (!$this->registerHook($hook)) {
					return false;
				}
			}
			return true;
		}


		/* Admin page*/

		public function getContent()
		{
			$output = null;

			if (Tools::isSubmit('submit' . $this->name)) {
				$my_module_name = strval(Tools::getValue('SWISSSTYLE_LICENSE_KEY'));
				if (!$my_module_name || empty($my_module_name) || !Validate::isGenericName($my_module_name))
					$output .= $this->displayError($this->l('Invalid Configuration value'));
				else {
					Configuration::updateValue('SWISSSTYLE_LICENSE_KEY', $my_module_name);

					if (isset($_REQUEST['pp_saver']) && $_REQUEST['pp_saver'] == true) {
						if (!isset($_REQUEST['on_payment_method']) || $_REQUEST['on_payment_method'] == false) {
							$_REQUEST['on_payment_method'] = '0';
						}

						\SwissStyle\CMS\Controller\CMS::init()->saveDefaultPaymentMethod($_REQUEST['on_payment_method']);

						if (isset($_REQUEST['pp_settings']) && !empty($_REQUEST['pp_settings'])) {
							SwissStyle\Payment\Controller\Payment::saveGroupPPConfigs($_REQUEST['pp_settings']);
						}
					}

					$output .= $this->displayConfirmation($this->l('Settings updated'));
				}
			}
			return $output . $this->displayForm();
		}

		public function displayForm()
		{
			// Get default Language
			$default_lang = (int)Configuration::get('PS_LANG_DEFAULT');

			// Init Fields form array
			$fields_form[0]['form'] = array(
				'legend' => array(
					'title' => $this->l('Settings'),
				),
				'input' => array(
					array(
						'type' => 'text',
						'label' => $this->l('License key'),
						'name' => 'SWISSSTYLE_LICENSE_KEY',
						'size' => 20,
						'required' => true,
						'placeholder' => ''
					),
					array(
						'type' => 'html',
						'label' => $this->l('License status'),
						'name' => 'SWISSSTYLE_ACCOUNT_NAME',
						'html_content' => SwissStyle\Viewer\Controller\Viewer::renderBlock('adminModuleLicenseStatus', [])
					)
				),
				'submit' => array(
					'title' => $this->l('Save'),
					'class' => 'button'
				)
			);

			$fields_form[1]['form'] = array(
				'legend' => array(
					'title' => $this->l('Payment'),
				),
				'input' => array(
					array(
						'type' => 'html',
						'label' => $this->l('Type'),
						'name' => 'SWISSSTYLE_PAYMENT_SETTINGS',
						'html_content' => SwissStyle\Viewer\Controller\Viewer::renderBlock(
							'adminPaymentSettings',
							['selected' => SwissStyle\CMS\Controller\CMS::init()->getDefaultPaymentMethod()]
						)
					)
				),
				'submit' => array(
					'id' => 'save_payment_settings',
					'title' => $this->l('Save'),
					'class' => 'button'
				)
			);

			$fields_form[2]['form'] = array(
				'legend' => array(
					'title' => $this->l('Tools'),
				),
				'input' => array(
					array(
						'type' => 'html',
						'label' => $this->l('Database'),
						'name' => 'SWISSSTYLE_ACCOUNT_NAME',
						'html_content' => SwissStyle\Viewer\Controller\Viewer::renderBlock('adminModuleDBTools', [])
					)
				)
			);

			$helper = new HelperForm();

			// Module, t    oken and currentIndex
			$helper->module = $this;
			$helper->name_controller = $this->name;
			$helper->token = Tools::getAdminTokenLite('AdminModules');
			$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;

			// Language
			$helper->default_form_language = $default_lang;
			$helper->allow_employee_form_lang = $default_lang;

			// Title and toolbar
			$helper->title = $this->displayName;
			$helper->show_toolbar = true;        // false -> remove toolbar
			$helper->toolbar_scroll = true;      // yes - > Toolbar is always visible on the top of the screen.
			$helper->submit_action = 'submit' . $this->name;
			$helper->toolbar_btn = array(
				'save' =>
					array(
						'desc' => $this->l('Save'),
						'href' => AdminController::$currentIndex . '&configure=' . $this->name . '&save' . $this->name .
							'&token=' . Tools::getAdminTokenLite('AdminModules'),
					),
				'back' => array(
					'href' => AdminController::$currentIndex . '&token=' . Tools::getAdminTokenLite('AdminModules'),
					'desc' => $this->l('Back to list')
				)
			);

			// Load current value
			$helper->fields_value['SWISSSTYLE_LICENSE_KEY'] = Configuration::get('SWISSSTYLE_LICENSE_KEY');

			return $helper->generateForm($fields_form);
		}


		/* Hooks */
		public function oldhookDisplayAdminOrder($params)
		{
			$order_id = $params['id_order'];
			$cart = $params['cart'];

			$designs = Styleswiss::Tools()->getDesignFromOrder($order_id);

			if (!empty($designs)) {

				$Products = array();
				$preview = ImageGeneration::singletone()->Preview();

				foreach ($cart->getProducts() as $product) {
					if (isset($designs[$product['id_product']])) {

						$previews = $preview->getPreview($product['id_product'], $designs[$product['id_product']]);

						$Products[] = array(
							'id' => $product['id_product'],
							'name' => $product['name'],
							'previews' => $previews
						);
					}
				}

				$this->context->smarty->assign(
					array(
						'products' => $Products
					)
				);

				return $this->display(__FILE__, 'admin_designs_details.tpl');
			}
		}

		public function oldhookActionCartSave($params)
		{
			/**
			 * @var CartCore $cart ;
			 */
			$cart = $params['cart'];
			$designs = self::Tools()->getDesignFromCart($cart->id);
			$product_id = (int)$_REQUEST['id_product'];

			if (isset($designs[$product_id])) {
				DesignsCollection::setStatusForDesignId($designs[$product_id], DesignsCollection::STATUS_DESIGN_CONFIRMED);
			}
		}

		public function oldhookActionValidateOrder($params)
		{
			/**
			 * @var CartCore $cart
			 * @var OrderCore $order
			 */
			$cart = $params['cart'];
			$order = $params['order'];

			$designs = Styleswiss::Tools()->getDesignFromCart($cart->id);

			foreach ($cart->getProducts() as $product) {
				if (isset($designs[$product['id_product']])) {
					DesignsCollection::setStatusForDesignId($designs[$product['id_product']], DesignsCollection::STATUS_DESIGN_BOOKED);
					Styleswiss::Tools()->addDesignToProductOrder($order->id, $product['id_product'], $designs[$product['id_product']]);
				}
			}
		}

		public function oldhookDisplayFooterProduct($params)
		{
			/**
			 * @var CartCore $cart
			 */

			$cart = $params['cart'];
			$product = $params['product'];

			$designs = Styleswiss::Tools()->getDesignFromCart($cart->id);

			if (isset($designs[$product->id])) {
				$preview_controller = ImageGeneration::singletone()->Preview();
				$previews = $preview_controller->getPreview($product->id, $designs[$product->id]);

				$this->context->smarty->assign(
					array(
						'previews' => $previews
					)
				);
			} else {
				$this->context->smarty->assign(
					array(
						'hide' => true
					)
				);
			}
			return $this->display(__FILE__, 'product_info_previews.tpl');
		}

		public function oldhookDisplayShoppingCartFooter($params)
		{
			/**
			 * @var CartCore $cart
			 */
			$cart = $params['cart'];
			$designs = self::Tools()->getDesignFromCart($cart->id);

			if (!empty($designs)) {
				$products_cart = $cart->getProducts();
				$products_grouped = array();
				foreach ($products_cart as $product_cart) {
					$products_grouped[$product_cart['id_product']] = $product_cart;
				}

				$preview_controller = ImageGeneration::singletone()->Preview();
				$products_preview = array();
				foreach ($designs as $product_id => $builder_id) {
					if ($products_grouped[$product_id]['name']) {
						$previews = $preview_controller->getPreview($product_id, $builder_id);
						$products_preview[] = array(
							'name' => $products_grouped[$product_id]['name'],
							'previews' => $previews
						);
					}
				}

				$this->context->smarty->assign(
					array(
						'products_preview' => $products_preview
					)
				);

				return $this->display(__FILE__, 'shopping_cart.tpl');
			}
			return '';
		}

		public function oldhookDisplayOrderDetail($params)
		{
			/**
			 * @var CartCore $cart
			 */
			$cart = new Cart($params['order']->id_cart);
			$designs = self::Tools()->getDesignFromCart($cart->id);

			if (!empty($designs)) {
				$products_cart = $cart->getProducts();
				$products_grouped = array();
				foreach ($products_cart as $product_cart) {
					$products_grouped[$product_cart['id_product']] = $product_cart;
				}

				$preview_controller = ImageGeneration::singletone()->Preview();
				$products_preview = array();
				foreach ($designs as $product_id => $builder_id) {
					if ($products_grouped[$product_id]['name']) {
						$previews = $preview_controller->getPreview($product_id, $builder_id);
						$products_preview[] = array(
							'name' => $products_grouped[$product_id]['name'],
							'previews' => $previews
						);
					}
				}

				$this->context->smarty->assign(
					array(
						'products_preview' => $products_preview
					)
				);

				return $this->display(__FILE__, 'display_order_detail.tpl');
			}
			return '';
		}

		public function oldhookDisplayBackOfficeHeader($params)
		{
			$this->context->controller->addJQuery();
			$this->context->controller->addJQueryUI('ui.draggable');
			$this->context->controller->addJQueryUI('ui.resizable');
		}

		public function oldhookDisplayBackOfficeFooter($params)
		{
			return '';
		}

		/* StyleSwiss Tools */
		public static function Content($class_name, $params = null)
		{
			require_once dirname(__FILE__) . '/classes/' . $class_name . '.php';
			$result_class = false;
			if (($type = call_user_func(array($class_name, 'getType'))) == true && $type == 'singletone') {
				$result_class = call_user_func(array($class_name, 'Create'));
			} else {
				$result_class = new $class_name($params);
			}
			return $result_class;
		}

		public static function Configure()
		{
			$styleswiss = new self;
			return $styleswiss->options;
		}

		public static function Tools()
		{
			return new StyleswissBuilderTools();
		}

		public static function getCartId()
		{
			$styleswiss = new Styleswiss();

			/**
			 * @var CartCore $cart ;
			 */
			return $styleswiss->context->cart->id;
		}

		public static function getDirectoryFiles($path)
		{
			$d = dir($path);
			$files = array();
			if ($d) {
				while (false !== ($name = $d->read())) {
					if ($name === '.' || $name === '..') continue;
					$FullName = $path . "/" . $name;
					if (is_file($FullName)) $files[] = $name;
				}
				$d->close();
			}
			if (empty($files)) return false;
			else return $files;
		}

		protected function array_to_obj($array, &$obj)
		{
			foreach ($array as $key => $value) {
				if (is_array($value)) {
					$obj->$key = new stdClass();
					$this->array_to_obj($value, $obj->$key);
				} else {
					$obj->$key = $value;
				}
			}
			return $obj;
		}

		protected function arrayToObject($array)
		{
			$object = new stdClass();
			return $this->array_to_obj($array, $object);
		}
	}
}