function webvideo_alter_render_early($args)
{
    $elem =& $args['elem'];
    $obj = $args['obj'];
    if (!elem_has_class($elem, 'webvideo')) {
        return false;
    }
    if (empty($obj['webvideo-provider']) || empty($obj['webvideo-id'])) {
        return false;
    }
    $i = elem('iframe');
    if ($obj['webvideo-provider'] == 'youtube') {
        if (empty($_SERVER['HTTPS'])) {
            $src = 'http://';
        } else {
            $src = 'https://';
        }
        $src .= 'www.youtube.com/embed/' . $obj['webvideo-id'] . '?rel=0';
        if (isset($obj['webvideo-autoplay']) && $obj['webvideo-autoplay'] == 'autoplay') {
            $src .= '&autoplay=1';
        }
        if (isset($obj['webvideo-loop']) && $obj['webvideo-loop'] == 'loop') {
            // this is not yet supported by the new youtube embed player
            $src .= '&loop=1';
        }
        elem_attr($i, 'src', $src);
        elem_add_class($i, 'youtube-player');
    } elseif ($obj['webvideo-provider'] == 'vimeo') {
        $src = 'http://player.vimeo.com/video/' . $obj['webvideo-id'] . '?title=0&byline=0&portrait=0&color=ffffff';
        if (isset($obj['webvideo-autoplay']) && $obj['webvideo-autoplay'] == 'autoplay') {
            $src .= '&autoplay=1';
        }
        if (isset($obj['webvideo-loop']) && $obj['webvideo-loop'] == 'loop') {
            $src .= '&loop=1';
        }
        elem_attr($i, 'src', $src);
    }
    // frameborder is not valid html
    //elem_attr($i, 'frameborder', '0');
    elem_css($i, 'border-width', '0px');
    elem_css($i, 'height', '100%');
    elem_css($i, 'position', 'absolute');
    elem_css($i, 'width', '100%');
    elem_append($elem, $i);
    if ($args['edit']) {
        // add handle as well
        $h = elem('div');
        elem_add_class($h, 'glue-webvideo-handle');
        elem_add_class($h, 'glue-ui');
        elem_attr($h, 'title', 'drag here');
        elem_append($elem, $h);
    }
    return true;
}
function download_alter_render_early($args)
{
    $elem =& $args['elem'];
    $obj = $args['obj'];
    if (!elem_has_class($elem, 'download')) {
        return false;
    }
    if ($args['edit']) {
        elem_attr($elem, 'title', 'this is ' . $obj['name'] . ', original file name was ' . $obj['download-file']);
    } else {
        elem_attr($elem, 'title', 'download file');
    }
    // get file extension
    $a = expl('.', $obj['download-file']);
    if (1 < count($a)) {
        $v = elem('div');
        elem_add_class($v, 'download-ext');
        elem_val($v, htmlspecialchars(array_pop($a), ENT_NOQUOTES, 'UTF-8'));
        elem_append($elem, $v);
    }
    return true;
}
function iframe_alter_render_early($args)
{
    $elem =& $args['elem'];
    $obj = $args['obj'];
    if (!elem_has_class($elem, 'iframe')) {
        return false;
    }
    // add iframe
    $i = elem('iframe');
    // frameborder is not valid html5
    //if (!$args['edit'] && IE8_COMPAT) {
    //	elem_attr($i, 'frameborder', '0');
    //}
    // set the name attribute
    elem_attr($i, 'name', $obj['name']);
    if (!$args['edit']) {
        // try to lift any restrictions
        elem_attr($i, 'sandbox', 'allow-forms allow-same-origin allow-scripts allow-top-navigation');
    }
    elem_css($i, 'background-color', 'transparent');
    elem_css($i, 'border-width', '0px');
    elem_css($i, 'height', '100%');
    elem_css($i, 'position', 'absolute');
    elem_css($i, 'width', '100%');
    // url
    if (!empty($obj['iframe-url'])) {
        elem_attr($i, 'src', $obj['iframe-url']);
    } else {
        elem_attr($i, 'src', '');
    }
    // scrolling
    if (isset($obj['iframe-scroll']) && $obj['iframe-scroll'] == 'scroll') {
        elem_css($i, 'overflow', 'auto');
        // attribute scrolling is not available in html5 but this effectivly
        // removes the scrollbars on Chrome, so..
        elem_attr($i, 'scrolling', 'auto');
    } else {
        elem_css($i, 'overflow', 'hidden');
        elem_attr($i, 'scrolling', 'no');
        elem_attr($i, 'seamless', 'seamless');
    }
    elem_append($elem, $i);
    if ($args['edit']) {
        // add shield as well
        $s = elem('div');
        elem_add_class($s, 'glue-iframe-shield');
        elem_add_class($s, 'glue-ui');
        elem_css($s, 'height', '100%');
        elem_css($s, 'position', 'absolute');
        elem_css($s, 'width', '100%');
        elem_attr($s, 'title', 'visitors will be able to interact with the webpage below');
        elem_append($elem, $s);
    }
    return true;
}
/**
 *	helper function for appending content to the body element
 *
 *	@param mixed $c content (can be either a string or another element)
 */
function body_append($c)
{
    global $html;
    elem_append($html['body'], $c);
}
function text_alter_render_early($args)
{
    $elem =& $args['elem'];
    $obj = $args['obj'];
    if (!elem_has_class($elem, 'text')) {
        return false;
    }
    // background-color
    if (!empty($obj['text-background-color'])) {
        elem_css($elem, 'background-color', $obj['text-background-color']);
    }
    // content
    if (!isset($obj['content'])) {
        $obj['content'] = '';
    }
    if ($args['edit']) {
        // add a textarea
        $i = elem('textarea');
        elem_add_class($i, 'glue-text-input');
        elem_css($i, 'width', '100%');
        elem_css($i, 'height', '100%');
        // hide the text area by default
        elem_css($i, 'display', 'none');
        // set the context to the textarea to the (unrendered) object content
        $content = htmlspecialchars($obj['content'], ENT_NOQUOTES, 'UTF-8');
        // replace newline characters by an entity to prevent render_object()
        // from adding some indentation
        $content = str_replace("\r\n", '&#10;', $content);
        $content = str_replace("\n", '&#10;', $content);
        // why not replace tabs as well why we are at it
        $content = str_replace("\t", '&#09;', $content);
        elem_val($i, $content);
        elem_append($elem, $i);
        // and a nested div
        $r = elem('div');
        elem_add_class($r, 'glue-text-render');
        elem_css($r, 'width', '100%');
        elem_css($r, 'height', '100%');
        // set the content of the div to the rendered object content
        elem_val($r, _text_render_content($obj['content'], $obj['name']));
        elem_append($elem, $r);
    } else {
        elem_append($elem, _text_render_content($obj['content'], $obj['name']));
    }
    // font-color
    if (!empty($obj['text-font-color'])) {
        elem_css($elem, 'color', $obj['text-font-color']);
    }
    // font-family
    if (!empty($obj['text-font-family'])) {
        elem_css($elem, 'font-family', $obj['text-font-family']);
        if (TEXT_USE_WOFF_FONTS) {
            if (_is_woff_font($obj['text-font-family'])) {
                // include all styles of the font because of inline html
                // (<strong>, etc)
                _include_woff_font($obj['text-font-family']);
            }
        }
    }
    // font-size
    if (!empty($obj['text-font-size'])) {
        elem_css($elem, 'font-size', $obj['text-font-size']);
    }
    // font-style
    if (!empty($obj['text-font-style'])) {
        elem_css($elem, 'font-style', $obj['text-font-style']);
    }
    // font-weight
    if (!empty($obj['text-font-weight'])) {
        elem_css($elem, 'font-weight', $obj['text-font-weight']);
    }
    // letter-spacing
    if (!empty($obj['text-letter-spacing'])) {
        elem_css($elem, 'letter-spacing', $obj['text-letter-spacing']);
    }
    // line-height
    if (!empty($obj['text-line-height'])) {
        elem_css($elem, 'line-height', $obj['text-line-height']);
    }
    // padding-x
    if (!empty($obj['text-padding-x'])) {
        elem_css($elem, 'padding-left', $obj['text-padding-x']);
        elem_css($elem, 'padding-right', $obj['text-padding-x']);
    }
    // padding-y
    if (!empty($obj['text-padding-y'])) {
        elem_css($elem, 'padding-top', $obj['text-padding-y']);
        elem_css($elem, 'padding-bottom', $obj['text-padding-y']);
    }
    // text-align
    if (!empty($obj['text-align'])) {
        elem_css($elem, 'text-align', $obj['text-align']);
    }
    // word-spacing
    if (!empty($obj['text-word-spacing'])) {
        elem_css($elem, 'word-spacing', $obj['text-word-spacing']);
    }
    return true;
}
function video_alter_render_early($args)
{
    $elem =& $args['elem'];
    $obj = $args['obj'];
    if (!elem_has_class($elem, 'video')) {
        return false;
    }
    // add a css (for viewing as well as editing)
    html_add_css(base_url() . 'modules/video/video.css');
    $v = elem('video');
    if (empty($obj['video-file'])) {
        elem_attr($v, 'src', '');
    } else {
        // TODO (later): support URLs as well
        if (SHORT_URLS) {
            elem_attr($v, 'src', base_url() . urlencode($obj['name']));
        } else {
            elem_attr($v, 'src', base_url() . '?' . urlencode($obj['name']));
        }
    }
    elem_css($v, 'width', '100%');
    elem_css($v, 'height', '100%');
    // we're currently not preloading the video due to some troubles on
    // Firefox
    //elem_css($v, 'preload', 'preload');
    // set some fallback text
    if (!empty($obj['video-file']) && !empty($obj['video-file-mime'])) {
        elem_val($v, '<div class="video-fallback">You are not seeing the video because your browser does not support ' . htmlspecialchars($obj['video-file-mime'], ENT_NOQUOTES, 'UTF-8') . '. Consider using a contemporary web browser.</div>');
    } else {
        elem_val($v, '<div class="video-fallback">You are not seeing the video because your browser does not support it. Consider using a contemporary web browser.</div>');
    }
    // autoplay
    if (!isset($obj['video-autoplay']) || $obj['video-autoplay'] == 'autoplay') {
        // autoplay is the default
        elem_attr($v, 'autoplay', 'autoplay');
    } else {
        if (VIDEO_START_ON_CLICK) {
            elem_attr($v, 'onclick', 'this.play()');
        }
    }
    // loop
    if (!empty($obj['video-loop'])) {
        elem_attr($v, 'loop', 'loop');
    }
    // controls
    if (!empty($obj['video-controls'])) {
        elem_attr($v, 'controls', 'controls');
    }
    // volume
    if (isset($obj['video-volume']) && $obj['video-volume'] == '0') {
        elem_attr($v, 'audio', 'muted');
    }
    elem_append($elem, $v);
    return true;
}
/**
 *	implements alter_render_early
 *
 *	see image_render_object()
 */
function image_alter_render_early($args)
{
    $elem =& $args['elem'];
    $obj = $args['obj'];
    if (!elem_has_class($elem, 'image')) {
        return false;
    }
    // try to calculate original-{width,height} if not already set
    if (!empty($obj['image-file']) && (empty($obj['image-file-width']) || intval($obj['image-file-width']) == 0)) {
        if (_gd_available()) {
            $a = expl('.', $obj['name']);
            $fn = CONTENT_DIR . '/' . $a[0] . '/shared/' . $obj['image-file'];
            // resolve symlinks
            if (@is_link($fn)) {
                $target = @readlink($fn);
                if (substr($target, 0, 1) == '/') {
                    $fn = $target;
                } else {
                    $fn = dirname($fn) . '/' . $target;
                }
            }
            $size = _gd_get_imagesize($fn);
            $obj['image-file-width'] = $size[0];
            // update regular with as well if not set
            if (empty($obj['object-width']) || intval($obj['object-width']) == 0) {
                $obj['object-width'] = $size[0] . 'px';
            }
            $obj['image-file-height'] = $size[1];
            if (empty($obj['object-height']) || intval($obj['object-height']) == 0) {
                $obj['object-height'] = $size[1] . 'px';
            }
        }
        save_object($obj);
    }
    // setup url
    // note: the url points to the object name, not the
    // filename in the shared directory (the file eventually gets served
    // in image_serve_resource())
    // TODO (later): support URLs as well
    if (SHORT_URLS) {
        $url = base_url() . urlencode($obj['name']);
    } else {
        $url = base_url() . '?' . urlencode($obj['name']);
    }
    // render a div with background if we have original-{width,height}
    // otherwise a div with an img inside
    if (empty($obj['image-file-width']) || intval($obj['image-file-width']) == 0) {
        // render a div with an img inside
        $i = elem('img');
        elem_attr($i, 'src', $url);
        if (!empty($obj['image-title'])) {
            elem_attr($i, 'alt', $obj['image-title']);
        } else {
            elem_attr($i, 'alt', '');
        }
        // make sure you only append to the element in alter_render_early
        // handlers, don't assume that nothing is in there yet
        elem_append($elem, $i);
    } else {
        if (!$args['edit'] && IE8_COMPAT && (empty($obj['image-background-repeat']) || $obj['image-background-repeat'] == 'no-repeat')) {
            // background-size is not supported by IE8, so render a div with an img inside instead
            $i = elem('img');
            elem_attr($i, 'src', $url);
            if (!empty($obj['image-title'])) {
                elem_attr($i, 'alt', $obj['image-title']);
            } else {
                elem_attr($i, 'alt', '');
            }
            elem_css($i, 'width', '100%');
            elem_css($i, 'height', '100%');
            elem_css($i, 'padding', '0px');
            elem_css($i, 'border', '0px');
            if (!empty($obj['image-background-position']) && $obj['image-background-position'] != '0px 0px' && $obj['image-background-position'] != '0% 0%') {
                elem_css($elem, 'max-width', $obj['object-width']);
                elem_css($elem, 'max-height', $obj['object-height']);
                elem_css($elem, 'overflow', 'hidden');
                // assume px
                $a = expl(' ', $obj['image-background-position']);
                elem_css($i, 'margin-left', @intval($a[0]) . 'px');
                elem_css($i, 'margin-top', @intval($a[1]) . 'px');
                elem_css($i, 'margin-right', '0px');
                elem_css($i, 'margin-bottom', '0px');
            } else {
                elem_css($i, 'margin', '0px');
            }
            elem_append($elem, $i);
        } else {
            // this is the regular case
            // render a div with background
            elem_css($elem, 'background-image', 'url(' . $url . ')');
            // default to no tiling
            if (empty($obj['image-background-repeat']) || $obj['image-background-repeat'] == 'no-repeat') {
                elem_css($elem, 'background-repeat', 'no-repeat');
                // set hardcoded background-size as well
                elem_css($elem, 'background-size', '100% 100%');
                // this is for Firefox 3.6
                elem_css($elem, '-moz-background-size', '100% 100%');
            } else {
                elem_css($elem, 'background-repeat', $obj['image-background-repeat']);
            }
            if (!empty($obj['image-background-position'])) {
                elem_css($elem, 'background-position', $obj['image-background-position']);
            }
        }
    }
    // additional properties for both
    if (!empty($obj['image-title'])) {
        elem_attr($elem, 'title', $obj['image-title']);
    }
    return true;
}