<?php
defined('WikyBlog') or die('Not an entry point...');

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 				Send A Normal Page
//

//template has to be included from outside of the $page object because of the scope of the $page variable
function includeTemplate(&$template){
	global $page,$pageOwner,$dbObject,$serverName1;
	include($template);
}

function evalTemplate($template){
	global $page,$pageOwner,$dbObject,$serverName1;
	eval('?'.'>'.$template.'<'.'?php ');
}

class wbPageNormal extends page{
	var $templateDir;
	var $cssLocation;
	var $css2Location = false;
	var $scriptInline = array();
	var $NormLinkPrefix;
	var $NormDirPrefix;
	
	function wbPageNormal(){
		global $wbLinkPrefix, $wbDirPrefix;
		$this->NormLinkPrefix = $wbLinkPrefix;
		$this->NormDirPrefix = $wbDirPrefix;
		parent::page();
	}
	
	
	function send(){
		global $rootDir,$includeDir,$jsNum,$langA,$userLanguage,$pageOwner,$dbObject,$processTotals,$wbConfig;
		global $wbNow,$wbMaintain,$wbLinkPrefixStor, $wbLinkPrefix;
	
			//!! version 1.7.2
			$this->HeadArray = $this->htmlHead; //for backwards compat
			
		////////	Powered By
			
			$temp[] = '<a href="http://www.wikyblog.com" title="WikyBlog, not exactly a wiki, not exactly a blog." >WikyBlog</a>';
			if( isset($wbConfig['poweredBy']) ){
				$temp += $wbConfig['poweredBy'];
			}
			$GLOBALS['pageFooter'][] = 'Powered by '.implode(', ',$temp);
			unset($temp);

							
		////////	WBExtras
			$this->extras = '<div id="WBextras" style="height:0px;width:0px;">';
			//$this->extras .= '<div id="WBajaxMsgs" style="display:none;position:absolute;z-index:10000;right:0;top:0;" onclick="WBm.CA()"></div>';
			//$this->extras .= '<div id="WBloading" style="display:none;position:absolute;z-index:10000;right:0;top:0;" onclick="WBm.CB()"></div>';
			$this->extras .= '<span id="WBextrasBox"></span>';
			
			if( is_array($wbMaintain) ){
				$this->extras .= '<img src="'.wbLinks::getDir('/include/maintenance/scheduledTasks.php').'" width="1" height="1" border="0" alt="" />';
			}
			
			$this->extras .= '</div>';
			
		////////	Meta Keywords ..limt at 10 keywords
			if( is_array($this->metaKeywords) && count($this->metaKeywords) > 0 ){
				$keys = array();
				foreach($this->metaKeywords as $key){
					if( empty($key)){
						continue;
					}
					$key = toDisplay($key);
					$pos = strpos($key,'(');
					if( $pos !== false){
						$key = substr($key,0,$pos);
					}
					$key = trim($key);
					
					if( !isset($keys[$key]) ){
						$keys[$key] = 0;
					}
					$keys[$key]++;
				}
				arsort($keys);
				$i = 0;
				$temp = '';
				foreach($keys as $key => $num){
					if( $i < 10){
						$temp .= $key.',';
					}
					$i++;
				}
				$this->HeadArray[] = '<meta name="keywords" content="'.str_replace('"','&quot;',$temp).'" />';
			}
	
		////////	Footer
			$this->setFooter();
	
		////////	Style
			$WikyBlogStyle = '<style type="text/css" >/*<![CDATA[*/ @import "'. wbLinks::getDir('/include/js/style.css?'.$jsNum) .'"; /*]]>*/</style>';
			$this->style = $WikyBlogStyle;
			$this->StyleUpdated = $WikyBlogStyle; //the same as $this->style, but it won't have css2 because the two files have been joined into one V1.7.1.2
			
			if( !empty($this->styles) ){
				$this->styles = array_unique($this->styles);
				foreach($this->styles as $style){
					$this->style .= '<style type="text/css" >/*<![CDATA[*/ @import "'. wbLinks::getDir($style) .'"; /*]]>*/</style>';
					$this->StyleUpdated .= '<style type="text/css" >/*<![CDATA[*/ @import "'. wbLinks::getDir($style) .'"; /*]]>*/</style>';
				}
			}
			//theme's css files after, so user's can overwrite declarations
			if( isset($this->cssLocation) ){
				$css1 = '<style type="text/css" >/*<![CDATA[*/ @import "'.$this->cssLocation.'"; /*]]>*/</style>';
				$this->style .= "\n".$css1."\n";
				$this->StyleUpdated .= "\n".$css1."\n";
				if( $this->css2 && $this->css2Location ){
					$this->style .= '<style type="text/css" >/*<![CDATA[*/ @import "'.$this->css2Location.'"; /*]]>*/</style>';
					$this->style .= "\n";
				}
			}
			
	
		////////	JavaScript::Inline
		//				Has to be before files so that these global variables are available
		//
		//
	
			$this->scriptInline[] = 'var lg=Array()';//just to prevent errors
			$this->scriptInline[] = 'var WB=new Object()';
			$this->scriptInline[] = 'var WBe=false';
			$this->scriptInline[] = 'var TS=false';
			$this->scriptInline[] = 'WB.status=0';
		
	
			//these session values need to be set for javascript and anonymous users
			//$_SESSION += array('ajax'=>'On', 'nWin'=>'Off', 'scrl'=>'Off', 'nTabs'=>7, 'shortK'=>'alt');
			$_SESSION += array('ajax'=>'Off', 'nWin'=>'Off', 'scrl'=>'Off', 'nTabs'=>7, 'shortK'=>'alt');
					
			//WB object
			$this->scriptInline[] = 'WB.ajax="'.$_SESSION['ajax'].'"';			//which level of ajax
			$this->scriptInline[] = 'WB.ul='.(string)$_SESSION['userlevel'];		//tells javascript when it can warn when an error occurs
			
			$this->scriptInline[] = 'WB.tabs='.$_SESSION['nTabs']; 				//number of tabs to keep open
			$this->scriptInline[] = 'WB.win="'.$_SESSION['nWin'].'"';			//open external links in new windows
			$this->scriptInline[] = 'WB.sc="'.$_SESSION['scrl'].'"';				//enhanced scroll
			$this->scriptInline[] = 'WB.sk="'.$_SESSION['shortK'].'"'; 				//javascript escape key sequence
			
			$this->scriptInline[] = 'WB.shn = "'.$wbLinkPrefixStor.$this->showId.'"';
			$this->scriptInline[] = 'WB.nJs="'.$jsNum.'"';
			$this->scriptInline[] = 'WB.own="'.$pageOwner['user_id'].'"';
			
			// used by watchlist check
			// if( isset($_SESSION['username'])){
			// 	$this->scriptInline[] = 'WB.user="'.$_SESSION['username'].'"';
			// 	if( isset($_SESSION['checked']) ){
			// 		$this->scriptInline[] = 'WB.chck="'.$_SESSION['checked'].'"';
			// 	}else{
			// 		$this->scriptInline[] = 'WB.chck=""';
			// 	}
			// }else{
			// 	$this->scriptInline[] = 'WB.user=false';
			// 	$this->scriptInline[] = 'WB.chck=false';
			// }
			
			// $this->scriptInline[] = 'WB.lPrefix="'.wbStrtolower($GLOBALS['wbLinkPrefix']).'"';
			// $this->scriptInline[] = 'WB.dPrefix="'.$GLOBALS['wbDirPrefix'].'"';
			$this->scriptInline[] = 'WB.lPrefix="'.wbStrtolower($this->NormLinkPrefix).'"';
			$this->scriptInline[] = 'WB.dPrefix="'.$this->NormDirPrefix.'"';
			
	
				
			$this->HeadArray[] = '<script language="JavaScript" type="text/javascript">/*<![CDATA[*/';
			$this->HeadArray[] = implode(";\n",$this->scriptInline).';';
			$this->HeadArray[] = '/*]]>*/</script>';
		
	////////	JavaScript::Files
			// if( defined('wbDebug') && wbDebug == true){
			// 	$this->scripts[] = '/include/js/x_test.js?'.$jsNum;
			// }
	
			// Load Scripts
			$this->scripts[] = '/include/lang/'.$userLanguage.'/lang.js?n='.$jsNum;
			//$this->scripts[] = '/include/js/main.js?'.$jsNum; //the last one sent!
			$this->scripts[] = '/include/js/main_combined.js?'.$jsNum; //the last one sent!
			
			//version 1.6 upgrade
			if( isset($pageOwner['imgs']) || isset($pageOwner['files']) ){
				if( isOwner(false,true,false) ){
					$link = $wbLinkPrefix.'/Attach/'.$pageOwner['username'].'?cmd=upgrade';
					$this->HeadArray[] = '<script language="JavaScript" type="text/javascript" src="'. $link .'"></script>';
				}
			}
			
			
			$this->scripts = array_unique($this->scripts);
			foreach($this->scripts as $value){
				$this->HeadArray[] = '<script language="JavaScript" type="text/javascript" src="'. wbLinks::getDir($value) .'"></script>';
			}
				
		////////	pngfix
			$this->HeadArray[] = '<!--[if lt IE 7.]>';
			$this->HeadArray[] = '<script language="JavaScript" type="text/javascript" src="'.wbLinks::getDir('/include/js/pngfix.js?'.$jsNum).'"></script>';
			$this->HeadArray[] = '<![endif]-->';
			
			
			//elements with the noscript class will be hidden if the user's browser does not have javascript
			//	.noScript, .scriptOnly	used to hide elements that are only usable when javascript is enabled
			//	.scriptHide			used to hide elements that will be shown later using javascript onmouseover and onclicks
			//	.loadHide				hides elements only when javascript is enabled 
			$this->HeadArray[] = '<style type="text/css" >.noscript, .scriptOnly, .scriptHide{display:none;}</style>'; //!! scriptOnly is a better name.. phase out .noscript
			
			//moved to xmlHttp.js
			//$this->HeadArray[] = '<script type="text/javascript">/*<![CDATA[*/';
			//$this->HeadArray[] = 'document.write("<style type=\'text/css\'>")';
			//$this->HeadArray[] = 'if(typeof(document.getElementById)!="undefined") document.write(".loadHide{display:none;}");';
			//$this->HeadArray[] = 'document.write(" .noscript, .scriptOnly{display:block !important;}");'; 
			//$this->HeadArray[] = 'document.write("</style>");';
			//$this->HeadArray[] = '/*]]>*/</script>';
			
			
		////////	rss links
			$this->HeadArray['rss'] = '<link href="'.wbLinks::getUrl('/Special/'.$pageOwner['username'].'/atom?field=blog').'" rel="alternate" title="Blog Feed for '.$pageOwner['username'].'" type="application/rss+xml" />';
			$this->HeadArray['rss'] .= '<link href="'.wbLinks::getUrl('/Special/'.$pageOwner['username'].'/atom').'" rel="alternate" title="Recently Modified Feed for '.$pageOwner['username'].'" type="application/rss+xml" />'; //!!lang
			$this->HeadArray['rss'] .= '<link href="'.wbLinks::getUrl('/Special/'.$pageOwner['username'].'/atom?field=1').'" rel="alternate" title="Recently Posted Feed for '.$pageOwner['username'].'" type="application/rss+xml" />';
		
		////////	favicon
			$this->HeadArray[] = '<link rel="shortcut icon" href="'. wbLinks::getDir('/favicon.ico') .'" type="image/x-icon" />';

		////////	htmlhead
			$this->HeadArray[] = '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />';
			$this->htmlHead = implode("\n",$this->HeadArray);

			
		////////	DisplayTitle
			if( !isset($this->displayTitle2)){
				if( empty($this->displayTitle) ){
					reset($this->rActions);
					$this->displayTitle2 = current($this->rActions);
				}else{
					$this->displayTitle2 = strip_tags($this->displayTitle);
				}
			}
			
				
		////////	Get the Template
			global $serverName1,$serverName2,$serverName3;
	
			echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >';
			echo "\n";
			
			if( isset($dbObject->isTemplate) && $dbObject->isTemplate && $dbObject->exists ){
				evalTemplate($dbObject->returnPageTemplate());
			}else{
				includeTemplate($this->templateDir);
			}
	}
	
	//!!version 1.7.1.2
	//		some of the work done in send() should be done here instead once user themes have been updated.
	function htmlHead(){
		
		unset($this->HeadArray['rss']);
		
		echo implode("\n",$this->HeadArray);
		echo "\n";
		echo $this->StyleUpdated;
		
		
		//once user themes are updated, this can be removed with any use of style2 or css2
		if( $this->css2 && $this->css2Location ){
			echo '<script language="JavaScript" type="text/javascript">/*<![CDATA[*/';
			echo ' var style2=false';
			echo '/*]]>*/</script>';
		}
	}
	
	
	//	Meta Keywords
	//
	function addMeta(&$arg){
		if( is_string($arg) ){
			$this->metaKeywords[] = strip_tags($arg);
		}elseif( is_array($arg)){
			$this->metaKeywords = array_merge( (array)$this->metaKeywords, (array)$arg);
		}
	}
	
	function prepPage(){
		global $langA;
		parent::prepPage();
		
		//Add a tab and content area for messages when there are no content areas
		$areaCount = 0;
		foreach($this->rActions as $url => $label){
			if( empty($this->contentA[$label]) && empty($this->contentB[$url]) ){
				continue;
			}
			$areaCount++;
			break;
		}
		if( $areaCount == 0 ){
			$this->rActions['/'] = $langA['messages'];
			$this->contentB['/'] = '&nbsp;';
		}
	}
		
	
	function displayPage(){
		global $langA,$wbLinkPrefixStor,$wbMessageBuffer;

		// Content Areas
		echo '<div id="WBcontentAreas">';
			if( !empty($this->formAction) ){
				$id = 'WBform'.$wbLinkPrefixStor.toStorageUrl($this->formAction);
				echo '<form onsubmit="return WB.RS(event)" method="'.$this->formMethod.'" action="'. wbLinks::getUrl($this->formAction) .'" enctype="'.$this->formEnc.'" id="'.$id.'">';
			}

				foreach($this->rActions as $url => $label){
					if( empty($this->contentA[$label]) && empty($this->contentB[$url]) ){
						continue;
					}
					$storUrl = toStorageUrl(wbLinks::escape($url));

					
					echo '<div class="WBcontentArea" id="WBbox'.$wbLinkPrefixStor.$storUrl.'">';
					echo $this->displayContentArea($label,$url);
					echo '</div>';	

				}
				
			if( !empty($this->formAction) ){
				echo '</form>';
			}
		echo '</div>'; //end WBcontentAreas
		global $wbDirPrefix;
		
		// style="width:0px;height:0px;border:0px" 
		// don't use display:none
		echo '<iframe style="width:0px;height:0px;border:0px" name="WBhistory" id="WBhistory" src="'.$wbDirPrefix.'/include/js/WBblank2.html#'.$this->showId.'" ></iframe>';//onload="iframeLoad()"
		//echo '<iframe style="width:100%;height:100px;border:1px solid #cccccc;" name="WBhistory" id="WBhistory" src="'.$wbDirPrefix.'/include/js/WBblank2.html#'.$this->showId.'" ></iframe>';//onload="iframeLoad()"

		echo '<form action="/" method="post" name="WBFormHistory" style="display:none">';
		echo '<input type="text" name="a" value="'.wbHtmlspecialchars($wbLinkPrefixStor.$this->showId).'" />';
		echo '<input type="text" name="b" value="" />';
		echo '</form>';

		//	used by javascript to add the "loading" window
		//	and the "load" text next to the cursor
		if( is_array($this->contentXml) ){
			foreach($this->contentXml as $urlKey => $xml){
				echo '<textarea id="WBxml'.$urlKey.'" cols="90" rows="10" style="display:none">';
				echo $xml;
				echo '</textarea>';
			}
		}
		echo '<div id="WBloaded"></div>'; //used by javascript
	}
	
	
	//	Actions ie Tabs
	//
	function displayActions(){
		global $pageOwner,$dbObject,$langA,$wbConfig,$userLanguage,$serverName3,$wbLinkPrefixStor;
		global $wbTabHtml,$wbLinkFormat,$dbInfo;
		
		
		//
		//	Format for wbActions
		//
		$actionsTag = 'div';
		switch($wbTabHtml){
			case 2:
				$wbTabHtml = '<li title="%4$s" %1$s><a %2$s>%3$s</a></li>';
				$actionsTag = 'ul';
			break;
			case 1:
				$wbTabHtml = '<a title="%4$s" %1$s %2$s><span class="tabLeft">%3$s</span><span class="tabRight">&nbsp;</span></a>';
			break;
			default:
				$wbTabHtml = '<a title="%4$s" %1$s %2$s>%3$s</a>';
			break;
		}
		echo "\n".'<script language="JavaScript" type="text/javascript">/*<![CDATA[*/';
		echo 'var tabHtml = "'.str_replace('"','\"',$wbTabHtml).'";';
		echo '/*]]>*/</script>'."\n";

		if( isset($pageOwner['data2']['tabs']) ){
			$list =& $pageOwner['data2']['tabs'];
		}else{
			$list['/Special/'.$pageOwner['username'].'/ControlPanel']= 'control_panel';
			$list['/Special/'.$pageOwner['username'].'/ChangeLog']= 'change_log';
		
			$list['/Special/'.$pageOwner['username'].'/BrowsePages']= $langA['browse'].' '.$langA['CLASSpage'];
		}

		
		$lowerList = array();
		foreach($this->rActions as $url => $label){
			$lowerList[wbStrtolower($url)] = $label;
		}
		
		$tabLinks = $this->rActions;
		foreach($list as $url => $label){
			if( isset($lowerList[wbStrtolower($url)]) ){
				continue;
			}
			if( isset($langA[$label]) ){
				$tabLinks[$url] = $langA[$label];
			}else{
				$tabLinks[$url] = $label;
			}
		}
		
		$tabLinks['/Help/'.$userLanguage.'/'.$langA['home'].'?en=Home'] = '?';
		$tabLinks = array_unique($tabLinks);
		
		echo '<'.$actionsTag.' id="WBactions" class="WBactions" style="position:relative;">';
		$shownTab = false;
		foreach($tabLinks as $url => $label){
			$class = ' class="WBcontentTab" ';
			$attribute = '';
			
			if( !empty($this->contentA[$label]) || !empty($this->contentB[$url]) ){
				if( !$shownTab ){
					$class=' class="WBcontentTabShow" ';
					$shownTab = true;
				}else{
					$class=' class="WBcontentTabHide" ';
				}
			}
			if( wbStrpos($url,'#WBnone') !== false){
				$attribute = ' name="none"';
			}
			
			if( wbStrlen($label) > 18){
				$shortLabel = wbSubstr($label,0,15).'...';
			}else{
				$shortLabel = $label;
			}
			
			
			//
			//	An attempt at a more complex tab area
			//
			if( $label == '?' ){
				if( $pageOwner['ihelp'] == 'Off' ){
					continue;
				}
			}
			
			//$url = str_replace('&','&amp;',$url);
			$url = wbLinks::escape($url);
			//$storUrl = toStorageUrl($url);
			if( ($label == '?') && isset($wbConfig['helpServer']) && ($serverName3 !== $wbConfig['helpServer'])){
				$storUrl = toStorageUrl($wbConfig['helpServer']).toStorageUrl($url);
				$href = ' href="'.$wbConfig['helpServer'].$url.'" rev="'.$storUrl.'"'.$attribute;
				$id = ' id="WBtab'.$storUrl.'" '.$class;
			}else{
				if( ($label == '?') && !isset($dbInfo['help']) ){
					continue;
				}
				
				//$href = ' '.wbLinks::local($url,false).$attribute;
				$storUrl = toStorageUrl($url);
				$href = ' '.sprintf($wbLinkFormat,$url,$storUrl,'').$attribute;
				$id = ' id="WBtab'.$wbLinkPrefixStor.$storUrl.'" '.$class;
			}
			echo sprintf($wbTabHtml,$id,$href,$shortLabel,$label);
			//echo str_replace(array('%s1','%s2','%s3','%s4'),array($id,$href,$shortLabel,$label),$wbTabHtml);
		}
		
		echo '</'.$actionsTag.'>';
		return;
	}
	
	////////	Page Footer
	//version 0.10
	//templates will call getFooter() instead of echoing $page->footer
	//so we wont have to set $page->footer
	//	
	function getFooter(){
		return $this->footer;
	}
	
	function setFooter(){
		global $processTotals,$langA;
		
		// $queryPercent = round(($processTotals['queryTimes']/$duration)*100);
// 		$duration = microtime_diff($processTotals['request'], microtime());
// 		$GLOBALS['pageFooter'][] = $duration.$langA['seconds'];
// 		$GLOBALS['pageFooter'][] = $processTotals['numQueries'].$langA['queries'];
		
		$this->footer = '<span>'.implode('</span><span>',$GLOBALS['pageFooter']).'</span>';
	}
	
	function search(){
		global $pageOwner,$langA,$wbConfig;
		
		if( !isset($wbConfig['search']) || !$wbConfig['search']){
			return;
		}
		
		$action = wbLinks::getUrl('/Special/'.$pageOwner['username'].'/Search');
		echo '<form onsubmit="return WB.RS(event)" action="'.$action.'" method="get" enctype="application/x-www-form-urlencoded">';
		echo '<input type="text" name="nothing" value="" size="5"  style="display:none" />'; //so that explorer will react correctly with a return
		echo '<ul>';
		echo '<li><input type="text" name="key" size="30" /></li>';
		echo '<li><input type="submit" name="search" value="'.$langA['search'].'" class="submit" /></li>';
		echo '</ul>';
		echo '</form>';
		
	}
	
	//
	//	Set the template information early so we can set lastModSalts
	//
	
	function setTemplate(){
		global $pageOwner,$rootDir,$dbObject;
		$template = false;
		$css = true;
		
		
		//
		//	CLASStemplates
		//	
			
			if( isset($dbObject->isTemplate) && $dbObject->isTemplate){
				$temp['template'] = $dbObject->owner.'/'.$dbObject->title;
				$template = whichTemplate($temp);
				$this->scriptInline[] = 'var style2=false';
				return;
			}
			
		//
		//	$pageOwner['template']
		//	
		
			if( isset($pageOwner['template']) && !empty($pageOwner['template']) ){
				
				$template = whichTemplate($pageOwner);
			}
			
		//
		//	Set location values
		//	
			
			if( is_array($template) ){
				$this->templateDir = $rootDir.'/templates/'.$template['templateNameLow'].'/template.php';
				if( $css ){
					$this->cssLocation = wbLinks::getDir('/templates/'.$template['templateNameLow'].'/style1.css?mod='.$template['modified']);
					$this->scriptInline[] = 'var style2="'.'/templates/'.wbStrtolower($template['templateName']).'/style2.css?mod='.$template['modified'].'"';
					$this->css2Location = wbLinks::getDir('/templates/'.wbStrtolower($template['templateName']).'/style2.css?mod='.$template['modified']);
				}
				if( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ){
					$this->lastModSalts[] = $template['modified'];
				}
				return;
			}
			
			//we don't need lastModSalts because the ownerSalt is changed when a template is changed.
			if( isset($pageOwner['pTemplate']) && $pageOwner['pTemplate'] != ''){
				//version 1.3.3
				$temp =& $pageOwner['pTemplate'];
				switch($temp){
					case 'default':
						$temp = 'default/blue';
					break;
					case 'simple_tan';
						$temp = 'simple/tan';
					break;
					case 'three_columns':
						$temp = 'three_columns/light_blue';
					break;
				}
				$this->packageTemplate($temp);
				return;
			}
			$this->packageTemplate('graphic/blue');
	}
	
	function packageTemplate($which){
		global $jsNum,$includeDir;
		$this->templateDir = $includeDir.'/themes/'.dirname($which).'/template.php';
		$this->cssLocation = wbLinks::getDir('/include/themes/'.$which.'/style1.css?r='.$jsNum);
		$this->scriptInline[] = 'var style2=false';
	}
	
	function saltMod($timestamp){
		if( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ){
			$this->lastModSalts[] = dbFromDate($timestamp,'unix');
		}
	}
	
	function saltModJS(){
		global $jsNum;
		if( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ){
			$this->lastModSalts[] = 883637000-$jsNum;
		}
	}
	
	// calls from templates need to be updated
	/* static */
	function getLinks(){
		global $pageOwner, $page;
		
		echo '<div id="WB.Links" style="position:relative">';
		
		if( !isset($pageOwner['data2']['links']) ){
			echo '</div>';
			return;
		}
		if( !is_array($pageOwner['data2']['links']) ){
			echo '</div>';
			return;
		}
		
		
		foreach($pageOwner['data2']['links'] as $groupName => $linkData){
			if( !isset($pageOwner['data2']['groups'][$groupName]) ){
				continue;
			}
			$groupData =& $pageOwner['data2']['groups'][$groupName];
			if( isset($groupData['order']) && $groupData['order'] === 'random'){
				$links = $linkData;
				shuffle($links);
			}else{
				$links =& $linkData;
			}
			$links =& $linkData;
			echo '<div class="sideMenuArea">';
			echo '<b>'.$groupName.'</b>';
			echo '<ul>';
			foreach($links as $i => $linkArray){
				echo '<li>';
				
				$attr = '';
				if( !empty($linkArray['desc']) ){
					$attr = ' title="'.$linkArray['desc'].'"';
				}
				
				if( isset($linkArray['intern']) ){
					echo wbLinks::local($linkArray['uri'],$linkArray['label'],$attr);
					
				}elseif( isset($linkArray['attach']) ){
					echo '<a href="'.wbLinks::getDir($linkArray['uri']).'"';
					echo ' rev="'.$page->revType.'" ';
					echo $attr;
					if( $page->nofollow ){
						echo ' rel="nofollow" ';
					}
					echo '>'.$linkArray['label'].'</a>';
					
				}elseif( isset($linkArray['otheruser']) ){
					
					echo '<a href="'.wbLinks::getUrl($linkArray['uri']).'"';
					echo ' class="otheruser" ';
					echo $attr;
					if( $page->nofollow ){
						echo ' rel="nofollow" ';
					}
					echo '>'.$linkArray['label'].'</a>';
					
				}else{
					echo '<a href="'.wbLinks::escape($linkArray['uri']).'" class="external"';
					//echo '<a href="'.str_replace('&','&amp;',$linkArray['uri']).'" class="external"';
					echo $attr;
					if( $page->nofollow ){
						echo ' rel="nofollow" ';
					}
					echo '>'.$linkArray['label'].'</a>';
				}
				
				echo '</li>';
				if( isset($groupData['limit']) && ($i >= ($groupData['limit']-1)) ){
					break;
				}
			}
			echo '</ul>';
			echo '</div>';
			
		}
		echo '</div>';
	}
	
	function userMenu(){
		global $langA;
		echo '<div class="sideMenuArea" id="WB.UserMenu" style="position:relative">';
		echo '<b>'.$langA['user_menu'].'</b>';
		echo '<div id="WBuserMenu">';
		getUserMenu();
		echo '</div></div>';
	}
	
	function getKeywords(){
		global $langA;
		echo '<div class="sideMenuArea" id="WB.Keywords" style="position:relative">';
		//echo '<b onclick="WB.SA(this.nextSibling.firstChild)">'.$langA['keywords'].'</b>';
		echo '<b>'.$langA['keywords'].'</b>';
		echo '<div id="WBkeywords">';
		getKeywords();
		echo '</div></div>';
	}
	
	function getNavBar(){
		global $langA;
		echo '<div id="WBnavbar" style="position:relative">';
		echo $this->navbar;
		echo '</div>';
	}
	
}
