/**
	 * Callback for <WikiForumList> tag.
	 * Takes only the following argument: num (used as the LIMIT for the SQL query)
	 */
	public static function renderWikiForumList( $input, $args, $parser, $frame ) {
		global $wgLang;

		if ( !isset( $args['num'] ) ) {
			$args['num'] = 5;
		}

		$dbr = wfGetDB( DB_SLAVE );
		$sqlThreads = $dbr->select(
			array(
				'wikiforum_forums', 'wikiforum_category', 'wikiforum_threads',
				'user'
			),
			array(
				'*', 'wff_forum', 'wff_forum_name', 'wfc_category',
				'wfc_category_name', 'user_name'
			),
			array(
				'wff_deleted' => 0,
				'wfc_deleted' => 0,
				'wft_deleted' => 0,
				'wff_category = wfc_category',
				'wff_forum = wft_forum'
			),
			__METHOD__,
			array(
				'ORDER BY' => 'wft_last_post_timestamp DESC',
				'LIMIT' => intval( $args['num'] )
			),
			array( 'user' => array( 'LEFT JOIN', 'user_id = wft_user' ) )
		);

		$output = WikiForumGui::getMainPageHeader(
			wfMsg( 'wikiforum-updates' ),
			wfMsg( 'wikiforum-replies' ),
			wfMsg( 'wikiforum-views' ),
			wfMsg( 'wikiforum-latest-reply' )
		);

		foreach ( $sqlThreads as $thread ) {
			$icon = WikiForumClass::getThreadIcon(
				$thread->wft_posted_timestamp,
				$thread->wft_closed,
				$thread->wft_sticky
			);

			$lastpost = '';
			// If there are some replies, then we can obviously figure out who was
			// the last user who posted something on the topic...
			if ( $thread->wft_reply_count > 0 ) {
				$lastpost = wfMsg(
					'wikiforum-by',
					$wgLang->timeanddate( $thread->wft_last_post_timestamp ),
					WikiForumClass::getUserLinkById( $thread->wft_last_post_user )
				);
			}

			$specialPageObj = SpecialPage::getTitleFor( 'WikiForum' );
			// Build the links to the category and forum pages by using Linker
			$categoryLink = Linker::link(
				$specialPageObj,
				$thread->wfc_category_name,
				array(),
				array( 'category' => $thread->wfc_category )
			);
			$forumLink = Linker::link(
				$specialPageObj,
				$thread->wff_forum_name,
				array(),
				array( 'forum' => $thread->wff_forum )
			);
			$threadLink = Linker::link(
				$specialPageObj,
				$thread->wft_thread_name,
				array(),
				array( 'thread' => $thread->wft_thread )
			);

			$output .= WikiForumGui::getMainBody(
				'<p class="mw-wikiforum-thread">' . $icon . $threadLink .
				'<p class="mw-wikiforum-descr" style="border-top: 0;">' .
				wfMsg(
					'wikiforum-posted',
					$wgLang->timeanddate( $thread->wft_posted_timestamp ),
					WikiForumClass::getUserLink( $thread->user_name )
				) . '<br />' .
				wfMsgHtml( 'wikiforum-forum', $categoryLink, $forumLink ) .
				'</p></p>',
				$thread->wft_reply_count,
				$thread->wft_view_count,
				$lastpost,
				false,
				false
			);
		}
		$output .= WikiForumGui::getMainPageFooter();

		return $output;
	}
	function showForum( $forumId ) {
		global $wgOut, $wgLang, $wgUser, $wgRequest, $wgScriptPath;

		$output = $this->showFailure();
		$dbr = wfGetDB( DB_SLAVE );

		$f_movethread = $wgRequest->getInt( 'movethread' );

		// sorting
		if ( $wgRequest->getVal( 'sd' ) == 'up' ) {
			$sort_direction = 'ASC';
		} else {
			$sort_direction = 'DESC';
		}

		if ( $wgRequest->getVal( 'st' ) == 'answers' ) {
			$sort_type = 'wft_reply_count';
		} elseif ( $wgRequest->getVal( 'st' ) == 'calls' ) {
			$sort_type = 'wft_view_count';
		} elseif ( $wgRequest->getVal( 'st' ) == 'thread' ) {
			$sort_type = 'wft_thread_name';
		} else {
			$sort_type = 'wft_last_post_timestamp';
		}
		// end sorting

		$maxThreadsPerPage = intval( wfMsgForContent( 'wikiforum-max-threads-per-page' ) );

		// limiting
		if ( $maxThreadsPerPage && $wgRequest->getVal( 'lc' ) > 0 ) {
			$limit_count = $wgRequest->getVal( 'lc' );
		} elseif ( $maxThreadsPerPage > 0 ) {
			$limit_count = $maxThreadsPerPage;
		}

		if ( is_numeric( $wgRequest->getVal( 'lp' ) ) ) {
			$limit_page = $wgRequest->getVal( 'lp' ) - 1;
		} else {
			$limit_page = 0;
		}
		// end limiting

		$sqlData = $dbr->select(
			array( 'wikiforum_forums', 'wikiforum_category' ),
			array(
				'wff_forum', 'wff_forum_name', 'wfc_category',
				'wfc_category_name', 'wff_announcement'
			),
			array(
				'wff_deleted' => 0,
				'wfc_deleted' => 0,
				'wff_category = wfc_category',
				'wff_forum' => intval( $forumId )
			),
			__METHOD__
		);
		$data_overview = $dbr->fetchObject( $sqlData );

		$specialPage = SpecialPage::getTitleFor( 'WikiForum' );

		if ( $data_overview ) {
			$options['ORDER BY'] = 'wft_sticky DESC, ' . $sort_type . ' ' . $sort_direction;
			if ( $limit_count > 0 ) {
				$options['LIMIT'] = $limit_count;
				$options['OFFSET'] = $limit_page * $limit_count;
			}
			$forumIdNumber = $data_overview->wff_forum;
			$sqlThreads = $dbr->select(
				array( 'wikiforum_threads', 'user' ),
				array( '*', 'user_name' ),
				array( 'wft_deleted' => 0, 'wft_forum' => $forumIdNumber ),
				__METHOD__,
				$options,
				array( 'user' => array( 'LEFT JOIN', 'user_id = wft_user' ) )
			);

			$button['up'] = '<img src="' . $wgScriptPath . '/extensions/WikiForum/icons/bullet_arrow_up.png" alt="" />';
			$button['down'] = '<img src="' . $wgScriptPath . '/extensions/WikiForum/icons/bullet_arrow_down.png" alt="" />';

			// Non-moderators cannot post in an announcement-only forum
			if ( $data_overview->wff_announcement == true && !$wgUser->isAllowed( 'wikiforum-moderator' ) ) {
				$write_thread = '';
			} else {
				$icon = '<img src="' . $wgScriptPath . '/extensions/WikiForum/icons/note_add.png" title="' . wfMsg( 'wikiforum-write-thread' ) . '" /> ';
				$write_thread = $icon . '<a href="' . $specialPage->escapeFullURL( array( 'writethread' => $forumIdNumber ) ) . '">' .
					wfMsg( 'wikiforum-write-thread' ) . '</a>';
			}

			$output .= WikiForumGui::getSearchbox();
			$output .= WikiForumGui::getHeaderRow(
				$data_overview->wfc_category,
				$data_overview->wfc_category_name,
				$forumIdNumber,
				$data_overview->wff_forum_name,
				$write_thread
			);

			// @todo FIXME: the logic here seems wonky from the end-users point
			// of view and this code is horrible...
			$output .= WikiForumGui::getMainHeader(
				$data_overview->wff_forum_name . ' <a href="' .
					$specialPage->escapeFullURL( array( 'st' => 'thread', 'sd' => 'up', 'forum' => $forumIdNumber ) ) . '">' . $button['up'] .
					'</a><a href="' .
					$specialPage->escapeFullURL( array( 'st' => 'thread', 'sd' => 'down', 'forum' => $forumIdNumber ) ) . '">' . $button['down'] . '</a>',
				wfMsg( 'wikiforum-replies' ) . ' <a href="' .
				$specialPage->escapeFullURL( array( 'st' => 'answers', 'sd' => 'up', 'forum' => $forumIdNumber ) ) . '">' . $button['up'] .
				'</a><a href="' . $specialPage->escapeFullURL( array( 'st' => 'answers', 'sd' => 'down', 'forum' => $forumIdNumber ) ) . '">' . $button['down'] . '</a>',
				wfMsg( 'wikiforum-views' ) . ' <a href="' .
					$specialPage->escapeFullURL( array( 'st' => 'calls', 'sd' => 'up', 'forum' => $forumIdNumber ) ) . '">' . $button['up'] . '</a><a href="' .
					$specialPage->escapeFullURL( array( 'st' => 'calls', 'sd' => 'down', 'forum' => $forumIdNumber ) ) . '">' . $button['down'] . '</a>',
				wfMsg( 'wikiforum-latest-reply' ) . ' <a href="' .
					$specialPage->escapeFullURL( array( 'st' => 'last', 'sd' => 'up', 'forum' => $forumIdNumber ) ) . '">' . $button['up'] .
					'</a><a href="' . $specialPage->escapeFullURL( array( 'st' => 'last', 'sd' => 'up', 'forum' => $forumIdNumber ) ) . '">' . $button['down'] . '</a>',
				false
			);

			$threads_exist = false;
			foreach ( $sqlThreads as $thread ) {
				$threads_exist = true;
				$icon = $this->getThreadIcon(
					$thread->wft_posted_timestamp,
					$thread->wft_closed,
					$thread->wft_sticky
				);

				$last_post = '';
				if ( $thread->wft_reply_count > 0 ) {
					$last_post = wfMsg(
						'wikiforum-by',
						$wgLang->timeanddate( $thread->wft_last_post_timestamp ),
						WikiForumClass::getUserLinkById( $thread->wft_last_post_user )
					);
				}

				if ( $thread->wft_sticky == true ) {
					$sticky = 'sticky';
				} else {
					$sticky = false;
				}

				$output .= WikiForumGui::getMainBody(
					'<p class="mw-wikiforum-thread">' . $icon .
						'<a href="' . $specialPage->escapeFullURL( array( 'thread' => $thread->wft_thread ) ) . '">' .
							htmlspecialchars( $thread->wft_thread_name ) . '</a>
					<p class="mw-wikiforum-descr">' .
						wfMsg(
							'wikiforum-posted',
							$wgLang->timeanddate( $thread->wft_posted_timestamp ),
							WikiForumClass::getUserLink( $thread->user_name )
						) . '</p></p>',
					$thread->wft_reply_count,
					$thread->wft_view_count,
					$last_post,
					false,
					$sticky
				);

			}
			if ( $threads_exist == false ) {
				$output .= WikiForumGui::getSingleLine( wfMsg( 'wikiforum-no-threads' ), 4 );
			}
			$output .= WikiForumGui::getMainFooter();

			$countReplies = '';

			if ( $limit_count > 0 ) {
				$countReplies = $dbr->selectRow(
					'wikiforum_threads',
					array( 'COUNT(*) AS count' ),
					array(
						'wft_deleted' => 0,
						'wft_forum' => intval( $data_overview->wff_forum )
					),
					__METHOD__
				);
				$output .= WikiForumGui::getFooterRow(
					$limit_page,
					( isset( $countReplies->count ) ? $countReplies->count : 0 ),
					$limit_count,
					$data_overview->wff_forum
				);
			}
		} else {
			$this->errorTitle = wfMsg( 'wikiforum-forum-not-found' );
			$this->errorMessage = wfMsg(
				'wikiforum-forum-not-found-text',
				'<a href="' . $specialPage->escapeFullURL() . '">' .
					wfMsg( 'wikiforum-overview' ) . '</a>'
			);
		}

		$pastethread_link = '';
		if ( $f_movethread > 0 ) {
			$icon = '<img src="' . $wgScriptPath . '/extensions/WikiForum/icons/paste_plain.png" title="' . wfMsg( 'wikiforum-paste-thread' ) . '" /> ';
			$pastethread_link = $icon . '<a href="' . $specialPage->escapeFullURL( array( 'pastethread' => $f_movethread ) ) . '">' . wfMsg( 'wikiforum-paste-thread' ) . '</a> ';
			$output .= WikiForumGui::getHeaderRow( 0, '', 0, '', $pastethread_link );
		}

		$output .= $this->showFailure();
		return $output;
	}