function wppa_create_textual_watermark_file($args)
{
    // See what we have
    $args = wp_parse_args((array) $args, array('content' => '---preview---', 'pos' => 'cencen', 'id' => '', 'font' => wppa_opt('textual_watermark_font'), 'text' => '', 'style' => wppa_opt('textual_watermark_type'), 'filebasename' => 'dummy', 'url' => false, 'width' => '', 'height' => '', 'transp' => '0'));
    // We may have been called from wppa_get_water_file_and_pos() just to find the settings
    // In this case there is no id given.
    $id = $args['id'];
    if (!$id && $args['content'] != '---preview---') {
        return false;
    }
    if ($id && wppa_is_video($id)) {
        //		return false;
    }
    // Set special values in case of preview
    if ($args['content'] == '---preview---') {
        $preview = true;
        $fontsize = $args['font'] == 'system' ? 5 : 12;
        $padding = 6;
        $linespacing = ceil($fontsize * 2 / 3);
    } else {
        $preview = false;
        $fontsize = wppa_opt('textual_watermark_size');
        if ($args['font'] == 'system') {
            $fontsize = min($fontsize, 5);
        }
        $padding = 12;
        $linespacing = ceil($fontsize * 2 / 3);
    }
    // Set font specific vars
    $fontfile = $args['font'] == 'system' ? '' : WPPA_UPLOAD_PATH . '/fonts/' . $args['font'] . '.ttf';
    // Output file
    if ($preview) {
        $filename = WPPA_UPLOAD_PATH . '/fonts/wmf' . $args['filebasename'] . '.png';
    } else {
        $filename = WPPA_UPLOAD_PATH . '/temp/wmf' . $args['filebasename'] . '.png';
    }
    // Preprocess the text
    if (!$args['text']) {
        switch ($args['content']) {
            case '---preview---':
                $text = strtoupper(substr($args['font'], 0, 1)) . strtolower(substr($args['font'], 1));
                break;
            case '---filename---':
                $text = wppa_get_photo_item($id, 'filename');
                break;
            case '---name---':
                $text = wppa_get_photo_name($id);
                break;
            case '---description---':
                $text = strip_tags(wppa_strip_tags(wppa_get_photo_desc($id), 'style&script'));
                break;
            case '---predef---':
                $text = wppa_opt('textual_watermark_text');
                if ($args['font'] != 'system') {
                    $text = str_replace('( c )', '©', $text);
                    $text = str_replace('( R )', '®', $text);
                }
                $text = html_entity_decode($text);
                $text = str_replace('w#site', get_bloginfo('url'), $text);
                $usr = get_user_by('login', wppa_get_photo_item($id, 'owner'));
                $text = wppa_translate_photo_keywords($id, $text);
                $text = wppa_filter_iptc($text, $id);
                // Render IPTC tags
                $text = wppa_filter_exif($text, $id);
                // Render EXIF tags
                $text = trim($text);
                break;
            default:
                wppa_log('Error', 'Unimplemented arg ' . $arg . ' in wppa_create_textual_watermark_file()');
                return false;
        }
    } else {
        $text = $args['text'];
    }
    // Any text anyway?
    if (!strlen($text)) {
        wppa_log('Error', 'No text for textual watermark. photo=' . $id);
        return false;
        // No text -> no watermark
    }
    // Split text on linebreaks
    $text = str_replace("\n", '\\n', $text);
    $lines = explode('\\n', $text);
    // Trim and remove empty lines
    $temp = $lines;
    $lines = array();
    foreach ($temp as $line) {
        $line = trim($line);
        if ($line) {
            $lines[] = $line;
        }
    }
    // Find image width
    if ($args['width']) {
        $image_width = $args['width'];
    } else {
        $image_width = '';
    }
    if ($args['height']) {
        $image_height = $args['height'];
    } else {
        $image_height = '';
    }
    if ($preview) {
        if (!$image_width) {
            $image_width = 2000;
        }
        if (!$image_height) {
            $image_height = 1000;
        }
    } else {
        //		$temp = getimagesize( wppa_get_photo_path( $id ) );
        $temp = wppa_get_imagexy($id);
        if (!is_array($temp)) {
            wppa_log('Error', 'Trying to apply a watermark on a non image file. Id = ' . $id);
            return false;
            // not an image
        }
        if (!$image_width) {
            $image_width = $temp[0];
        }
        if (!$image_height) {
            $image_height = $temp[1];
        }
    }
    $width_fits = false;
    while (!$width_fits) {
        // Find pixel linelengths
        foreach (array_keys($lines) as $key) {
            $lines[$key] = trim($lines[$key]);
            if ($args['font'] == 'system') {
                $lengths[$key] = strlen($lines[$key]) * imagefontwidth($fontsize);
            } else {
                $temp = imagettfbbox($fontsize, 0.0, $fontfile, $lines[$key]);
                $lengths[$key] = $temp[2] - $temp[0];
            }
        }
        $maxlen = wppa_array_max($lengths);
        // Find canvas size
        $nlines = count($lines);
        if ($args['font'] == 'system') {
            $lineheight = imagefontheight($fontsize);
        } else {
            $temp = imagettfbbox($fontsize, 0.0, $fontfile, $lines[0]);
            $lineheight = $temp[3] - $temp[7];
        }
        $canvas_width = wppa_array_max($lengths) + 4 * $padding;
        $canvas_height = ($lineheight + $linespacing) * count($lines) + 2 * $padding;
        // Does it fit?
        if ($canvas_width > $image_width) {
            // Break the longest line into two sublines. There should be a space in the right half, if not: fail
            $i = 0;
            $l = 0;
            foreach (array_keys($lines) as $key) {
                if (strlen($lines[$key]) > $l) {
                    $i = $key;
                    $l = strlen($lines[$key]);
                }
            }
            $temp = $lines;
            $lines = array();
            $j = 0;
            while ($j < $i) {
                $lines[$j] = $temp[$j];
                $j++;
            }
            //
            $j = $i;
            $llen = strlen($temp[$i]);
            $spos = floor($llen / 2);
            while ($spos < $llen && substr($temp[$i], $spos, 1) != ' ') {
                $spos++;
            }
            if ($spos == $llen) {
                // Unable to find a space, give up
                wppa_log('Error', 'Trying to apply a watermark that is too wide for the image. Id = ' . $id);
                return false;
                // too wide
            }
            $lines[$j] = substr($temp[$i], 0, $spos);
            $lines[$j + 1] = trim(str_replace($lines[$j], '', $temp[$i]));
            $i++;
            //
            $j = $i + 1;
            while ($j <= count($temp)) {
                $lines[$j] = $temp[$i];
                $j++;
            }
        } else {
            $width_fits = true;
        }
        if ($canvas_height > $image_height) {
            wppa_log('Error', 'Trying to apply a watermark that is too high for the image. Id = ' . $id);
            return false;
            // not an image
        }
    }
    // Create canvas
    $fg = wppa_opt('watermark_fgcol_text');
    $fgr = hexdec(substr($fg, 1, 2));
    $fgg = hexdec(substr($fg, 3, 2));
    $fgb = hexdec(substr($fg, 5, 2));
    $bg = wppa_opt('watermark_bgcol_text');
    $bgr = hexdec(substr($bg, 1, 2));
    $bgg = hexdec(substr($bg, 3, 2));
    $bgb = hexdec(substr($bg, 5, 2));
    $canvas = imagecreatetruecolor($canvas_width, $canvas_height);
    $bgcolor = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
    // Transparent
    $white = imagecolorallocatealpha($canvas, $bgr, $bgg, $bgb, $args['transp']);
    $black = imagecolorallocatealpha($canvas, $fgr, $fgg, $fgb, $args['transp']);
    imagefill($canvas, 0, 0, $bgcolor);
    //	imagerectangle( $canvas, 0, 0, $canvas_width-1, $canvas_height-1, $white );	// debug
    // Define the text colors
    switch ($args['style']) {
        case 'tvstyle':
        case 'whiteonblack':
            $fg = $white;
            $bg = $black;
            break;
        case 'utopia':
        case 'blackonwhite':
            $fg = $black;
            $bg = $white;
            break;
        case 'white':
            $fg = $white;
            $bg = $bgcolor;
            break;
        case 'black':
            $fg = $black;
            $bg = $bgcolor;
            break;
    }
    // Plot the text
    foreach (array_keys($lines) as $lineno) {
        if (strpos($args['pos'], 'lft') !== false) {
            $indent = 0;
        } elseif (strpos($args['pos'], 'rht') !== false) {
            $indent = $maxlen - $lengths[$lineno];
        } else {
            $indent = floor(($maxlen - $lengths[$lineno]) / 2);
        }
        switch ($args['style']) {
            case 'tvstyle':
            case 'utopia':
                for ($i = -1; $i <= 1; $i++) {
                    for ($j = -1; $j <= 1; $j++) {
                        if ($args['font'] == 'system') {
                            imagestring($canvas, $fontsize, 2 * $padding + $i + $indent, $padding + $lineno * ($lineheight + $linespacing) + $j, $lines[$lineno], $bg);
                        } else {
                            imagettftext($canvas, $fontsize, 0, 2 * $padding + $i + $indent, $padding + ($lineno + 1) * $lineheight + $lineno * $linespacing + $j, $bg, $fontfile, $lines[$lineno]);
                        }
                    }
                }
                if ($args['font'] == 'system') {
                    imagestring($canvas, $fontsize, 2 * $padding + $indent, $padding + $lineno * ($lineheight + $linespacing), $lines[$lineno], $fg);
                } else {
                    imagettftext($canvas, $fontsize, 0, 2 * $padding + $indent, $padding + ($lineno + 1) * $lineheight + $lineno * $linespacing, $fg, $fontfile, $lines[$lineno]);
                }
                break;
            case 'blackonwhite':
            case 'whiteonblack':
            case 'white':
            case 'black':
                $lft = $padding + $indent;
                $rht = 3 * $padding + $indent + $lengths[$lineno];
                $top = $lineno * ($lineheight + $linespacing) + $padding;
                $bot = ($lineno + 1) * ($lineheight + $linespacing) + $padding;
                imagefilledrectangle($canvas, $lft, $top + 1, $rht, $bot, $bg);
                //				imagerectangle( $canvas, $lft, $top, $rht, $bot, $fg );	// debug
                $top = $padding + $lineno * ($lineheight + $linespacing) + floor($linespacing / 2);
                $lft = 2 * $padding + $indent;
                $bot = $padding + ($lineno + 1) * ($lineheight + $linespacing) - ceil($linespacing / 2);
                if ($args['font'] == 'system') {
                    imagestring($canvas, $fontsize, $lft, $top, $lines[$lineno], $fg);
                } else {
                    imagettftext($canvas, $fontsize, 0, $lft, $bot - 1, $fg, $fontfile, $lines[$lineno]);
                }
                break;
        }
    }
    imagesavealpha($canvas, true);
    imagepng($canvas, $filename);
    imagedestroy($canvas);
    if ($preview || $args['url']) {
        $url = str_replace(WPPA_UPLOAD_PATH, WPPA_UPLOAD_URL, $filename);
        return $url;
    } else {
        return $filename;
    }
}
function wppa_send_comment_approved_email($id)
{
    global $wpdb;
    // Feature enabled?
    if (!wppa_switch('com_notify_approved')) {
        return;
    }
    // Get comment
    $com = $wpdb->get_row($wpdb->prepare("SELECT * FROM `" . WPPA_COMMENTS . "` WHERE `id` = %d", $id), ARRAY_A);
    if (!$com) {
        return;
    }
    // Get photo owner
    $owner = wppa_get_photo_item($com['photo'], 'owner');
    if (!$owner) {
        return;
    }
    // Get email
    $user = get_user_by('login', $owner);
    if (!$user) {
        return;
    }
    // Custom content?
    if (wppa_opt('com_notify_approved_text')) {
        // The subject
        $subject = wppa_opt('com_notify_approved_subj');
        // The content
        $content = wppa_opt('com_notify_approved_text');
        $content = str_replace('w#comment', $com['comment'], $content);
        $content = str_replace('w#user', $com['user'], $content);
        $content = wppa_translate_photo_keywords($com['photo'], $content);
        // Try to send it with extra headers and with html
        $iret = wp_mail($user->user_email, $subject, $content, array('Content-Type: text/html'), '');
        if ($iret) {
            return;
        }
        // Failed
        echo 'Mail sending Failed';
        echo 'Subj=' . $subject . ', content=' . $content;
        return;
    }
    // Make email text
    $content = '<h3>' . __('Your photo has a new approved comment', 'wp-photo-album-plus') . '</h3>' . '<h3>' . __('From:', 'wp-photo-album-plus') . ' ' . $com['user'] . '</h3>' . '<h3>' . __('Comment:', 'wp-photo-album-plus') . '</h3>' . '<blockquote style="color:#000077; background-color: #dddddd; border:1px solid black; padding: 6px; border-radius 4px;" ><em> ' . stripslashes($com['comment']) . '</em></blockquote>';
    // Send mail
    wppa_send_mail($user->user_email, __('Approved comment on photo', 'wp-photo-album-plus'), $content, $com['photo'], 'void');
}
function wppa_get_photo_desc($id, $do_shortcodes = false, $do_geo = false)
{
    // Verify args
    if (!is_numeric($id) || $id < '1') {
        wppa_dbg_msg('Invalid arg wppa_get_photo_desc( ' . $id . ' )', 'red');
        return '';
    }
    // Get data
    $thumb = wppa_cache_thumb($id);
    $desc = $thumb['description'];
    // Raw data
    $desc = stripslashes($desc);
    // Unescape
    $desc = __($desc, 'wp-photo-album-plus');
    // qTranslate
    // To prevent recursive rendering of scripts or shortcodes:
    $desc = str_replace(array('%%wppa%%', '[wppa', '[/wppa]'), array('%-wppa-%', '{wppa', '{/wppa}'), $desc);
    // Geo
    if ($thumb['location'] && !wppa_in_widget() && strpos(wppa_opt('custom_content'), 'w#location') !== false && $do_geo == 'do_geo') {
        wppa_do_geo($id, $thumb['location']);
    }
    // Other keywords
    $desc = wppa_translate_photo_keywords($id, $desc);
    // Shortcodes
    if ($do_shortcodes) {
        $desc = do_shortcode($desc);
    } else {
        $desc = strip_shortcodes($desc);
    }
    // Remove shortcodes if not wanted
    $desc = wppa_html($desc);
    // Enable html
    $desc = balanceTags($desc, true);
    // Balance tags
    $desc = wppa_filter_iptc($desc, $id);
    // Render IPTC tags
    $desc = wppa_filter_exif($desc, $id);
    // Render EXIF tags
    $desc = make_clickable($desc);
    // Auto make a tags for links
    $desc = convert_smilies($desc);
    // Make smilies visible
    // CMTooltipGlossary on board?
    $desc = wppa_filter_glossary($desc);
    return $desc;
}