<?php
#CopyRight @ Jinjun Xia 2004-2005
#2004/10
#Version 2
#FFBBCODE is Free Software developed and released under GPL license 
#for phpnuke FriendFinder(http://yuelao.net)
#But it also can be used for other modules those use textareas
#Because I have a full time job, I can not help support now, So
#I don't wanna provide my email, thanks for understanding. 


function decode_bbcode_code($text)
{
    global $bb_codes;
    $bb_codes['code_start'] = '<table valign=top width="90%" cellspacing="1" cellpadding="3" border="0" align="center" bordercolor="#B99999"><tr>
    <td><span class="genmed"><b>Code:</b></span><br /><HR></td>
    </tr><tr>
    <td class="code"><code>';
    $bb_codes['code_end'] =  '</code><HR></td></tr></table>';

    $text = substr($text, 6, -7);
    // Replace 2 spaces with "&nbsp; " so non-tabbed code indents without making huge long lines.
    $text = str_replace('  ', '&nbsp; ', $text);
    // now Replace 2 spaces with ' &nbsp;' to catch odd #s of spaces.
    $text = str_replace('  ', ' &nbsp;', $text);
    // Replace tabs with "&nbsp; &nbsp;" so tabbed code indents sorta right without making huge long lines.
    $text = str_replace("\t", '&nbsp; &nbsp;', $text);
    // now Replace space occurring at the beginning of a line
    $text = preg_replace('/^ {1}/m', '&nbsp;', $text);
    $text = str_replace('[', '&#91;', $text);
    return $bb_codes['code_start'].$text.$bb_codes['code_end'];
} // decode_bbcode_code()
// split the bbcodes and use nl2br on everything except [php]
function split_on_bbcodes($text)
{
    $curr_pos = 1;
    $text_parts = array();
    $count = 0;
    while ($curr_pos < strlen($text)) {
        // Find bbcode start tag, if not found end the loop.
        $curr_pos = strpos($text, '[', $curr_pos);
        if ($curr_pos === false) { break; }
        $end = strpos($text, ']', $curr_pos);
        if ($end === false) { break; }

        $code_start = substr($text, $curr_pos, $end-$curr_pos+1);
        $code = preg_replace('/\[([a-z]+).*]/i', '\\1', $code_start);
        $code_len = strlen($code);

        $end_pos = $end;
        $depth = 0;
        while ($end_pos) {
            // Find bbcode end tag, if not found end the loop.
            $end_pos = strpos($text, '[', $end_pos);
            if ($end_pos === false) { break; }
            $end = strpos($text, ']', $end_pos);
            if ($end === false) { break; }
            $code_end = substr($text, $end_pos, $end-$end_pos+1);

            if (strncasecmp($code_end, "[/$code", 2+$code_len) == 0) {
                if ($depth > 0) {
                    $depth--;
                } else {
                    if ($curr_pos > 1) {
                        $text_parts[$count]['text'] = substr($text, 0, $curr_pos);
                        $count++;
                    }
                    $text_parts[$count]['text'] = substr($text, $curr_pos, $end-$curr_pos+1);
                    $text_parts[$count]['code'] = $code;
                    $count++;
                    $text = substr($text, $end+1);
                    $curr_pos = 1;
                    $end_pos = false;
                }
            } else {
                if (strncasecmp($code_end, "[$code", 1+$code_len) == 0) {
                    $depth++;
                }
                $end_pos++;
            }
        }
        $curr_pos++;
    }
    if (strlen($text) > 0) {
        $text_parts[$count]['text'] = $text;
        $count++;
    }
    $text = '';
    for ($i=0; $i<$count; $i++) {
        if (isset($text_parts[$i]['code'])) {
            if ($text_parts[$i]['code'] == 'php') {
                // [PHP] and [/PHP] for posting PHP code in your posts.
                $text .= decode_bbcode_php($text_parts[$i]['text']);
            } else if ($text_parts[$i]['code'] == 'code') {
                // [CODE] and [/CODE] for posting code (HTML, C etc etc) in your posts.
                $text_parts[$i]['text'] = nl2br($text_parts[$i]['text']);
                $text .= decode_bbcode_code($text_parts[$i]['text']) ;
            } else {
                $text .= split_on_bbcodes($text_parts[$i]['text']);
            }
        } else {
            $text .= nl2br($text_parts[$i]['text']);
        }
        $text_parts[$i] = '';
    }
    unset($text_parts);
    return $text;
}

function decode_bbcode_php($text)
{
    $code_start_html = '<table valign=top border="0" align="center" width="90%" cellpadding="3" cellspacing="1">
    <tr>
      <td><span class="genmed"><b>PHP:</b></span><br /><HR></td>
    </tr>
    <tr>
      <td class="code">';
    $code_end_html =  '<HR></td></tr></table>';
    $matches = array();
    $match_count = preg_match_all("#\[php\](.*?)\[/php\]#si", $text, $matches);

    for ($i = 0; $i < $match_count; $i++) {
        $before_replace = $matches[1][$i];
        $after_replace = trim($matches[1][$i]);
        $str_to_match = "[php]" . $before_replace . "[/php]";
        $replacement = $code_start_html;
        $after_replace = str_replace('&lt;', '<', $after_replace);
        $after_replace = str_replace('&gt;', '>', $after_replace);
        $after_replace = str_replace("<br />\r\n", "\n", $after_replace);
        $after_replace = str_replace("<br />\n", "\n", $after_replace);
        $after_replace = str_replace('&amp;', '&', $after_replace);
        $after_replace = str_replace('&quot;', '"', $after_replace);
        $added = FALSE;
        if (preg_match('/^<\?.*?\?>$/si', $after_replace) <= 0) {
            $after_replace = "<?php $after_replace ?>";
            $added = TRUE;
        }
        if(strcmp('4.2.0', phpversion()) > 0) {
            ob_start();
            highlight_string($after_replace);
            $after_replace = ob_get_contents();
            ob_end_clean();
        }
        else {
            $after_replace = highlight_string($after_replace, TRUE);
        }
        if ($added == TRUE) {
            $after_replace = str_replace('<font color="#0000BB">&lt;?php ', '<font color="#0000BB">', $after_replace);
            $after_replace = str_replace('<font color="#0000BB">?&gt;</font>', '', $after_replace);
        }
        $after_replace = preg_replace('/<font color="(.*?)">/si', '<span style="color: \\1;">', $after_replace);
        $after_replace = str_replace('</font>', '</span>', $after_replace);
        $after_replace = str_replace("\n", '', $after_replace);
        $replacement .= $after_replace;
        $replacement .= $code_end_html;

        $text = str_replace($str_to_match, $replacement, $text);
    }

    $text = str_replace("[php]", $code_start_html, $text);
    $text = str_replace("[/php]", $code_end_html, $text);

    return $text;
} // decode_bbcode_php()

function bbcode_replace($str,$poster){
	// pad it with a space so we can match things at the start of the 1st line.
	$str = " " . $str;
	$str=str_replace("<?","<?",$str);
	$str=str_replace("?>","?>",$str);
	$str = str_replace("[quote]","$poster&nbsp;<b>Quote:</b>\n<table width=100% border=1 align=\"center\" cellpadding=\"5\" cellspacing=\"0\" bordercolor=\"#B99999\"><tr><td bgcolor=\"#F6e6e6\">", $str);
	$str = str_replace("[/quote]","</td></tr></table>\n", $str);
    	// pad it with a space so we can distinguish between FALSE and matching the 1st char (index 0).

	//t�
	// matches an "xxxx://yyyy" URL at the start of a line, or after a space.
	// xxxx can only be alpha characters.
	// yyyy is anything up to the first space, newline, or comma.
	$str = preg_replace("#([\n ])([a-z]+?)://([^,\t \n\r]+)#i", "\\1<a href=\"\\2://\\3\" target=\"_blank\">\\2://\\3</a>", $str);

	// matches a "www.xxxx.yyyy[/zzzz]" kinda lazy URL thing
	// Must contain at least 2 dots. xxxx contains either alphanum, or "-"
	// yyyy contains either alphanum, "-", or "."
	// zzzz is optional.. will contain everything up to the first space, newline, or comma.
	// This is slightly restrictive - it's not going to match stuff like "forums.foo.com"
	// This is to keep it from getting annoying and matching stuff that's not meant to be a link.
	$str = preg_replace("#([\n ])www\.([a-z0-9\-]+)\.([a-z0-9\-.\~]+)((?:/[^,\t \n\r]*)?)#i", "\\1<a href=\"http://www.\\2.\\3\\4\" target=\"_blank\">www.\\2.\\3\\4</a>", $str);

	// matches an user_email@domain type address at the start of a line, or after a space.
	// Note: Only the followed chars are valid; alphanums, "-", "_" and or ".".
	$str = preg_replace("#([\n ])([a-z0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)?[\w]+)#i", "\\1<a href=\"mailto:\\2@\\3\">\\2@\\3</a>", $str);

	// Remove our padding..
	// [img]image_url_here[/img] code..
	// This one gets first-passed..
	$patterns[0] = "#\[img\](.*?)\[/img\]#si";
	$str= preg_replace("#\[img\](([a-z]+?)://([^ \"\n\r]+?))\[/img\]#si", "[img]\\1[/img]", $str);
	$replacements[0] = "<img src=\"{URL}\" border=\"0\" />";
	$replacements[0] = str_replace('{URL}', '\\1', $replacements[0]);
	$bbcode_tpl['url']="<a href=\"{URL}\" target=\"_blank\" class=\"postlink\">{DESCRIPTION}</a>";
	$bbcode_tpl['url1'] = str_replace('{URL}', '\\1\\2', $bbcode_tpl['url']);
	$bbcode_tpl['url1'] = str_replace('{DESCRIPTION}', '\\1\\2', $bbcode_tpl['url1']);

	$bbcode_tpl['url2'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']);
	$bbcode_tpl['url2'] = str_replace('{DESCRIPTION}', '\\1', $bbcode_tpl['url2']);

	$bbcode_tpl['url3'] = str_replace('{URL}', '\\1\\2', $bbcode_tpl['url']);
	$bbcode_tpl['url3'] = str_replace('{DESCRIPTION}', '\\3', $bbcode_tpl['url3']);

	$bbcode_tpl['url4'] = str_replace('{URL}', 'http://\\1', $bbcode_tpl['url']);
	$bbcode_tpl['url4'] = str_replace('{DESCRIPTION}', '\\2', $bbcode_tpl['url4']);
		
	$bbcode_tpl['user_email']="<a href=\"mailto:{EMAIL}\">{EMAIL}</A>";
	$bbcode_tpl['user_email'] = str_replace('{EMAIL}', '\\1', $bbcode_tpl['user_email']);


	// [url]xxxx://www.yuelao.net[/url] code..
	$patterns[1] = "#\[url\]([a-z]+?://){1}([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]+)\[/url\]#si";
	$replacements[1] = $bbcode_tpl['url1'];
		
	// [url]www.yuelao.net[/url] code.. (no xxxx:// prefix).
	$patterns[2] = "#\[url\]([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]+)\[/url\]#si";
	$replacements[2] = $bbcode_tpl['url2'];
		
	// [url=xxxx://www.yuelao.net]yuelao.net[/url] code..
	$patterns[3] = "#\[url=([a-z]+?://){1}([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]+)\](.*?)\[/url\]#si";
	$replacements[3] = $bbcode_tpl['url3'];
		
	// [url=www.yuelao.net]yuelao.net[/url] code.. (no xxxx:// prefix).
	$patterns[4] = "#\[url=([a-z0-9\-\.,\?!%\*_\#:;~\\&$@\/=\+]+)\](.*?)\[/url\]#si";
	$replacements[4] = $bbcode_tpl['url4'];
		
	// [user_email]user@domain.tld[/user_email] code..
	$patterns[5] = "#\[email\]([a-z0-9\-_.]+?@[\w\-]+\.([\w\-\.]+\.)?[\w]+)\[/email\]#si";
	$replacements[5] = $bbcode_tpl['user_email'];
    	$str = ' '.split_on_bbcodes(' '.$str);

	
	// sound
        $bbcode_tpl['stream']="<object id=\"wmp\" width={WIDTH} height={HEIGHT} classid=\"CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95\" 
	codebase=\"http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,0,0\" 
	standby=\"Loading Microsoft Windows Media Player components...\" type=\"application/x-oleobject\"> 
	<param name=\"FileName\" value=\"{URL}\"> 
	<param name=\"ShowControls\" value=\"1\"> 
	<param name=\"ShowDisplay\" value=\"0\"> 
	<param name=\"ShowStatusBar\" value=\"1\"> 
	<param name=\"AutoSize\" value=\"1\"> 
        <embed type=\"application/x-mplayer2\" 
	pluginspage=\"http://www.microsoft.com/windows95/downloads/contents/wurecommended/s_wufeatured/mediaplayer/default.asp\" 
	src=\"{URL}\" name=MediaPlayer2 showcontrols=1 showdisplay=0 showstatusbar=1 autosize=1 visible=1 animationatstart=0 transparentatstart=1 loop=0 height=70 width=300> 
	</embed></object>";
	$bbcode_tpl['video']="<div align=\"center\"><embed src=\"{URL}\" width={WIDTH} height={HEIGHT}></embed></div>";
        $bbcode_tpl['flash']="<OBJECT classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=5,0,0,0\" WIDTH={WIDTH} HEIGHT={HEIGHT}> 
	<PARAM NAME=movie VALUE=\"{URL}\"><PARAM NAME=quality VALUE=high> <PARAM NAME=scale VALUE=noborder> <PARAM NAME=wmode VALUE=transparent> <PARAM NAME=bgcolor VALUE=#000000> 
  	<EMBED src=\"{URL}\" quality=high scale=noborder wmode=transparent bgcolor=#000000 WIDTH={WIDTH} HEIGHT={HEIGHT} TYPE=\"application/x-shockwave-flash\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\">
	</EMBED></OBJECT>";

        $patterns[6] = "#\[stream\](.*?)\[/stream\]#si";
        // [stream]and[/stream]
        $replacements[6] = $bbcode_tpl['stream'];
        $replacements[6] = str_replace('{URL}', '\\1', $replacements[6]);
        // [flash width= height= loop= ] and [/flash] code..
        $patterns[7] = "#\[flash width=([0-6]?[0-9]?[0-9]) height=([0-4]?[0-9]?[0-9])\](.*?)\[/flash\]#si";
        //[flash width= heigth= loop=] and [/flash]
        $replacements[7] = $bbcode_tpl['flash'];
        $replacements[7] = str_replace('{WIDTH}', '\\1', $replacements[7]);
        $replacements[7] = str_replace('{HEIGHT}', '\\2', $replacements[7]);
        $replacements[7] = str_replace('{URL}', '\\3', $replacements[7]);

        // [flash width= height= loop= ] and [/flash] code..
        $patterns[8] = "#\[video width=([0-6]?[0-9]?[0-9]) height=([0-4]?[0-9]?[0-9])\](.*?)\[/video\]#si";
        //[video width= heigth=] and [/video]
        $replacements[8] = $bbcode_tpl['video'];
        $replacements[8] = str_replace('{URL}', '\\3', $replacements[8]);
        $replacements[8] = str_replace('{WIDTH}', '\\1', $replacements[8]);
        $replacements[8] = str_replace('{HEIGHT}', '\\2', $replacements[8]);
    	// colours
    	$patterns[] = '#\[color=(\#[0-9A-F]{6}|[a-z]+)\](.*?)\[/color\]#si';
    	$replacements[] = '<span style="color: \\1">\\2</span>';

    	// size
    	$patterns[] = '#\[size=([1-2]?[0-9])\](.*?)\[/size\]#si';
    	$replacements[] = '<span style="font-size: \\1px; line-height: normal">\\2</span>';

    	// [b] and [/b] for bolding text.
    	$patterns[] = '#\[b\](.*?)\[/b\]#si';
    	$replacements[] = '<span style="font-weight: bold">\\1</span>';

    	// [u] and [/u] for underlining text.
    	$patterns[] = '#\[u\](.*?)\[/u\]#si';
    	$replacements[] = '<span style="text-decoration: underline">\\1</span>';

    	// [i] and [/i] for italicizing text.
    	$patterns[] = '#\[i\](.*?)\[/i\]#si';
    	$replacements[] = '<span style="font-style: italic">\\1</span>';

    	// align
    	$patterns[] = '#\[align=(left|right|center|justify)\](.*?)\[/align\]#si';
    	$replacements[] = '<div style="text-align:\\1">\\2</div>';

        // [hr]
        $patterns[] = "#\[hr\]#si";
        $replacements[] = '<hr />';

        // marquee
        $patterns[] = "#\[marq=(left|right|up|down)\](.*?)\[/marq\]#si";
        $replacements[] = '<marquee direction="\\1" scrolldelay="60" scrollamount="1" onmouseover="this.stop()" onmouseout="this.start()">\\2</marquee>';

	// font
	$bbcode_tpl['font_open']="<span style=\"font-family:{FONT}\">";
	$bbcode_tpl['font_close']="</span>";
	$bbcode_tpl['font_open'] = str_replace('{FONT}', '\\1', $bbcode_tpl['font_open']);
        $str = preg_replace("/\[font=(.*?)\]/si", $bbcode_tpl['font_open'], $str);
        $str = str_replace("[/font]", $bbcode_tpl['font_close'], $str);
        // colours
        $bbcode_tpl['color_open']="<span style=\"color: {COLOR}\">";
        $bbcode_tpl['color_close']="</span>";
        $bbcode_tpl['color_open'] = str_replace('{COLOR}', '\\1', $bbcode_tpl['color_open']);
	$str = preg_replace("/\[color=(\#[0-9A-F]{6}|[a-z]+)\]/si", $bbcode_tpl['color_open'], $str);
	$str = str_replace("[/color]", $bbcode_tpl['color_close'], $str);

	// size
	$bbcode_tpl['size_open']="<span style=\"font-size: {SIZE}px; line-height: normal\">";
	$bbcode_tpl['size_close']="</span>";
	$bbcode_tpl['size_open'] = str_replace('{SIZE}', '\\1', $bbcode_tpl['size_open']);
	$str = preg_replace("/\[size=([\-\+]?[1-2]?[0-9])\]/si", $bbcode_tpl['size_open'], $str);
	$str = str_replace("[/size]", $bbcode_tpl['size_close'], $str);

	$str = preg_replace($patterns, $replacements, $str);
	//echo htmlspecialchars($str);
	return $str;
}