/**
  * Returns the next context menu level
  *
  * @param array $actions
  * @param t3lib_tree_Node $node
  * @param int $level
  * @return t3lib_contextmenu_ActionCollection
  */
 protected function getNextContextMenuLevel(array $actions, t3lib_tree_Node $node, $level = 0)
 {
     /** @var $actionCollection t3lib_contextmenu_ActionCollection */
     $actionCollection = t3lib_div::makeInstance('t3lib_contextmenu_ActionCollection');
     if ($level > 5) {
         return $actionCollection;
     }
     $type = '';
     foreach ($actions as $index => $actionConfiguration) {
         if (substr($index, -1) !== '.') {
             $type = $actionConfiguration;
             if ($type !== 'DIVIDER') {
                 continue;
             }
         }
         if (!in_array($type, array('DIVIDER', 'SUBMENU', 'ITEM'))) {
             continue;
         }
         /** @var $action t3lib_contextmenu_Action */
         $action = t3lib_div::makeInstance('t3lib_contextmenu_Action');
         $action->setId($index);
         if ($type === 'DIVIDER') {
             $action->setType('divider');
         } else {
             if (in_array($actionConfiguration['name'], $this->disableItems) || isset($actionConfiguration['displayCondition']) && trim($actionConfiguration['displayCondition']) !== '' && !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])) {
                 unset($action);
                 continue;
             }
             $label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
             if ($type === 'SUBMENU') {
                 $action->setType('submenu');
                 $action->setChildActions($this->getNextContextMenuLevel($actionConfiguration, $node, $level + 1));
             } else {
                 $action->setType('action');
                 $action->setCallbackAction($actionConfiguration['callbackAction']);
                 if (is_array($actionConfiguration['customAttributes.'])) {
                     $action->setCustomAttributes($actionConfiguration['customAttributes.']);
                 }
             }
             $action->setLabel($label);
             if (isset($actionConfiguration['icon']) && trim($actionConfiguration['icon']) !== '') {
                 $action->setIcon($actionConfiguration['icon']);
             } elseif (isset($actionConfiguration['spriteIcon'])) {
                 $action->setClass(t3lib_iconWorks::getSpriteIconClasses($actionConfiguration['spriteIcon']));
             }
         }
         $actionCollection->offsetSet($level . intval($index), $action);
         $actionCollection->ksort();
     }
     return $actionCollection;
 }
    /**
     * Constructor function for script class.
     *
     * @return	void
     */
    function init()
    {
        global $BE_USER, $BACK_PATH;
        // Setting GPvars:
        $this->backPath = t3lib_div::_GP('backPath');
        $this->item = t3lib_div::_GP('item');
        $this->reloadListFrame = t3lib_div::_GP('reloadListFrame');
        // Setting pseudo module name
        $this->MCONF['name'] = 'xMOD_alt_clickmenu.php';
        // Takes the backPath as a parameter BUT since we are worried about someone forging a backPath (XSS security hole) we will check with sent md5 hash:
        $inputBP = explode('|', $this->backPath);
        if (count($inputBP) == 2 && $inputBP[1] == t3lib_div::shortMD5($inputBP[0] . '|' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
            $this->backPath = $inputBP[0];
        } else {
            $this->backPath = $BACK_PATH;
        }
        // Setting internal array of classes for extending the clickmenu:
        $this->extClassArray = $GLOBALS['TBE_MODULES_EXT']['xMOD_alt_clickmenu']['extendCMclasses'];
        // Traversing that array and setting files for inclusion:
        if (is_array($this->extClassArray)) {
            foreach ($this->extClassArray as $extClassConf) {
                if ($extClassConf['path']) {
                    $this->include_once[] = $extClassConf['path'];
                }
            }
        }
        // Initialize template object
        if (!$this->ajax) {
            $this->doc = t3lib_div::makeInstance('template');
            $this->doc->backPath = $BACK_PATH;
        }
        // Setting mode for display and background image in the top frame
        $this->dontDisplayTopFrameCM = $this->doc->isCMlayers() && !$BE_USER->getTSConfigVal('options.contextMenu.options.alwaysShowClickMenuInTopFrame');
        if ($this->dontDisplayTopFrameCM) {
            $this->doc->bodyTagId .= '-notop';
        }
        // Setting clickmenu timeout
        $secs = t3lib_div::intInRange($BE_USER->getTSConfigVal('options.contextMenu.options.clickMenuTimeOut'), 1, 100, 5);
        // default is 5
        // Setting the JavaScript controlling the timer on the page
        $listFrameDoc = $this->reloadListFrame != 2 ? 'top.content.list_frame' : 'top.content';
        $this->doc->JScode .= $this->doc->wrapScriptTags('
	var date = new Date();
	var mo_timeout = Math.floor(date.getTime()/1000);

	roImg = "' . t3lib_iconWorks::getSpriteIconClasses('status-status-current') . '";

	routImg = "t3-icon-empty";

	function mo(c)	{	//
		var name="roimg_"+c;
		document.getElementById(name).className = roImg;
		updateTime();
	}
	function mout(c)	{	//
		var name="roimg_"+c;
		document[name].src = routImg;
		updateTime();
	}
	function updateTime()	{	//
		date = new Date();
		mo_timeout = Math.floor(date.getTime()/1000);
	}
	function timeout_func()	{	//
		date = new Date();
		if (Math.floor(date.getTime()/1000)-mo_timeout > ' . $secs . ')	{
			hideCM();
			return false;
		} else {
			window.setTimeout("timeout_func();",1*1000);
		}
	}
	function hideCM()	{	//
		window.location.href="alt_topmenu_dummy.php";
		return false;
	}

		// Start timer
	timeout_func();

	' . ($this->reloadListFrame ? '
		// Reload list frame:
	if(' . $listFrameDoc . '){' . $listFrameDoc . '.location.href=' . $listFrameDoc . '.location.href;}' : '') . '
		');
    }
    /**
     * renders the tree as replacement for the selector
     *
     * @param string The table name of the record
     * @param string The field name which this element is supposed to edit
     * @param array The record data array where the value(s) for the field can be found
     * @param array An array with additional configuration options.
     * @param array (Redundant) content of $PA['fieldConf']['config'] (for convenience)
     * @param array Items available for selection
     * @param string Label for no-matching-value
     * @return string The HTML code for the TCEform field
     */
    public function renderField($table, $field, $row, &$PA, $config, $possibleSelectboxItems, $noMatchLabel)
    {
        $valueArray = explode(',', $PA['itemFormElValue']);
        $selectedNodes = array();
        if (count($valueArray)) {
            foreach ($valueArray as $selectedValue) {
                $temp = explode('|', $selectedValue);
                $selectedNodes[] = $temp[0];
            }
        }
        $allowedUids = array();
        foreach ($possibleSelectboxItems as $item) {
            if (intval($item[1]) > 0) {
                $allowedUids[] = $item[1];
            }
        }
        $treeDataProvider = t3lib_tree_Tca_DataProviderFactory::getDataProvider($config, $table, $field, $row);
        $treeDataProvider->setSelectedList(implode(',', $selectedNodes));
        $treeDataProvider->setItemWhiteList($allowedUids);
        $treeDataProvider->initializeTreeData();
        $treeRenderer = t3lib_div::makeInstance('t3lib_tree_Tca_ExtJsArrayRenderer');
        $tree = t3lib_div::makeInstance('t3lib_tree_Tca_TcaTree');
        $tree->setDataProvider($treeDataProvider);
        $tree->setNodeRenderer($treeRenderer);
        $treeData = $tree->render();
        $itemArray = array();
        if (is_array($PA['fieldConf']['config']['items'])) {
            foreach ($PA['fieldConf']['config']['items'] as $additionalItem) {
                if ($additionalItem[1] !== '--div--') {
                    $item = new stdClass();
                    $item->uid = $additionalItem[1];
                    $item->text = $GLOBALS['LANG']->sL($additionalItem[0]);
                    $item->selectable = TRUE;
                    $item->leaf = TRUE;
                    $item->checked = in_array($additionalItem[1], $selectedNodes);
                    if (file_exists(PATH_typo3 . $additionalItem[3])) {
                        $item->icon = $additionalItem[3];
                    } elseif (strlen(trim($additionalItem[3]))) {
                        $item->iconCls = t3lib_iconWorks::getSpriteIconClasses($additionalItem[3]);
                    }
                    $itemArray[] = $item;
                }
            }
        }
        $itemArray[] = $treeData;
        $treeData = json_encode($itemArray);
        $id = md5($PA['itemFormElName']);
        if (isset($PA['fieldConf']['config']['size']) && intval($PA['fieldConf']['config']['size']) > 0) {
            $height = intval($PA['fieldConf']['config']['size']) * 20;
        } else {
            $height = 280;
        }
        if (isset($PA['fieldConf']['config']['autoSizeMax']) && intval($PA['fieldConf']['config']['autoSizeMax']) > 0) {
            $autoSizeMax = intval($PA['fieldConf']['config']['autoSizeMax']) * 20;
        }
        $header = FALSE;
        $expanded = FALSE;
        $appearance = $PA['fieldConf']['config']['treeConfig']['appearance'];
        if (is_array($appearance)) {
            $header = $appearance['showHeader'] ? TRUE : FALSE;
            $expanded = $appearance['expandAll'] === TRUE;
        }
        $onChange = '';
        if ($PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged']) {
            $onChange = substr($PA['fieldChangeFunc']['TBE_EDITOR_fieldChanged'], 0, -1);
        }
        /** @var $pageRenderer t3lib_PageRenderer */
        $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
        $pageRenderer->loadExtJs();
        $pageRenderer->addJsFile('../t3lib/js/extjs/tree/tree.js');
        $pageRenderer->addExtOnReadyCode('
			TYPO3.Components.Tree.StandardTreeItemData["' . $id . '"] = ' . $treeData . ';
			var tree' . $id . ' = new TYPO3.Components.Tree.StandardTree({
				id: "' . $id . '",
				showHeader: ' . intval($header) . ',
				onChange: "' . $onChange . '",
				countSelectedNodes: ' . count($selectedNodes) . ',
				listeners: {
					click: function(node, event) {
						if (typeof(node.attributes.checked) == "boolean") {
							node.attributes.checked = ! node.attributes.checked;
							node.getUI().toggleCheck(node.attributes.checked);
						}
					},
					dblclick: function(node, event) {
						if (typeof(node.attributes.checked) == "boolean") {
							node.attributes.checked = ! node.attributes.checked;
							node.getUI().toggleCheck(node.attributes.checked);
						}
					},
					checkchange: TYPO3.Components.Tree.TcaCheckChangeHandler,
					collapsenode: function(node) {
						top.TYPO3.BackendUserSettings.ExtDirect.removeFromList("tcaTrees." + this.ucId, node.attributes.uid);
					},
					expandnode: function(node) {
						top.TYPO3.BackendUserSettings.ExtDirect.addToList("tcaTrees." + this.ucId, node.attributes.uid);
					}
				},
				tcaMaxItems: ' . ($PA['fieldConf']['config']['maxitems'] ? intval($PA['fieldConf']['config']['maxitems']) : 99999) . ',
				tcaExclusiveKeys: "' . ($PA['fieldConf']['config']['exclusiveKeys'] ? $PA['fieldConf']['config']['exclusiveKeys'] : '') . '",
				ucId: "' . md5($table . '|' . $field) . '",
				selModel: TYPO3.Components.Tree.EmptySelectionModel
			});' . LF . ($autoSizeMax ? 'tree' . $id . '.bodyStyle = "max-height: ' . $autoSizeMax . 'px;min-height: ' . $height . 'px;";' : 'tree' . $id . '.height = ' . $height . ';') . LF . 'tree' . $id . '.render("tree_' . $id . '");' . ($expanded ? 'tree' . $id . '.expandAll();' : '') . '
		');
        $formField = '
			<div class="typo3-tceforms-tree">
				<input type="hidden" name="' . htmlspecialchars($PA['itemFormElName']) . '" id="treeinput' . $id . '" value="' . htmlspecialchars($PA['itemFormElValue']) . '" />
			</div>
			<div id="tree_' . $id . '">

			</div>';
        return $formField;
    }
 /**
  * Returns the language labels, sprites and configuration options for the pagetree
  *
  * @return void
  */
 public function loadResources()
 {
     $file = 'LLL:EXT:lang/locallang_core.xml:';
     $indicators = $this->getIndicators();
     $configuration = array('LLL' => array('copyHint' => $GLOBALS['LANG']->sL($file . 'tree.copyHint', TRUE), 'fakeNodeHint' => $GLOBALS['LANG']->sL($file . 'mess.please_wait', TRUE), 'activeFilterMode' => $GLOBALS['LANG']->sL($file . 'tree.activeFilterMode', TRUE), 'dropToRemove' => $GLOBALS['LANG']->sL($file . 'tree.dropToRemove', TRUE), 'buttonRefresh' => $GLOBALS['LANG']->sL($file . 'labels.refresh', TRUE), 'buttonNewNode' => $GLOBALS['LANG']->sL($file . 'tree.buttonNewNode', TRUE), 'buttonFilter' => $GLOBALS['LANG']->sL($file . 'tree.buttonFilter', TRUE), 'dropZoneElementRemoved' => $GLOBALS['LANG']->sL($file . 'tree.dropZoneElementRemoved', TRUE), 'dropZoneElementRestored' => $GLOBALS['LANG']->sL($file . 'tree.dropZoneElementRestored', TRUE), 'searchTermInfo' => $GLOBALS['LANG']->sL($file . 'tree.searchTermInfo', TRUE), 'temporaryMountPointIndicatorInfo' => $GLOBALS['LANG']->sl($file . 'labels.temporaryDBmount', TRUE), 'deleteDialogTitle' => $GLOBALS['LANG']->sL('LLL:EXT:cms/layout/locallang.xml:deleteItem', TRUE), 'deleteDialogMessage' => $GLOBALS['LANG']->sL('LLL:EXT:cms/layout/locallang.xml:deleteWarning', TRUE), 'recursiveDeleteDialogMessage' => $GLOBALS['LANG']->sL('LLL:EXT:cms/layout/locallang.xml:recursiveDeleteWarning', TRUE)), 'Configuration' => array('hideFilter' => $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.hideFilter'), 'displayDeleteConfirmation' => $GLOBALS['BE_USER']->jsConfirmation(4), 'canDeleteRecursivly' => $GLOBALS['BE_USER']->uc['recursiveDelete'] == TRUE, 'disableIconLinkToContextmenu' => $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.disableIconLinkToContextmenu'), 'indicator' => $indicators['html'], 'temporaryMountPoint' => t3lib_tree_pagetree_Commands::getMountPointPath()), 'Sprites' => array('Filter' => t3lib_iconWorks::getSpriteIconClasses('actions-system-tree-search-open'), 'NewNode' => t3lib_iconWorks::getSpriteIconClasses('actions-page-new'), 'Refresh' => t3lib_iconWorks::getSpriteIconClasses('actions-system-refresh'), 'InputClear' => t3lib_iconWorks::getSpriteIconClasses('actions-input-clear'), 'TrashCan' => t3lib_iconWorks::getSpriteIconClasses('actions-edit-delete'), 'TrashCanRestore' => t3lib_iconWorks::getSpriteIconClasses('actions-edit-restore'), 'Info' => t3lib_iconWorks::getSpriteIconClasses('actions-document-info')));
     return $configuration;
 }