function welcome_render_page_late($args)
{
    global $page_has_object;
    if (!$args['edit'] || $page_has_object) {
        return false;
    }
    // we only display the information when there are no other pages in the
    // content directory except the current one
    load_modules('glue');
    $pns = pagenames(array());
    $pns = $pns['#data'];
    if (1 < count($pns)) {
        return false;
    }
    html_add_css(base_url() . 'modules/welcome/welcome-edit.css');
    html_add_js(base_url() . 'modules/welcome/welcome.js');
    body_append('<div id="welcome-msg">' . nl());
    body_append(tab() . '<span id="welcome-first"><img style="float:left; margin:5px 10px 0 5px" src="' . base_url() . 'modules/welcome/gun32.gif">Welcome to HOTGLUE!</span><br>' . nl());
    body_append(tab() . 'Your Content Manipulation System is ready to go!' . nl());
    body_append(tab() . '<p>A short intro before you start:</p>' . nl());
    body_append(tab() . '<span id="cont"><span id="text"><b>1.</b> Right now you are in <u>editing mode</u>. You can use single and double click to access the menus - they will appear next to the mouse pointer.</span>' . nl());
    body_append(tab() . '<span id="text"><b>2.</b> Click on the canvas (white background of the page) to open a menu which will let you create new objects, upload files and embed YouTube and Vimeo videos! Once you made an object click on it to activate its contextual menu.</span>' . nl());
    body_append(tab() . '<span id="text"><b>3.</b> Double-click on the canvas will give you a menu of options to change preferences, show a grid, make new pages, set background picture and more!</span>' . nl());
    body_append(tab() . '<span id="text"><b>4.</b> Remove "' . (SHORT_URLS ? '' : '?') . 'edit" from the address of the page (the URL) to see the "view-only" version. That\'s how your page will look to everyone else!</span>' . nl());
    body_append(tab() . '<span id="text"><b>5.</b> To get back to editing mode add "' . (SHORT_URLS ? '' : '?') . 'edit" to the URL of the page.<br>(for example: ' . base_url() . '<b>' . (SHORT_URLS ? '' : '?') . 'edit</b>)</span></span>' . nl());
    body_append(tab() . '<p>We recommend you to use <a href="http://firefox.com" target="_blank">Mozilla Firefox</a> browser when editing in HOTGLUE. Firefox is a very reliable and modern web-browser, it is our favorite!' . nl());
    body_append(tab() . '<p>You can find more information on how to work with HOTGLUE on our <a href="http://hotglue.me" target="_blank">web-site</a>. Make sure to check out "<a href="http://hotglue.me/what" target="_blank">What is HOTGLUE?</a>" and "<a href="http://hotglue.me/how" target="_blank">How to HOTGLUE?</a>" pages!' . nl());
    body_append(tab() . '<p>Enjoy! <span id="welcome-light">[click this message to make it go away]</span></p>' . nl());
    body_append('</div>' . nl());
    return true;
}
function controller_pages($args)
{
    default_html(true);
    html_add_css(base_url() . 'modules/page_browser/page_browser.css');
    if (USE_MIN_FILES) {
        html_add_js(base_url() . 'modules/page_browser/page_browser.min.js');
    } else {
        html_add_js(base_url() . 'modules/page_browser/page_browser.js');
    }
    html_add_js_var('$.glue.conf.page.startpage', startpage());
    $bdy =& body();
    elem_attr($bdy, 'id', 'pages');
    body_append('<h1>All pages</h1>');
    load_modules('glue');
    $pns = pagenames(array());
    $pns = $pns['#data'];
    foreach ($pns as $pn) {
        // display only pages with 'head'
        if (is_dir(CONTENT_DIR . '/' . $pn . '/head')) {
            body_append('<div class="page_browser_entry" id="' . htmlspecialchars($pn, ENT_COMPAT, 'UTF-8') . '"><span class="page_browser_pagename"><a href="' . base_url() . '?' . htmlspecialchars(urlencode($pn), ENT_COMPAT, 'UTF-8') . '">' . htmlspecialchars($pn, ENT_NOQUOTES, 'UTF-8') . '</a></span> ');
            if ($pn . '.head' == startpage()) {
                body_append('<span id="page_browser_startpage">[startpage]</span> ');
            }
        }
        body_append('</div>');
    }
    echo html_finalize();
}
function welcome_render_page_late($args)
{
    global $page_has_object;
    if (!$args['edit'] || $page_has_object) {
        return false;
    }
    // we only display the information when there are no other pages in the
    // content directory except the current one
    load_modules('glue');
    $pns = pagenames(array());
    $pns = $pns['#data'];
    if (1 < count($pns)) {
        return false;
    }
    html_add_css(base_url() . 'modules/welcome/welcome-edit.css');
    html_add_js(base_url() . 'modules/welcome/welcome.js');
    body_append('<div id="welcome-msg">' . nl());
    body_append(tab() . '<span id="welcome-first">Welcome to HOTGLUE!</span><br>' . nl());
    body_append(tab() . 'Your Content Manipulation System is ready to go!' . nl());
    body_append(tab() . '<p>A short intro before you start:<br>' . nl());
    body_append(tab() . '&#164; To get back to editing mode in the future, add "' . (SHORT_URLS ? '' : '?') . 'edit" to the address in the address bar (i.e.: ' . base_url() . '<b>' . (SHORT_URLS ? '' : '?') . 'edit</b>)<br>' . nl());
    body_append(tab() . '&#164; In editing mode, you can use single and double click to access the menus.<br>' . nl());
    body_append(tab() . '&#164; Click the page\'s background once to open a menu that lets you create new objects, upload files and embed videos (YouTube and Vimeo).<br>' . nl());
    body_append(tab() . '&#164; Double-click to open a menu that allows you to change preferences, show a grid, make new pages and more.<br>' . nl());
    body_append(tab() . '&#164; Remove "' . (SHORT_URLS ? '' : '?') . 'edit" from the address in the address bar to go to the viewing-only mode of this page.</p>' . nl());
    body_append(tab() . '<p>You can find more ideas on how to use HOTGLUE at the <a href="http://hotglue.me/how_basic" target="_blank">"How-to" section of our website</a>!' . nl());
    body_append(tab() . '<p>Enjoy!<br>' . nl());
    body_append(tab() . '<span id="welcome-light">[This message goes away when you click it]</span></p>' . nl());
    body_append('</div>' . nl());
    return true;
}
/**
 *	copy a page
 *	original page revisions are left out 
 *	@param array $args arguments
 *		key 'old' old page (i.e. page1.rev)
 *		key 'new' new page (i.e. page2.rev)
 *	@return array response
 */
function copy_page($args)
{
    if (empty($args['old'])) {
        return response('Required argument "old" missing or empty', 400);
    }
    $pns = pagenames(array());
    $pns = $pns['#data'];
    if (!in_array($args['old'], $pns)) {
        return response('Page name ' . quot($args['old']) . ' does not exist', 404);
    }
    if (empty($args['new'])) {
        return response('Required argument "new" missing or empty', 400);
    }
    if (in_array($args['new'], $pns)) {
        return response('Page name ' . quot($args['new']) . ' already exists', 400);
    }
    if (!valid_pagename($args['new'] . '.head')) {
        return response('Invalid page name ' . quot($args['new']), 400);
    }
    $src = CONTENT_DIR . '/' . $args['old'];
    $dest = CONTENT_DIR . '/' . $args['new'];
    $dirs = scandir($src);
    foreach ($dirs as $d) {
        // skip root '.', top '..' and revisions 'auto-*'
        if ($d == '.' || $d == '..' || substr($d, 0, 5) == 'auto-') {
            continue;
            // we should only have directories in source
        } elseif (is_dir($src . '/' . $d)) {
            $m = umask(00);
            if (!@mkdir($dest . '/' . $d, 0777, true)) {
                umask($m);
                return response('Error creating directory ' . quot($dest . '/' . $d), 500);
            }
            umask($m);
            $files = scandir($src . '/' . $d);
            foreach ($files as $f) {
                if ($f == '.' || $f == '..') {
                    continue;
                } elseif (is_file($src . '/' . $d . '/' . $f)) {
                    // copy file
                    $m = umask(0111);
                    if (!@copy($src . '/' . $d . '/' . $f, $dest . '/' . $d . '/' . $f)) {
                        log_msg('error', 'copy: error copying ' . quot($src . '/' . $d . '/' . $f) . ' to ' . quot($dest . '/' . $d . '/' . $f) . ', skipping file');
                    }
                    umask($m);
                }
            }
        }
    }
    log_msg('info', 'copy_page: copied ' . quot($args['old']) . ' to ' . quot($args['new']));
    invoke_hook('copy_page', array('pagename' => $args['new']));
    return response(true);
}
/**
 *	rename a page
 *	@param array $args arguments
 *		key 'old' old page (i.e. page1.rev)
 *		key 'new' new page (i.e. page2.rev)
 *	@return array response
 */
function rename_page($args)
{
    if (empty($args['old'])) {
        return response('Required argument "old" missing or empty', 400);
    }
    $pns = pagenames(array());
    $pns = $pns['#data'];
    if (!in_array($args['old'], $pns)) {
        return response('Page name ' . quot($args['old']) . ' does not exist', 404);
    }
    if (empty($args['new'])) {
        return response('Required argument "new" missing or empty', 400);
    }
    if (in_array($args['new'], $pns)) {
        return response('Page name ' . quot($args['new']) . ' already exists', 400);
    }
    if (!valid_pagename($args['new'] . '.head')) {
        return response('Invalid page name ' . quot($args['new']), 400);
    }
    if (!@rename(CONTENT_DIR . '/' . $args['old'], CONTENT_DIR . '/' . $args['new'])) {
        return response('Error renaming page ' . quot($args['old']) . ' to ' . quot($args['new']), 500);
    } else {
        log_msg('info', 'rename_page: renamed ' . quot($args['old']) . ' to ' . quot($args['new']));
        // clean up cache as well
        $revs = revisions(array('pagename' => $args['new']));
        $revs = $revs['#data'];
        foreach ($revs as $rev) {
            drop_cache('page', $args['old'] . '.' . $rev);
        }
        invoke_hook('rename_page', array('pagename' => $args['new']));
        return response(true);
    }
}