<?php

require_once(dirname(__FILE__).'/Callbacks.php');

class HookController
{
	public static function parseHook($themeDir, $fileName, $content, $positions)
	{
		$hooks = array('sidebarleft' => 'displayLeftColumn', 'sidebarright' => 'displayRightColumn', 'sidebarfooter' => 'displayFooter', 'sidebartop' => 'displayTop');
		$name = self::getControlName($fileName);
		if (!array_key_exists($name, $hooks)) // we do not parse the control. it's not hook
			return $content;
		$hookName = $hooks[$name];
		if (!array_key_exists($hookName, $positions['current'])) {// there is no position for the hook. it's empty
			return "<!-- Hook $hookName has empty positions -->";
		}

		$modules = $positions['current'][$hookName]; // Designer positions in the hook
		$controller = Dispatcher::getInstance()->getController();
		$modulesList = Hook::exec($hookName, $param, null, true); // Prestashop list of modules in the hook
		
		$output = '';
		foreach ($modules as $name)
		{
			if (!array_key_exists($moduleName, $modulesList))
				$output .= "Module $moduleName doesn't exist in moduleList for hook $hookName";//continue;
			/*$blockDataAttr = $name;
			if (file_exists($themeDir . "/modules/$name/$name.tpl"))
			{
				$output .= <<< EOT
\r\n{assign var=blockDataAttr value='$blockDataAttr'}\n
{include file="{\$tpl_dir}./modules/$name/$name.tpl" blockId=\$blockId blockDataAttr=\$blockDataAttr blockDataRequirePosAttr=''}
EOT;
			}
			elseif (file_exists(_PS_MODULE_DIR_ . "$name/$name.tpl"))
			{
				$output .= <<< EOT
\r\n{include file="{\$modules_dir}./$name/$name.tpl"}
EOT;
			}*/
			//$output .= $modulesList[$moduleName];
		}
		
		
		
		$pattern = '~(\{assign var=hookName value=[\'"])(.*?)([\'"])([^\}]*)(\})~';
		$result = preg_replace($pattern, $output, $content);
		return $result;
	}
	
	/*
	 * Gets control name from file without '_' and extension
	 */
	private static function getControlName($fileName)
	{
		$pattern = '~(.*?)(_)(.*?)(.tpl)~';
		$result = preg_replace($pattern, '$1', $fileName);
		return $result;
	}

	public static function parseFooter($themeDir, $content)
	{
		$hook_name = 'displayFooter';
		//TODO: use names dynamically
		$hook_list = array('footerPosition1', 'footerPosition2', 'footerPosition3', 'footerPosition4');
		
		$module_list = HookController::getHookModuleExecList($hook_name);
		HookController::registerHookModule($module_list, $hook_list);
		
		$pattern = '~(\{include file=[\'"])(.*?)(includes/layoutposition)(.*?)([\'"])([^\}]*)(\})~';//TODO: '~(<footer)(.*?)(\{include file=[\'"])(.*?)(layoutposition)(.*?)([\'"])([^\}]*)(\})(.*?)(<\/footer>)~';
		$callback = new HookCallback($themeDir, $hook_list);
		$result = preg_replace_callback($pattern, array($callback, 'replace'), $content);
		
		return $result;	
	}
	
	public static function getHookModuleExecList($hook_name)
	{
		if (!Validate::isHookName($hook_name) || !$module_list = Hook::getHookModuleExecList($hook_name))
			return null;
		return $module_list;
	}
	
	public static function registerHookModule($module_list, $hook_list)
	{
		if (!isset($module_list))
			return;
		
		$context = Context::getContext();
		HookController::clearHookListPositions($hook_list);

		$index = 0;
		$return = true;
		foreach ($module_list as $array)
		{
			if (!($moduleInstance = Module::getInstanceByName($array['module'])))
				continue;
			$exceptions = $moduleInstance->getExceptions($array['id_hook']);
			if (in_array(Dispatcher::getInstance()->getController(), $exceptions))
				continue;
			if (Validate::isLoadedObject($context->employee) && !$moduleInstance->getPermission('view', $context->employee))
				continue;
				
			$name = $moduleInstance->name;
			if (Module::preCall($moduleInstance->name))
			{
				$hook_name = $hook_list[$index % 4];
				$index++;
				$return &= HookController::registerHook($hook_name, $moduleInstance->id);
			}
		}
		
		return $return;
	}
	
	/*
	 * Clears all footer positions
	 */
	public static function clearHookListPositions($hook_list)
	{
		if (!isset($hook_list))
			return;
		
		foreach ($hook_list as $hook_name)
		{
			// Check if hook exists
			if (!$id_hook = Hook::getIdByName($hook_name))
				continue;
			$sql = 'DELETE FROM `'._DB_PREFIX_.'hook_module` WHERE id_hook = '.(int)$id_hook;
			Db::getInstance()->execute($sql);
		}
	}
	
	/**
     * @@param string $content
     */
	public static function parseHookOutput($themeDir, $hook_name, $hook_list)
	{
		$context = Context::getContext();
		$output = '';
		
		if (!Validate::isHookName($hook_name) || !$module_list = Hook::getHookModuleExecList($hook_name))
			return null;
		
		$id_hook = Hook::getIdByName($hook_name);
		$dataRequirePosAttr = implode(';', $hook_list);

		foreach ($module_list as $array)
		{
			if (!($moduleInstance = Module::getInstanceByName($array['module'])))
				continue;
			$exceptions = $moduleInstance->getExceptions($array['id_hook']);
			if (in_array(Dispatcher::getInstance()->getController(), $exceptions))
				continue;
			if (Validate::isLoadedObject($context->employee) && !$moduleInstance->getPermission('view', $context->employee))
				continue;
			$name = $moduleInstance->name;
			if (Module::preCall($name))
			{	
				$blockDataAttr = 'hook_'.$id_hook.'_module_'.$moduleInstance->id.'_moduleName_'.$name;
				if ($name === 'blocklayered') // blocklayered template for footer
				{
					$output .= <<< EOT
\r\n{if \$page_name eq 'category'}
{literal}
	<script type="text/javascript">
		//<![CDATA[
		\$(document).ready(function()
		{
			\$('#selectPrductSort').unbind('change').bind('change', function()
			{
				reloadContent();
			})
		});
		//]]>
	</script>
{/literal}
{/if}
EOT;
				}
				elseif (file_exists($themeDir . "/modules/$name/$name.tpl"))
				{
					$output .= <<< EOT
\r\n{assign var=blockDataAttr value='$blockDataAttr'}\n{assign var=blockDataRequirePosAttr value='$dataRequirePosAttr'}\n
{include file="{\$tpl_dir}./modules/$name/$name.tpl" blockId=\$blockId blockDataAttr=\$blockDataAttr blockDataRequirePosAttr=\$blockDataRequirePosAttr}
EOT;
				}
				elseif (file_exists(_PS_MODULE_DIR_ . "$name/$name.tpl"))
				{
					$output .= <<< EOT
\r\n{include file="{\$modules_dir}./$name/$name.tpl"}
EOT;
				}
			}
		}
		
		return $output;
	}
	
	/**
	 * Gets HOOK from control file content
	 */
	public static function getHookFromControl($themeDir, $content, $controlToParce)
	{
		$pattern = '~(\{include file=[\'"])(.*?)(includes/' . $controlToParce . ')(.*?)([\'"])([^\}]*)(\})~';
		$callback = new Callback($themeDir);
		$result = preg_replace_callback($pattern, array($callback, 'replace'), $content);
		return $result;
	}
	
	/**
	 * Add data-position attribute to <div> with hook
	 */
	private function _addDataPositionAttribute($content, $hookName, $positionName)
	{
		$result = preg_replace("~(<div)([^>]*)(>)($hookName</div>)~", "$1 data-position=\"$positionName\"$2$3$4", $content);
		return $result;
	}
}
