<?php global $action, $area, $frame;

/**
 * Project: 
 * Contenido Content Management System
 * 
 * Description: 
 * Edit modules
 * 
 * Requirements: 
 * @con_php_req 5.0
 * 
 *
 * @package    Contenido Backend includes
 * @version    1.0.2
 * @author     Olaf Niemann
 * @copyright  four for business AG <www.4fb.de>
 * @license    http://www.contenido.org/license/LIZENZ.txt
 * @link       http://www.4fb.de
 * @link       http://www.contenido.org
 * @since      file available since contenido release <= 4.6
 * 
 * {@internal 
 *   created 2003-01-21
 *   modified 2008-06-27, Frederic Schneider, add security fix
 *   modified 2011-02-07, Dominik Ziegler, removed integration of not supported java module editor
 *
 *   $Id$:
 * }}
 * 
 */
// security
if (!defined('CON_FRAMEWORK')) {
    die('Illegal call');
}

cInclude("includes", "functions.upl.php");
cInclude("external", "edit_area/class.edit_area.php");

$noti = "";
$sOptionDebugRows = getEffectiveSetting("modules", "show-debug-rows", "never");

if (!isset($idmod))
    $idmod = 0;

if ($action == "mod_delete") {
    $modules = new cApiModuleCollection;
    $modules->delete($idmod);
    unset($modules);
    $idmod = 0;
}

/** @var Contenido_Perm $perm */
if (($action == "mod_new") && (!$perm->have_perm_area_action_anyitem($area, $action))) {
    /** @var Contenido_Notification $notification */
    $notification->displayNotification("error", i18n("No permission"));
} else {
    if ($action == "mod_new") {
        $modules = new cApiModuleCollection;
        $module = $modules->create(i18n("- Unnamed Module -"));
        $module->set("description", implode("\n", array(i18n("<your module description>"), "", i18n("Author: "), i18n("Version:"))));
        $module->store();
    } else {
        $module = new cApiModule;
        $module->loadByPrimaryKey($idmod);
    }

    if ($action == "mod_importexport_module") {
        /** @var string $mode */
        if ($mode == "export") {
            $name = uplCreateFriendlyName($module->get("name"));

            if ($name != "") {
                $module->export($name . ".xml");
            }
        }
        if ($mode == "import") {
            if (file_exists($_FILES["upload"]["tmp_name"])) {
                if (!$module->import($_FILES["upload"]["tmp_name"])) {
                    $noti .= sprintf(i18n("Error while importing XML file: %s"), $module->getError()) . "<br>";
                } else {
                    // Load the item again (clearing slashes from import)
                    $module->loadByPrimaryKey($module->get($module->primaryKey));
                }
            }
        }
    }
    /** @var Contenido_Notification $notification */
    if ($action == "mod_folder_create") {
        if ($module->createModuleFolder()) {
            $notification->displayNotification("info", i18n("Module folder created"));
            $module->loadByPrimaryKey($module->get($module->primaryKey));
        } else {
            $notification->displayNotification("error", i18n("Error while creating module folder"));
        }
    }

    $idmod = $module->get("idmod");
    //var_dump($module);

    if (!$perm->have_perm_area_action_item("mod_edit", "mod_edit", $idmod)) {
        $link = new cHTMLLink;
        $link->setCLink("mod_translate", 4, "");
        $link->setCustom("idmod", $idmod);

        header("Location: " . $link->getHREF());
    } else {
        $oInUse = new InUseCollection;
        list($bInUse, $message) = $oInUse->checkAndMark("idmod", $idmod, true, i18n("Module is in use by %s (%s)"), true, "main.php?area=$area&frame=$frame&idmod=$idmod");
        unset($oInUse);

        if ($bInUse == true) {
            $message .= "<br>";
            $disabled = 'disabled="disabled"';
        } else {
            $disabled = "";
        }

        $page = new cPage;
        $form = new UI_Table_Form("mod_edit");
        $form->setVar("area", "mod_edit");
        $form->setVar("frame", $frame);
        $form->setVar("idmod", $idmod);

        if (!$bInUse) {
            $form->setVar("action", "mod_edit");
        }
        $form->setWidth("100%");

        $form->addHeader(i18n("Edit module"));
        $name = new cHTMLTextbox("name", $module->get("name"), 60);
        $descr = new cHTMLTextarea("descr", clHtmlSpecialChars($module->get("description")), 100, 5);

        // Get input and output code; if specified, prepare row fields
        $sInputData = clHtmlSpecialChars($module->get("input"));
        $sOutputData = clHtmlSpecialChars($module->get("output"));

        if ($sOptionDebugRows !== "never") {
            $iInputNewLines = substr_count($sInputData, "\n") + 2; // +2: Just sanity, to have at least two more lines than the code
            $iOutputNewLines = substr_count($sOutputData, "\n") + 2; // +2: Just sanity, to have at least two more lines than the code
            // Have at least 15 + 2 lines (15 = code textarea lines count)
            if ($iInputNewLines < 21) {
                $iInputNewLines = 21;
            }
            if ($iOutputNewLines < 21) {
                $iOutputNewLines = 21;
            }

            // Calculate how many characters are needed (e.g. 2 for lines ip to 99)
            $iInputNewLineChars = strlen($iInputNewLines);
            $iOutputNewLineChars = strlen($iOutputNewLines);
            if ($iInputNewLineChars > $iOutputNewLineChars) {
                $iChars = $iInputNewLineChars;
            } else {
                $iChars = $iOutputNewLineChars;
            }
            unset($iInputNewLineChars);
            unset($iOutputNewLineChars);

            $sRows = "";
            for ($i = 1; $i <= $iInputNewLines; $i++) {
                if ($sRows) {
                    $sRows .= "\r\n";
                }
                $sRows .= sprintf("%0" . $iChars . "d", $i);
            }
            $oInputRows = new cHTMLTextarea("txtInputRows", $sRows, $iChars, 20);

            $sRows = "";
            for ($i = 1; $i <= $iOutputNewLines; $i++) {
                if ($sRows) {
                    $sRows .= "\r\n";
                }
                $sRows .= sprintf("%0" . $iChars . "d", $i);
            }
            $oOutputRows = new cHTMLTextarea("txtOutputRows", $sRows, $iChars, 20);

            $oInputRows->updateAttributes(array("wrap" => "off"));
            $oOutputRows->updateAttributes(array("wrap" => "off"));

            $oInputRows->updateAttributes(array("readonly" => "true"));
            $oOutputRows->updateAttributes(array("readonly" => "true"));

            $oInputRows->setStyle("font-family: monospace;");
            $oOutputRows->setStyle("font-family: monospace;");
            $oOutputRows->setStyle("font-family: monospace;");
        }
        $input = new cHTMLTextarea("input", $sInputData, 100, 20, 'input');
        $output = new cHTMLTextarea("output", $sOutputData, 100, 20, 'output');

        // Style the fields
        $input->updateAttributes(array("wrap" => "off"));
        $output->updateAttributes(array("wrap" => "off"));

        $name->setDisabled($disabled);
        $descr->setDisabled($disabled);
        if ($module->isLoadedFromFile("input")) {
            $input->setDisabled('disabled="disabled"');
        } else {
            $input->setDisabled($disabled);
        }
        if ($module->isLoadedFromFile("output")) {
            $output->setDisabled('disabled="disabled"');
        } else {
            $output->setDisabled($disabled);
        }

        $descr->setStyle("width: 100%; font-family: monospace;");
        $input->setStyle("width: 100%; font-family: monospace;");
        $output->setStyle("width: 100%; font-family: monospace;");

        // Check, if tabs may be inserted in text areas (instead jumping to next element)
        if (getEffectiveSetting("modules", "edit-with-tabs", "false") == "true") {
            $sTabScript = '<script type="text/javascript"><!--
/**
* Insert a tab at the current text position in a textarea
* Jan Dittmer, jdittmer@ppp0.net, 2005-05-28
* Inspired by http://www.forum4designers.com/archive22-2004-9-127735.html
* Tested on: 
*   Mozilla Firefox 1.0.3 (Linux)
*   Mozilla 1.7.8 (Linux)
*   Epiphany 1.4.8 (Linux)
*   Internet Explorer 6.0 (Linux)
* Does not work in: 
*   Konqueror (no tab inserted, but focus stays)
* Fix for IE "free focus" problem:
*   Idea from mastercomputers from New Zealand
*   http://www.antilost.com/community/index.php?showtopic=134&pid=1022&st=0&#entry1022
*   integrated by HerrB
*/
function insertTab(event, obj) {
	var tabKeyCode = 9;
    var keycode;

	if (event.which) // mozilla
		keycode = event.which;
	else // ie
		keycode = event.keyCode;

	if (keycode == tabKeyCode) {
		if (event.type == "keydown") {
			if (obj.setSelectionRange) { // mozilla
				var s = obj.selectionStart;
				var e = obj.selectionEnd;
				obj.value = obj.value.substring(0, s) + "\t" + obj.value.substr(e);
				obj.setSelectionRange(s + 1, s + 1);
				obj.focus();
			} else if (obj.createTextRange) { // ie
				document.selection.createRange().text = "\t";
				setTimeout("document.getElementById(\'"+obj.id+"\').focus();",0);
			} else {
				// unsupported browsers
			}
		}
		if (event.returnValue) // ie ?
			event.returnValue = false;
		if (event.preventDefault) // dom
			event.preventDefault();
		return false; // should work in all browsers
	} else {
		return true;
	}
}
//--></script>';
            $page->addScript("tabScript", $sTabScript);

            $input->setEvent("onkeydown", "return insertTab(event,this);");
            $output->setEvent("onkeydown", "return insertTab(event,this);");
        }

        // Prepare type select box
        $typeselect = new cHTMLSelectElement("type");

        $db2 = new DB_ConLite;
        $sql = "SELECT type FROM " . cRegistry::getConfigValue('tab', 'mod') . " " .
                "WHERE idclient = '" . cRegistry::getClientId() . "' GROUP BY type"; // @todo check: This query can't be designed using GenericDB...
        $db2->query($sql);

        $aTypes = array();
        while ($db2->next_record()) {
            if ($db2->f("type") != "") {
                $aTypes[] = $db2->f("type");
            }
        }

        // Read existing layouts
        $oLayouts = new cApiLayoutCollection;
        $oLayouts->setWhere("idclient", cRegistry::getClientId());
        $oLayouts->query();

        while ($oLayout = $oLayouts->next()) {
            $aTypes = array_merge(explode(";", $oLayout->getProperty("layout", "used-types")), $aTypes);
        }
        $aTypes = array_unique($aTypes);

        foreach ($aTypes as $sType) {
            $typearray[$sType] = $sType;
        }
        unset($aTypes);

        if (is_array($typearray)) {
            asort($typearray);
            $typeselect->autoFill(array_merge(array("" => "-- " . i18n("Custom") . " --"), $typearray));
        } else {
            $typeselect->autoFill(array("" => "-- " . i18n("Custom") . " --"));
        }

        $typeselect->setEvent("change", 'if (document.forms["mod_edit"].elements["type"].value == 0) { document.forms["mod_edit"].elements["customtype"].disabled=0;} else {document.forms["mod_edit"].elements["customtype"].disabled=1;}');
        $typeselect->setDisabled($disabled);

        $custom = new cHTMLTextbox("customtype", "");
        $custom->setDisabled($disabled);

        if ($module->get("type") == "" || $module->get("type") == "0") {
            $typeselect->setDefault("0");
        } else {
            $typeselect->setDefault($module->get("type"));
            $custom->setDisabled("disabled");
        }

        $modulecheck = getSystemProperty("system", "modulecheck");

        $inputok = true;
        $outputok = true;

        /** @var string $modErrorMessage */
        if ($modulecheck !== "false") {
            $outputok = modTestModule($module->get("output"), $module->get("idmod") . "o", true);
            if (!$outputok) {
                $errorMessage = sprintf(i18n("Error in module. Error location: %s"), $modErrorMessage);
                $outled = '<img align="right" src="images/but_online_no.gif" alt="' . $errorMessage . '" title="' . $errorMessage . '">';
            } else {
                $okMessage = i18n("Module successfully compiled");
                $outled = '<img align="right" src="images/but_online.gif" alt="' . $okMessage . '" title="' . $okMessage . '">';
            }

            $inputok = modTestModule($module->get("input"), $module->get("idmod") . "i");
            if (!$inputok) {
                $errorMessage = sprintf(i18n("Error in module. Error location: %s"), $modErrorMessage);
                $inled = '<img align="right" src="images/but_online_no.gif" alt="' . $errorMessage . '" title="' . $errorMessage . '">';
            } else {
                $okMessage = i18n("Module successfully compiled");
                $inled = '<img align="right" src="images/but_online.gif" alt="' . $okMessage . '" title="' . $okMessage . '">';
            }

            // Store error information in the database (to avoid re-eval for module overview/menu)
            if ($inputok && $outputok) {
                $sStatus = "none";
            } else if ($inputok) {
                $sStatus = "input";
            } else if ($outputok) {
                $sStatus = "output";
            } else {
                $sStatus = "both";
            }

            // If status has been changed, store and show in overview
            $sPrevStatus = $module->get("error");
            if ($sPrevStatus !== $sStatus) {
                $module->set("error", $sStatus);
                $module->store();

                $page->setReload();
            }
        }

        if (cRegistry::getConfigValue('dceModEdit', 'use')) {
            // button for mod folder creation
            if (!$module->hasModuleFolder() && $action != "mod_new") {
                $aParam = array(
                    'action' => 'mod_folder_create',
                    'area' => $area,
                    'idmod' => $idmod,
                    'frame' => $frame
                );
                /** @var Contenido_Session $sess */
                $oCreateFolderButton = new cHTMLLink($sess->self_url($aParam));
                $oCreateFolderButton->setContent(i18n("Create Folder"));
                $sCreateFolderButton = " " . $oCreateFolderButton->render();
            } else {
                $sCreateFolderButton = "";
            }

            $form->add(i18n("Name"), $name->render() . " (id: " . $module->get("idmod") .
                    " | dir: " . strtolower(uplCreateFriendlyName($module->get("name"))) . ")" .
                    $sCreateFolderButton);
        } else {
            $form->add(i18n("Name"), $name->render());
        }

        $form->add(i18n("Type"), $typeselect->render() . $custom->render());
        $form->add(i18n("Description"), $descr->render());

        if ($sOptionDebugRows == "always" || ($sOptionDebugRows == "onerror" && (!$inputok || !$outputok))) {
            $sSyncScript = '<script type="text/javascript"><!--
function scrolltheother() {
var oICArea = document.mod_edit.input;
var oOCArea = document.mod_edit.output;
var oIRArea = document.mod_edit.txtInputRows;
var oORArea = document.mod_edit.txtOutputRows;

oIRArea.scrollTop = oICArea.scrollTop;
oORArea.scrollTop = oOCArea.scrollTop;

setTimeout("scrolltheother()", 10);
}
window.onload = scrolltheother;
			//--></script>
			';
            $page->addScript("syncScript", $sSyncScript);

            $form->add('<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td style="vertical-align: top;">' . i18n("Input") . '</td><td style="vertical-align: top;">' . $inled . '</td><td style="padding-left: 5px; vertical-align: top;">' . $oInputRows->render() . '</td></tr></table>', $input->render());
            $form->add('<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td style="vertical-align: top;">' . i18n("Output") . '</td><td style="vertical-align: top;">' . $outled . '</td><td style="padding-left: 5px; vertical-align: top;">' . $oOutputRows->render() . '</td></tr></table>', $output->render());
        } else {
            $form->add('<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td style="vertical-align: top;">' . i18n("Input") . '</td><td style="vertical-align: top;">' . $inled . '</td></tr></table>', $input->render());
            $form->add('<table width="100%" border="0" cellspacing="0" cellpadding="0"><tr><td style="vertical-align: top;">' . i18n("Output") . '</td><td style="vertical-align: top;">' . $outled . '</td></tr></table>', $output->render());
        }

        $noti = "";

        if ($module->isOldModule()) {
            $noti .= $notification->returnNotification("warning", i18n("This module uses variables and/or functions which are probably not available in this Contenido version. Please make sure that you use up-to-date modules."));
            $noti .= "<br>";
        }

        if ($idmod != 0) {
            $import = new cHTMLRadiobutton("mode", "import");
            $export = new cHTMLRadiobutton("mode", "export");

            $import->setLabelText(i18n("Import from file"));
            $export->setLabelText(i18n("Export to file"));

            $import->setEvent("click", "document.getElementById('vupload').style.display = '';");
            $export->setEvent("click", "document.getElementById('vupload').style.display = 'none';");

            $upload = new cHTMLUpload("upload");

            if ($module->get("input") != "" && $module->get("output") != "") {
                $export->setChecked("checked");
            } else {
                $import->setChecked("checked");
            }
            $form2 = new UI_Table_Form("export");
            $form2->setVar("action", "mod_importexport_module");
            $form2->setVar("use_encoding", "false");
            $form2->addHeader("Import/Export");
            $form2->add(i18n("Mode"), array($export, "<br>", $import));
            if ($module->get("input") != "" && $module->get("output") != "") {
                $form2->add(i18n("File"), $upload, "vupload", "display: none;");
            } else {
                $form2->add(i18n("File"), $upload, "vupload");
            }
            $form2->setVar("area", $area);
            $form2->setVar("frame", $frame);
            $form2->setVar("idmod", $idmod);
            $form2->custom["submit"]["accesskey"] = '';

            $sScript = '<script type="text/javascript">
                            if (document.getElementById(\'scroll\')) {
                                document.getElementById(\'scroll\').onmousedown = triggerClickOn;
                                document.getElementById(\'scroll\').onmouseup = triggerClickOff;
                                document.getElementById(\'scroll\').style.paddingTop=\'4px\';
								document.getElementById(\'scroll\').style.paddingBottom=\'5px\';
								
                            }
                        </script>';

            $page->setContent($noti . $message . $form->render() . "<br>" . $form2->render() . $sScript);
        }

        $page->setSubnav("idmod=$idmod", "mod");
        if ($action) {
            if (stripslashes($idmod > 0)) {
                $sReloadScript = "<script type=\"text/javascript\">
                                         var left_bottom = parent.parent.frames['left'].frames['left_bottom'];
                                         if (left_bottom) {
                                             var href = left_bottom.location.href;
                                             href = href.replace(/&idmod[^&]*/, '');
                                             left_bottom.location.href = href+'&idmod='+'" . $idmod . "';

                                         }
                                </script>";
            } else {
                $sReloadScript = "";
            }

            // Only reload overview/menu page, if something may have changed
            $page->addScript('reload', $sReloadScript);
        }
        if (!($action == "mod_importexport_module" && $mode == "export")) {
            /** @var string $belang */
            $oEditAreaInput = new EditArea('input', 'php', substr(strtolower($belang), 0, 2), true, cRegistry::getConfig(), (($module->isLoadedFromFile("input")) ? FALSE : !$bInUse));
            $oEditAreaOutput = new EditArea('output', 'php', substr(strtolower($belang), 0, 2), false, cRegistry::getConfig(), (($module->isLoadedFromFile("output")) ? FALSE : !$bInUse));
            $page->addScript('editarea', $oEditAreaInput->renderScript() . $oEditAreaOutput->renderScript());

            $page->render();
        }
    }
}