<?php
/**
 * NextBestNetwork - Tweaked version of Vector, using Twitter Bootstrap.

 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 * @ingroup Skins
 */

use MediaWiki\Linker\Linker;
use MediaWiki\MediaWikiServices;
use MediaWiki\Session\SessionManager;
use MediaWiki\Title\Title;

/**
 * QuickTemplate subclass for Vector
 * @ingroup Skins
 */
class NextBestNetworkTemplate extends BaseTemplate {

	/* Functions */

	/**
	 * Outputs the entire contents of the (X)HTML page
	 */
	public function execute() {
		$this->data['namespace_urls'] = $this->data['content_navigation']['namespaces'];
		$this->data['view_urls'] = $this->data['content_navigation']['views'];
		$this->data['action_urls'] = $this->data['content_navigation']['actions'];
		$this->data['variant_urls'] = $this->data['content_navigation']['variants'];
		$this->data['watch_urls'] = [];
		if( $GLOBALS['wgNextBestNetworkSkinUseRealnames'] == true && $this->data['username'] ) {
			$this->data['username'] = NextBestNetworkHooks::getRealname( $this->data['username'] );
		}
		$this->data['advanced'] = MediaWikiServices::getInstance()->getUserOptionsLookup()->getOption( $this->getSkin()->getUser(), 'nextbestnetwork-advanced' );


		// Remove the watch/unwatch star from the "actions" menu
		if ( $this->config->get( 'NextBestNetworkSkinUseIconWatch' ) ) {
			if ( method_exists( MediaWikiServices::class, 'getWatchlistManager' ) ) {
				// MediaWiki 1.36+
				$watchlistManager = MediaWikiServices::getInstance()->getWatchlistManager();
				$watched = $watchlistManager->isWatched( $this->getSkin()->getUser(), $this->getSkin()->getRelevantTitle() );
			} else {
				$watched = $this->getSkin()->getUser()->isWatched( $this->getSkin()->getRelevantTitle() );
			}

			$mode = $watched ? 'unwatch' : 'watch';

			if ( isset( $this->data['action_urls'][$mode] ) ) {
				$this->data['watch_urls'][$mode] = $this->data['action_urls'][$mode];
				unset( $this->data['action_urls'][$mode] );
			}
		}
		$this->data['pageLanguage'] =
			$this->getSkin()->getTitle()->getPageLanguage()->getHtmlCode();

		//set userStateClass
		if ( $this->data['loggedin'] ) {
			$this->data['userstateclass'] = "user-loggedin";
		} else {
			$this->data['userstateclass'] = "user-loggedout";
		}

		if ( ( isset( $this->config->get( 'GroupPermissions' )['*']['edit'] ) && $this->config->get( 'GroupPermissions' )['*']['edit'] ) || $this->data['loggedin'] ) {
			$this->data['userstateclass'] .= " editable";
		} else {
			$this->data['userstateclass'] .= " not-editable";
		}

		//set 'namespace' and 'title_formatted' variables
		$this->data['title_formatted'] = $this->data['title'];
		$this->data['namespace'] = str_replace( "_", " ", $this->getSkin()->getTitle()->getNsText() );

		// the following is obsolete since MW 1.39, namespace and separator have their own spans
		if( strpos( $this->data['title_formatted'], $this->data['namespace'] . ':' ) === 0 ) {
			$this->data['title_formatted'] = '<span class="namespace">' . $this->data['namespace'] . ":</span> " . str_replace( $this->data['namespace'] . ':', '', $this->data['title_formatted'] );
		}

		call_user_func_array( $this->config->get( 'NextBestNetworkSkinPageRenderer' ), [ $this ] );
?>
	</body>
</html>
<?php
	}


	/**
	 * Render the whole page
	 *
	 * Copy this function and use $wgNextBestNetworkSkinPageRenderer to create
	 * completely custom page layouts
	 *
	 * @param $skin Skin skin object
	 */
	public static function renderPage( $skin ) {
		// load defaults for layout without sidebar
		$main_offset = $skin->getConfig( 'NextBestNetworkSkinGridNone' )['mainoffset'];
		$main_width = $skin->getConfig( 'NextBestNetworkSkinGridNone' )['mainwidth'];
		$left_width = 0;
		$left_offset = 0;
		$right_width = 0;
		$right_offset = 0;
		// TODO: check for situational emptiness of sidebar (e.g. on special pages)
		if( true ) {
			$sidebar_left = $skin->checkVisibility( 'sidebar-left' ) && !$skin->checkEmptiness( 'sidebar-left' );
			$sidebar_right = $skin->checkVisibility( 'sidebar-right' ) && !$skin->checkEmptiness( 'sidebar-right' );
			if( $sidebar_left && $sidebar_right ) { // both sidebars
				$left_offset = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['leftoffset'];
				$left_width = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['leftwidth'];
				$main_offset = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['mainoffset'];
				$main_width = $skin->config->get( 'NextBestNetworkSkinGridBoth' )['mainwidth'];
				$right_offset = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['rightoffset'];
				$right_width = $skin->getConfig( 'NextBestNetworkSkinGridBoth' )['rightwidth'];
			}
			if( $sidebar_left XOR $sidebar_right ) { // only one of the sidebars
				if( $sidebar_left ) {
					$left_offset = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['leftoffset'];
					$left_width = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['leftwidth'];
					$main_offset = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['mainoffset'];
					$main_width = $skin->getConfig( 'NextBestNetworkSkinGridLeft' )['mainwidth'];
				} else {
					$main_offset = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['mainoffset'];
					$main_width = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['mainwidth'];
					$right_offset = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['rightoffset'];
					$right_width = $skin->getConfig( 'NextBestNetworkSkinGridRight' )['rightwidth'];
				}
			}
		}

		$contentclass = $skin->data['userstateclass'];
		$contentclass .= ' ' . wfMessage( 'nextbestnetwork-container-class' )->escaped();
		$contentclass .= ( $skin->checkVisibility( 'navbar' ) ) ? ' with-navbar' : ' without-navbar';

		if( false !== stripos( wfMessage( 'nextbestnetwork-navbar-class' ), 'fixed' ) ) {
			$contentclass .= ' with-navbar-fixed';
		}

		$mainclass = 'col-md-' . $main_width;
		if( $main_offset > 0 ) {
			$mainclass .= ' offset-md-' . $main_offset;
		} elseif( $main_width == 12 ) {
			$mainclass = 'col';
		}

		call_user_func_array( $skin->getConfig( 'NextBestNetworkSkinNavbarRenderer' ), [ $skin ] );
?>
		<main role="main">
			<div id="mw-page-base"></div>
			<div id="mw-head-base"></div>
			<a id="top"></a>


			<div id="contentwrapper" class="<?php echo $contentclass; ?>">

				<div class="row">
					<div id="maincontentwrapper" class="<?php echo $mainclass; ?>">
						<?php if( !$skin->checkEmptiness( 'subnav' ) ) { $skin->renderSubnav( $mainclass ); } ?>

						<!-- content -->
						<main role="main">
							<?php $skin->renderContent(); ?>
						</main>
						<!-- /content -->
					</div>

<?php
		if( !$skin->checkEmptiness( 'sidebar-left' ) ) {
			$leftclass = 'col-md-' . $left_width;
			$skin->renderSidebar( 'left', $leftclass );
		}
		if( !$skin->checkEmptiness( 'sidebar-right' ) ) {
			$rightclass = 'col-md-' . $right_width;
			$skin->renderSidebar( 'right', $rightclass );
		}
?>
				</div>
			</div>
		</main>


<?php
		$skin->renderFooter();
	}

	public function getConfig( $config ) {
		return $this->config->get($config);
	}


	/**
	 * Render one or more navigations elements by name, automatically reversed by css
	 * when UI is in RTL mode
	 *
	 * @param $elements
	 * @param String $context
	 */
	protected function renderNavigation( $elements, $context = '' ) {

		// If only one element was given, wrap it in an array, allowing more
		// flexible arguments
		if ( !is_array( $elements ) ) {
			$elements = [ $elements ];
			// If there's a series of elements, reverse them when in RTL mode
		} elseif ( $this->data['rtl'] ) {
			$elements = array_reverse( $elements );
		}
		// Render elements
		foreach ( $elements as $name => $element ) {
			if ( !$this->checkVisibility( $element ) ) {
				return [];
			}
			// was this element defined in LocalSettings?
			if ( isset( $this->config->get( 'NextBestNetworkSkinNavigationalElements' )[ $element ] ) ) {
				return call_user_func( $this->config->get( 'NextBestNetworkSkinNavigationalElements' )[ $element ], $this, $context );
			}
			// is it a special element with special non-buttonesque rendering?
			if ( isset( $this->config->get( 'NextBestNetworkSkinSpecialElements' )[ $element ] ) ) {
				return [ [ 'special' => $element ] ];
			}

			switch ( $element ) {

			case 'EDIT':
				$views = $this->data['view_urls'];
				if(count( $views ) > 0) {
					unset( $views['view'] );
					if( isset( $views['formedit'] ) ) {
						$link = $views['formedit'];
					} else {
						$link = array_shift( $views );
					}
					$link['icon'] = wfMessage( 'nextbestnetwork-edit-icon' )->plain();
					$link['text'] = wfMessage( 'nextbestnetwork-edit', $link['text'] )->plain();
					unset( $link['class'] ); // interferes with btn classing
					if( $link['id'] == 'ca-ve-edit' ) {
						$link['id'] = 'ca-edit';
					}
					return [ $link ];
				}
				return [];
				break;

			case 'EDIT-EXT':
				$views = $this->data['view_urls'];
				if(count( $views ) > 0) {
					unset( $views['view'] );
					if ( $this->checkVisibility( 'EDIT-EXT-special' ) ) {
						$items = $views;
						if(count($this->data['action_urls']) > 0) {
							$items[] = []; #divider
							$actions = $this->renderNavigation( 'ACTIONS' );
							$items = array_merge( $items, $actions[0]['items'] );
						}
						if( strpos( $context, 'navbar' ) !== false ) {
							$button = [
								'href' => '#',
								'html' => wfMessage( 'nextbestnetwork-edit-ext-nav' )->plain(),
								'id' => 'ca-edit-ext',
								'items' => $items
							];
						} else {
							if( isset( $items['formedit'] ) ) {
								$link = $items['formedit'];
								unset( $items['formedit'] );
							} else {
								$link = array_shift( $items );
							}
							$button = [
								'href' => $link['href'],
								'href_implicit' => false,
								'id' => 'ca-edit',
								'icon' => wfMessage( 'nextbestnetwork-edit-ext-icon' )->plain(),
								'text' => wfMessage( 'nextbestnetwork-edit-ext', $this->data['namespace'] )->plain(),
								'name' => 'ca-edit-ext'
							];
							if( isset( $items['edit'] ) ) {
								$items['edit']['id'] = 'ca-edit-source';
							}
							$button['items'] = $items;
						}
					} else {
						$link = array_shift( $views );
						$button = [
							'href' => $link['href'],
							'id' => 'ca-edit',
							'icon' => wfMessage( 'nextbestnetwork-edit-ext-icon' )->plain(),
							'text' => wfMessage( 'nextbestnetwork-edit-ext', $this->data['namespace'] )->plain()
						];
					}
					return [ $button ];
				}
				return [];
				break;

			case 'PAGE':
				$items = array_merge( $this->data['namespace_urls'], $this->data['view_urls'] );
				$text = wfMessage( 'namespaces' );
				foreach ( $items as $key => $link ) {
					if ( array_key_exists( 'context', $link ) && $link['context'] == 'subject' ) {
						$text = $link['text'];
					}
					if (preg_match('/^ca-(view|edit)$/', $link['id'])) {
						unset( $items[$key] );
					}
				}
				return [[
					'href' => '#',
					'text' => $text,
					'id' => 'n-namespaces',
					'items' => $items
				]];
				break;

			case 'NAMESPACES':
				$items = $this->data['namespace_urls'];
				$text = wfMessage( 'namespaces' );
					/*
					foreach ( $items as $key => $link ) {
						if ( array_key_exists( 'context', $link ) && $link['context'] == 'subject' ) {
							$text = $link['text'];
						}
						if (
							array_key_exists( 'attributes', $link ) && false !== strpos( $link['attributes'], 'selected' )
							|| array_key_exists( 'class', $link ) && false !== strpos( $link['class'], 'selected' )
						) {
							unset( $items[$key] );
						}
					}
					 */
				return [[
					'href' => '#',
					'text' => $text,
					'id' => 'n-namespaces',
					'items' => $items
				]];
				break;

			case 'TALK':
				$items = $this->data['namespace_urls'];
				foreach ( $items as $key => &$link ) {
					if( isset( $link['context'] ) ) {
						$link['icon'] = wfMessage( 'nextbestnetwork-namespace-' . $link['context'] . '-icon' )->plain();
					}
					if (
						array_key_exists( 'attributes', $link ) && false !== strpos( $link['attributes'], 'selected' )
						|| array_key_exists( 'class', $link ) && false !== strpos( $link['class'], 'selected' )
					) {
						unset( $items[$key] );
					} else {
						unset( $link['class'] ); // interferes with btn classing
					}
				}
				return $items;
				break;

			case 'TOOLBOX':
				$items = array_reverse($this->get('sidebar')['TOOLBOX']);
				$divideditems = [];
				$html = (wfMessage( 'nextbestnetwork-toolbox' )->plain() == "") ? wfMessage( 'toolbox' )->plain() : wfMessage( 'nextbestnetwork-toolbox' )->plain();
				foreach($items as $key => $item) {
					if(!isset( $item['text'] ) ) {
						$item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text();
					}
					if(preg_match( '/specialpages|whatlinkshere/', $key )) {
						$divideditems[] = [];
					}
					$divideditems[$key] = $item;
				}

				return [[
					'href' => '#',
					'html' => $html,
					'id' => 't-tools',
					'items' => $divideditems
				]];
				break;

			case 'TOOLBOX-EXT':
				$items = array_reverse($this->get('sidebar')['TOOLBOX']);
				$divideditems = [];
				$html = (wfMessage( 'nextbestnetwork-toolbox' )->plain() == "") ? wfMessage( 'toolbox' )->plain() : wfMessage( 'nextbestnetwork-toolbox' )->plain();
				foreach($items as $key => $item) {
					if(!isset( $item['text'] ) ) {
						$item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text();
					}

                    // Remove icons
                    if(isset( $item['icon'] ) ) {
                        unset( $item['icon'] );
                    }

					if(preg_match( '/specialpages|whatlinkshere/', $key )) {
						$divideditems[] = [];
					}
					$divideditems[$key] = $item;
				}

                // Special section, just for our historians
				$divideditems[] = [];
				$divideditems['recent'] = [
					'text' => wfMessage( 'recentchanges' )->plain(),
					'href' => Title::newFromText( 'Special:RecentChanges' )->getLocalURL(),
					'id' => 't-recentchanges',
				];

                // Add page history link at bottom
                $views = $this->data['view_urls'];
                if( isset( $views['history'] )  ) {
                    if (
                            array_key_exists( 'attributes', $views['history'] ) && false !== strpos( $views['history']['attributes'], 'selected' )
                            || array_key_exists( 'class', $views['history'] ) && false !== strpos( $views['history']['class'], 'selected' )
                    ) {
                        $divideditems['history']  = array_shift( $this->data['namespace_urls'] );
                    } else {
                        $divideditems['history']  = $views['history'];
                    }
                }

                return [[
					'href' => '#',
					'html' => $html,
					'id' => 't-tools',
					'items' => $divideditems
				]];
				break;

			case 'VARIANTS':
				$theMsg = 'variants';
				$items = $this->data['variant_urls'];
				if (count($items) > 0) {
					return [[
						'href' => '#',
						'text' => wfMessage( 'variants' ),
						'id' => 'ca-variants',
						'items' => $items
					]];
				}
				break;

			case 'VIEWS':
				$items = $this->data['view_urls'];
				if (count($items) > 0) {
					return [[
						'href' => '#',
						'text' => wfMessage( 'views' ),
						'id' => 'ca-views',
						'items' => $items
					]];
				}
				break;

			case 'HISTORY':
				$button = null;
				$views = $this->data['view_urls'];
				if( isset( $views['history'] )  ) {
					if (
						array_key_exists( 'attributes', $views['history'] ) && false !== strpos( $views['history']['attributes'], 'selected' )
						|| array_key_exists( 'class', $views['history'] ) && false !== strpos( $views['history']['class'], 'selected' )
					) {
						$button = array_shift( $this->data['namespace_urls'] );
					} else {
						$button = $views['history'];
						$button['icon'] = wfMessage( 'nextbestnetwork-history-icon' )->plain();
					}
				}
				if( !is_null( $button ) ) {
					$button['options'] = [ 'wrapperid' => $button['id'] ];
					unset( $button['id'] );
					unset( $button['class'] );
					return [ $button ];
				}
				break;

			case 'ACTIONS':
				$items = array_reverse($this->data['action_urls']);
				if (count($items) > 0) {
					return [[
						'href' => '#',
						'text' => wfMessage( 'actions' ),
						'id' => 'ca-actions',
						'items' => $items
					]];
				}
				break;

			case 'WATCH':
				$button = null;
				$actions = $this->data['action_urls'];
				if( isset( $actions['watch'] )  ) {
					$button = $actions['watch'];
				} else if( isset( $actions['unwatch'] ) ) {
					$button = $actions['unwatch'];
				}
				if( !is_null( $button ) ) {
					$button['options'] = [ 'wrapperid' => $button['id'] ];
					unset( $button['id'] );
					return [ $button ];
				}
				break;

			case 'ICONWATCH':
				$button = null;
				$watch = $this->data['watch_urls'];
				if( isset( $watch['watch'] )  ) {
					$button = $watch['watch'];
				} else if( isset( $watch['unwatch'] ) ) {
					$button = $watch['unwatch'];
				}
				if( !is_null( $button ) ) {
					$button['class'] .= 'icon';
					$button['options'] = [
						'wrapperid' => $button['id'],
						'wrapperclass' => 'nav icon'
					];
					if( strpos( $context, 'nav' ) !== false ) {
						$button['class'] .= ' nav-link';
						$button['options']['wrapperclass'] .= ' nav-item';
					}
					unset( $button['id'] );
					return [ $button ];
				}
				break;

			case 'PERSONAL':
				$items = $this->getPersonalTools();
				$divideditems = [];
				foreach($items as $key => $item) {
					if(!isset( $item['text'] ) ) {
						$item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text();
					}
					if(!isset( $item['href'] ) ) {
						$item['href'] = $item['links'][0]['href'];
					}
					if(preg_match( '/preferences|logout/', $key )) {
						$divideditems[] = [];
					}
					unset( $item['links'] );
					$divideditems[$key] = $item;
				}
				if ( array_key_exists( 'login', $divideditems ) ) {
					if( array_key_exists( 'createaccount', $divideditems ) ) { // If ConfirmAccount Extension is used
						return [ $divideditems['login'], $divideditems['createaccount'] ];
					}
					$divideditems['login']['text'] = wfMessage( 'nextbestnetwork-login' )->plain();
					return [ $divideditems['login'] ];
				}
				if ( array_key_exists( 'login-private', $divideditems ) ) {
					if( array_key_exists( 'createaccount', $divideditems ) ) { // If ConfirmAccount Extension is used
						return [ $divideditems['login-private'], $divideditems['createaccount'] ];
					}
					$divideditems['login-private']['text'] = wfMessage( 'nextbestnetwork-login' )->plain();
					return [ $divideditems['login-private'] ];
				}
				if (count($items) > 0) {
					$personal = [
						'href' => '#',
						'html' => '<span class="nextbestnetwork-username">' . wfMessage( 'nextbestnetwork-personaltools-text', $this->data['username'] )->text() . '</span>',
						'icon' => wfMessage( 'nextbestnetwork-personaltools-icon' )->text(),
						'id' => 'pt-personaltools',
						'items' => $divideditems
					];
					if( isset( $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] ) && $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] !== false ) {
						$userImages = \SMW\StoreFactory::getStore()->getPropertyValues( \SMW\DIWikiPage::newFromTitle( $this->getSkin()->getUser()->getUserPage() ), \SMW\DIProperty::newFromUserLabel( $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] ) );
						//die(var_dump( \SMW\DIProperty::newFromUserLabel( $GLOBALS['wgNextBestNetworkSkinUserImageProperty'] ) ) );
						if ( !empty( $userImages ) ) {
							$userImage = reset( $userImages );
							if ( is_a( $userImage, '\SMW\DIWikiPage' ) && $userImage->getNamespace() === NS_FILE ) {
								$imagePage = new WikiFilePage( $userImage->getTitle() );
								$personal['html'] = '<img src="' . $imagePage->getFile()->createThumb( 31, 31 ) . '" class="nextbestnetwork-user-image">';
								unset( $personal['icon'] );
							}
						}
					}
					return [$personal];
				}
				break;

			case 'PERSONAL-EXT':
				$items = $this->getPersonalTools();
				$divideditems = [];
				foreach($items as $key => $item) {
					if(!isset( $item['text'] ) ) {
						$item['text'] = wfMessage( isset( $item['msg'] ) ? $item['msg'] : $key )->text();
					}
					if(!isset( $item['href'] ) ) {
						$item['href'] = isset( $item['links'][0]['href'] ) ? $item['links'][0]['href'] : '';
					}
					if(preg_match( '/preferences|logout/', $key )) {
						$divideditems[] = [];
					}
					unset( $item['links'] );
					$divideditems[$key] = $item;
				}
				if ( array_key_exists( 'login', $divideditems ) ) {
					return [ [ 'special' => 'LOGIN-EXT' ] ];
				}
				if ( array_key_exists( 'login-private', $divideditems ) ) {
					return [ [ 'special' => 'LOGIN-EXT' ] ];
				}
				if (count($items) > 0) {
					return [[
						'href' => '#',
						'html' => '<span class="nextbestnetwork-username">' . wfMessage( 'nextbestnetwork-personaltools-text', $this->data['username'] )->text() . '</span>',
						'icon' => wfMessage( 'nextbestnetwork-personaltools-icon' )->text(),
						'id' => 'pt-personaltools-ext',
						'items' => $divideditems
					]];
				}
				break;

			case 'LOGIN':
				$items = $this->getPersonalTools();
				if ( array_key_exists( 'login', $items ) ) {
					if( array_key_exists( 'createaccount', $items ) ) { // If ConfirmAccount Extension is used
						return [ $items['login'], $items['createaccount'] ];
					}
					$items['login']['links'][0]['text'] = wfMessage( 'nextbestnetwork-login' )->plain();
					return [ $items['login'] ];
				}
				if ( array_key_exists( 'login-private', $items ) ) {
					if( array_key_exists( 'createaccount', $items ) ) { // If ConfirmAccount Extension is used
						return [ $items['login-private'], $items['createaccount'] ];
					}
					$items['login-private']['links'][0]['text'] = wfMessage( 'nextbestnetwork-login' )->plain();
					return [ $items['login-private'] ];
				}
				return [];
				break;

			case 'SIDEBAR':
				$sidebar = [];
				foreach ( $this->data['sidebar'] as $name => $content ) {
					if( !in_array( $name , ['TOOLBOX', 'SEARCH', 'LANGUAGES'] ) ) {
						if ( empty ( $content ) ) {
							if( strpos( $name, '|' ) !== false ) {
								$parser = MediaWikiServices::getInstance()->getParserFactory()->create();
								$parser->setOutputType(Parser::OT_HTML);
								$sidebarItem = NextBestNetworkHooks::parseButtonLink( $name, $parser, false );
								$sidebar[] = $sidebarItem[0];
								continue;
							}
							// navigational keywords
							$navigation = $this->renderNavigation( $name );
							if( is_array( $navigation ) ) {
								if( isset( $navigation[0] ) ) {
									$sidebar[] = $navigation[0];
								}
								continue;
							}
						}
						$msgObj = wfMessage( $name );
						$name = htmlspecialchars( $msgObj->exists() ? $msgObj->text() : $name );
						$sidebar[] = [
							'href' => '#',
							'text' => $name,
							'items' => $content
						];
					}
				}
				return $sidebar;
				break;

			case 'LANGUAGES':
				$items = $this->data['language_urls'];
				if (is_array($items) && count($items) > 0 && $items) {
					return [[
						'href' => '#',
						'text' => wfMessage( 'otherlanguages' ),
						'id' => 'p-otherlanguages',
						'items' => $items
					]];
				}
				return [];
				break;

			default:
				return $element;
				break;
			}
		}
	}


	/**
	 * Check navigational sections for content
	 *
	 * @param $item String
	 */
	public function checkEmptiness( $item ) {
		return wfMessage( 'nextbestnetwork-' . $item )->isDisabled();
	}


	/**
	 * Elements can be hidden for anonymous or logged in users or for everybody who has not opted
	 * to show the advanced features in their preferences
	 *
	 * @param $item String
	 */
	public function checkVisibility( $item ) {
		$hookContainer = MediaWikiServices::getInstance()->getHookContainer();
		return (
			(
				!$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideNonAdvanced' ) ) ||
				$this->data['advanced'] // not hidden for non-advanced OR advanced
			) &&
			(
				!$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideAnon' ) ) ||
				$this->data['loggedin'] // not hidden for anonymous users OR non-anonymous user
			) &&
			(
				!$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideLoggedin' ) ) ||
				!$this->data['loggedin'] // not hidden for logged-in users OR anonymous user
			) &&
			!$this->checkVisibilitySetting( $item, $this->config->get( 'NextBestNetworkSkinHideAll' ) ) // not hidden for all
			&&
			!$this->checkVisibilityGroups( $item ) // not hidden for all OR user is in exempted group
			&&
			false !== $hookContainer->run( 'SkinNextBestNetworkCheckVisibility', [ $this, $item ] ) // not hidden via hook
		);
	}


	/**
	 * Check if an element has an entry in a configuration option and if it's set to true
	 * (i.e. the element should be hidden)
	 *
	 * @param $item Element to be tested
	 * @param $setting Configuration option to be searched
	 *
	 * @return Boolean returns true, if the element is hidden
	 */
	public function checkVisibilitySetting( $item, $setting ) {
		// this is for backwards compatibility
		if( in_array( $item, $setting, true ) ) {
			return true;
		}
		if( array_key_exists( $item, $setting ) ) {
			return $setting[$item] ? true : false;
		}
		return false;
	}


	/**
	 * Check if an element has an entry in $wgNextBestNetworkSkinExcept or if the user is
	 * in the corresponding group
	 *
	 * @param $item Element to be tested
	 *
	 * @return Boolean returns true, if the element is hidden
	 */
	public function checkVisibilityGroups( $item ) {
		// has the option been used?
		if( !$this->config->has( 'NextBestNetworkSkinHideExcept' ) ) {
			return false;
		}

		$group_settings = $this->config->get( 'NextBestNetworkSkinHideExcept' );

		// has the option been set for this item?
		if( isset( $group_settings[$item] ) && is_array( $group_settings[$item] ) ) {
			$userGroupManager = MediaWikiServices::getInstance()->getUserGroupManager();
			$groups = $userGroupManager->getUserEffectiveGroups($this->getSkin()->getUser());

			// is the user in the exempted group?
			if( count( array_intersect( $group_settings[$item], $groups ) ) > 0 ) {
				return false;
			}

			return true;
		}

		return false;
	}


	/**
	 * Get a navigational element's content as defined in the respective message or customized with {{#nextbestnetworknav}}
	 * 
	 * @param $item Element whose content should be returned
	 * 
	 * @return String Element's content
	 */
	public function getNavContent( $item ) {
		if( isset( $GLOBALS['wgNextBestNetworkSkinCustomNav'][$item] ) ) {
			return $GLOBALS['wgNextBestNetworkSkinCustomNav'][$item];
		}
		return wfMessage( 'nextbestnetwork-' . $item )->plain();
	}


	/**
	 * Render Subnavigation
	 */
	public function renderSubnav() {
		$options = $this->getParsingOptions( 'subnav' );
		if( !wfMessage( 'nextbestnetwork-subnav' )->isDisabled() && $this->checkVisibility( 'subnav' ) ) { ?>
			<!-- subnav -->
			<div id="page-header">
				<ul class="<?php $this->msg( 'nextbestnetwork-subnav-class' ) ?>">
					<?php $this->buildItems( $this->getNavContent( 'subnav' ), $options, 'subnav' ); ?>
				</ul>
			</div>
			<!-- /subnav -->
<?php }
	}


	/**
	 * Render Navbar
	 *
	 * @param $skin
	 */
	public static function renderNavbar($skin) {
		$navbar_class = $skin->getMsg( 'nextbestnetwork-navbar-class' );
		if ( $skin->checkVisibility( 'navbar' ) ) { ?>
			<header>
				<nav id="mw-navigation" data-bs-theme="dark" class="<?php echo $navbar_class; ?>">
					<div class="<?php echo wfMessage( 'nextbestnetwork-container-class' )->plain(); ?>">
<?php if ( $skin->checkVisibility( 'navbar-brand' ) ) {
$skin->renderBrand();
		} ?>

						<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
							<span class="navbar-toggler-icon"></span>
						</button>

						<div id="navbar" class="collapse navbar-collapse">
							<?php if ( $skin->checkVisibility( 'navbar-left' ) ) { ?>
								<ul class="navbar-nav me-auto">
									<?php $skin->renderNavbarElement( 'left' ); ?>
								</ul>
							<?php } ?>

							<?php if ( $skin->checkVisibility( 'navbar-right' ) ) { ?>
								<ul class="navbar-nav">
									<?php $skin->renderNavbarElement( 'right' ); ?>
								</ul>
							<?php } ?>
						</div>
					</div>
				</nav>
			</header>
<?php }
	}


	/**
	 * Render Navbarelement
	 *
	 * @param $side string
	 */
	public function renderNavbarElement( $side ) {
		$element = 'navbar-' . $side;
		$options = $this->getParsingOptions( $element );

		$options['wrapperclass'] = 'nav-item';
		$options['class'] = 'nav-link';
		$this->buildItems( $this->getNavContent( $element ), $options, $element );
	}


	/**
	 * Render Sidebar
	 *
	 * @param $side string
	 * @param $class string
	 */
	public function renderSidebar( $side, $class = '' ) {
		$element = 'sidebar-' . $side;
		$options = $this->getParsingOptions( $element );
		$classes = $class;
		if( wfMessage( 'nextbestnetwork-sidebar-class' )->exists() ) {
			$classes .= ' ' . $this->getMsg( 'nextbestnetwork-sidebar-class' );
		}
		if( wfMessage( 'nextbestnetwork-' . $element . '-class' )->exists() ) {
			$classes .= ' ' . $this->getMsg( 'nextbestnetwork-' . $element . '-class' );
		}
		/* TODO: can we move these criteria elsewhere? rather there should be some handling for empty sidebars */
		if ( ( true || count( $this->data['view_urls'] ) > 0 || $this->data['isarticle'] ) && $this->checkVisibility( $element ) ) { ?>
			<!-- <?php echo $element;?> -->

				<div id="<?php echo $element; ?>" class="<?php echo $classes; ?>">
					<?php $this->buildItems( $this->getNavContent( $element ), $options, $element ); ?>
				</div>

			<!-- /<?php echo $element;?> -->
<?php }
	}


	/**
	 * Render Content
	 */
	public function renderContent() {
?>
		<div class="mw-body" id="content">
			<div id="mw-js-message" style="display:none;"<?php $this->html( 'userlangattributes' ) ?>></div>
			<?php if ( $this->data['sitenotice'] ) { ?>
			<!-- sitenotice -->
			<div id="siteNotice"><?php $this->html( 'sitenotice' ) ?></div>
			<!-- /sitenotice -->
			<?php } ?>
			<?php if ( $this->checkVisibility( 'firstHeading' ) ) { ?>
			<h1 id="firstHeading" class="firstHeading page-header" lang="<?php
				$this->data['pageLanguage'] = $this->getSkin()->getTitle()->getPageLanguage()->getHtmlCode();
				$this->text( 'pageLanguage' );
			?>"><span dir="auto"><?php $this->html( 'title_formatted' ) ?></span></h1>
			<?php } ?>
			<?php $this->html( 'prebodyhtml' ) ?>
			<!-- bodyContent -->
			<div id="bodyContent">
			<?php if ( $this->data['isarticle'] ) { ?>
			<div id="siteSub"><?php $this->msg( 'tagline' ) ?></div>
			<?php } ?>
			<div id="contentSub"<?php $this->html( 'userlangattributes' ) ?>><?php $this->html( 'subtitle' ) ?></div>
			<?php if ( $this->data['undelete'] ) { ?>
			<div id="contentSub2"><?php $this->html( 'undelete' ) ?></div>
			<?php } ?>
			<?php if ( $this->data['newtalk'] ) { ?>
			<div class="usermessage"><?php $this->html( 'newtalk' ) ?></div>
			<?php } ?>
			<div id="jump-to-nav" class="mw-jump">
			<?php $this->msg( 'jumpto' ) ?>
			<a href="#mw-navigation"><?php $this->msg( 'jumptonavigation' ) ?></a><?php $this->msg( 'comma-separator' ) ?>
			<a href="#p-search"><?php $this->msg( 'jumptosearch' ) ?></a>
			</div>
			<?php $this->html( 'bodycontent' ) ?>
			<?php if ( $this->data['printfooter'] ) { ?>
			<div class="printfooter">
			<?php $this->html( 'printfooter' ); ?>
		</div>
			<?php } ?>
			<?php if ( $this->data['catlinks'] ) { ?>
			<?php $this->html( 'catlinks' ); ?>
		<?php } ?>
			<?php if ( $this->data['dataAfterContent'] ) { ?>
			<?php $this->html( 'dataAfterContent' ); ?>
		<?php } ?>
			<div class="visualClear"></div>
			<?php $this->html( 'debughtml' ); ?>
		</div>
			<!-- /bodyContent -->
			</div>
<?php
	}


	public function renderFooter() {
		$options = $this->getParsingOptions( 'footer' );
		if ( $this->checkVisibility( 'footer' ) ) { ?>
			<footer id="footer" role="contentinfo" class="footer <?php $this->msg( 'nextbestnetwork-footer-class' ); ?>"<?php $this->html( 'userlangattributes' ) ?>>
				<div class="<?php $this->msg( 'nextbestnetwork-container-class' ); ?>">
					<div class="row">
						<?php $this->buildItems( $this->getNavContent( 'footer' ), $options, 'footer' ); ?>
					</div>
				</div>
			</footer>
<?php }
	}


	/**
	 * Get options for navigational sections
	 *
	 * Options can be set via system messages
	 *
	 * @param $element string
	 */
	private function getParsingOptions( $element ) {
		$options = [];
		$available_options = [
			'btnclass',
			'wrapper',
			'wrapperclass',
			'dropdownclass'
		];
		foreach( $available_options as $option ) {
			$msg = wfMessage( 'nextbestnetwork-' . $element . '-' . $option );
			if( $msg->exists() ) {
				/* the btnclass option's name for the parser is different */
				if( $option === 'btnclass' ) {
					$option = 'class';
				}
				$options[$option] = $msg->parse();
			}
		}
		return $options;
	}


	/**
	 * Build Items for navbar, subnav, sidebar
	 *
	 * @param $items String
	 * @param $options Array
	 * @param $context String
	 */
	public function buildItems( $items, $options, $context ) {
		$buttons = [];
		$customItems = [];
		$navbarItems = preg_split( '/[\n,]/', $items );
		foreach( $navbarItems as $navbarItem ) {
			$navbarItem = trim( $navbarItem );
			$navbarItem = $this->renderNavigation( $navbarItem, $context );
			if ( is_array( $navbarItem ) ) {
				$this->renderCustomNavigation( $buttons, $customItems );
				if(count($navbarItem) !== 0) {
					$buttons = array_merge( $buttons, $navbarItem );
				}
			}	else {
				$customItems[] = $navbarItem;
			}
		}
		$this->renderCustomNavigation( $buttons, $customItems );
		foreach( $buttons as $button ) {
			/* standard button rendering */
			if( !isset( $button['special'] ) ) {
				$button_options = [];
				if( isset( $button['options'] ) ) {
					$button_options = $button['options'];
					unset( $button['options'] );
				}
				echo NextBestNetworkHooks::renderButtons( [ $button ], array_merge( $options, $button_options ) );
			}
			/* special cases */
			else {
				call_user_func_array( $this->config->get( 'NextBestNetworkSkinSpecialElements' )[$button['special']], [ $this, $context, $options ] );
			}
		}
	}


	/**
	 * Render navigations elements that renderNavigation hasn't dealt with
	 *
	 * @param $buttons array
	 * @param $customItems array
	 */
	private function renderCustomNavigation( &$buttons, &$customItems ) {
		$parser = MediaWikiServices::getInstance()->getParserFactory()->create();
		$parser->setOutputType(Parser::OT_HTML);
		$parser->setOptions( ParserOptions::newFromContext( $this->getSkin()->getContext() ) );
		$parser->setTitle( $this->getSkin()->getTitle() );
		$parser->clearState();

		if( count( $customItems ) !== 0 ) {
			$newButtons = NextBestNetworkHooks::parseButtons( implode( chr(10), $customItems ), $parser, false );
			$buttons = array_merge( $buttons, $newButtons );
			$customItems = [];
		}
	}


	/**
	 * Render firstheading
	 */
	public function renderFirstHeading( $skin, $context ) {
		echo '<div class="nextbestnetworkFirstHeading">' . $skin->data[ 'title_formatted' ] . '</div>';
	}


	/**
	 * Render TOC
	 */
	public function renderTOC( $skin, $context ) {
		if( $context == 'sidebar-left' || $context == 'sidebar-right' ) {
			echo '<div id="nextbestnetworkTOC"></div>';
		} else {
			echo '<li class="nav dropdown" id="nextbestnetworkDropdownTOC"><a id="n-toc" class="dropdown-toggle" data-bs-toggle="dropdown" href="#">' . wfMessage( 'Toc' )->text() . '<span class="caret"></span></a><ul class="dropdown-menu pull-right" role="menu" id="nextbestnetworkTOC"><li><a href="#">' . wfMessage( 'nextbestnetwork-toc-top' )->text() . '</a></li><li class="divider"></li></ul></li>';
		}
	}


	/**
	 * Render logo
	 */
	public function renderLogo( $skin, $context ) {
		$mainPageLink = $skin->data['nav_urls']['mainpage']['href'];
		$toolTip = Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) );
		echo '
				<a id="p-logo" href="' . htmlspecialchars( $skin->data['nav_urls']['mainpage']['href'] ) . '" ' . Xml::expandAttributes( Linker::tooltipAndAccesskeyAttribs( 'p-logo' ) ) . '>
					<img src="';
		$skin->text( 'logopath' );
		echo '" alt="';
		$skin->html( 'sitename' );
		echo '"></a>';
	}


	/**
	 * Render Login-ext
	 */
	public function renderLoginExt( $skin, $context ) {
		SessionManager::getGlobalSession()->persist();

		//build path for form action
		$returntotitle = $skin->getSkin()->getTitle();
		$returnto = $returntotitle->getFullText();
		if ( $returntotitle->equals( SpecialPage::getTitleFor( 'Userlogin' ) )
			|| $returntotitle->equals( SpecialPage::getTitleFor( 'Userlogout' ) )
			|| !$returntotitle->exists() ) {
			$returnto = Title::newMainPage()->getFullText();
		}
		$returnto = $this->getSkin()->getRequest()->getVal( 'returnto', $returnto );

		if ( $this->config->has( 'NextBestNetworkReturnto' ) && $returnto == Title::newMainPage()->getFullText() ) {
			$returnto = $this->config->get( 'NextBestNetworkReturnto' );
		}
		$action = $GLOBALS['wgScript'] . '?title=Special:UserLogin&amp;action=submitlogin&amp;type=login&amp;returnto=' . $returnto;

		//create login token if it doesn't exist
		if( !$this->getSkin()->getRequest()->getSession()->getToken( '', 'login' ) ) $this->getSkin()->getRequest()->getSession()->resetToken( 'login' );
		$this->getSkin()->getUser()->setCookies();

		$dropdown['class'] = ' dropdown-toggle';
		if( strpos( $context, 'navbar' ) === 0 ) {
			$dropdown['class'] .= ' nav-link';
		}
		$dropdown['data-bs-toggle'] = 'dropdown';
		$dropdown['text'] = $this->getMsg( 'nextbestnetwork-login' )->text();
		$dropdown['html'] = $dropdown['text'] . ' <b class="caret"></b>';
		$dropdown['href'] = '#';
		$dropdown['type'] = 'button';
		$dropdown['id'] = 'n-login-ext';
		$renderedDropdown = NextBestNetworkHooks::makeLink( $dropdown);
		$wrapperclass = ( $context == 'footer' ) ? 'dropup' : 'nav-item dropdown';

		echo '<li class="' . $wrapperclass . '">
			' . $renderedDropdown . '
			<div class="dropdown-menu" role="menu" aria-labelledby="' . $this->getMsg( 'nextbestnetwork-login' )->text() . '" id="loginext">
			<form action="' . $action . '" method="post" name="userloginext" class="clearfix p-1">
			<div class="form-group">
			<label for="wpName2" class="hidden-xs">
			' . $this->getMsg( 'userlogin-yourname' )->text() . '
			</label>';
		echo Html::input( 'wpName', null, 'text', [
			'class' => 'form-control input-sm',
			'id' => 'wpName2',
			'tabindex' => '101',
			'placeholder' => $this->getMsg( 'userlogin-yourname-ph' )->text()
		] );
		echo	'</div>
			<div class="form-group">
			<label for="wpPassword2" class="hidden-xs">
			' . $this->getMsg( 'userlogin-yourpassword' )->text() . '
			</label>';
		echo Html::input( 'wpPassword', null, 'password', [
			'class' => 'form-control input-sm',
			'id' => 'wpPassword2',
			'tabindex' => '102',
			'placeholder' => $this->getMsg( 'userlogin-yourpassword-ph' )->text()
		] );
		echo '</div>
			<div class="form-group">
			<button type="submit" name="wpLoginAttempt" tabindex="103" id="wpLoginAttempt2" class="float-end btn btn-primary btn-block">
			' . $this->getMsg( 'pt-login-button' )->text() . '
			</button>
			</div>
			<input type="hidden" id="wpEditToken" value="+\" name="wpEditToken">
			<input type="hidden" value="Special:UserLogin" name="title">
			<input name="authAction" type="hidden" value="login">
			<input name="force" type="hidden">
			<input type="hidden" value="' . $this->getSkin()->getRequest()->getSession()->getToken( '', 'login' ) . '" name="wpLoginToken">
			</form>';

		if( $this->getSkin()->getUser()->isAllowed( 'createaccount' ) ) {
			echo	'<div class="nav center mb-2" id="tw-createaccount">
				<a href="' . $GLOBALS['wgScript'] . '?title=special:userlogin&amp;type=signup">
				' . $this->getMsg( 'createaccount' )->text() . '
				</a>
				</div>';
		} else if( array_key_exists( 'createaccount', $this->getPersonalTools() ) ) { // ConfirmAccount Extension
			echo	'<div class="nav center mb-2" id="tw-requestaccount">
				<a href="' . $GLOBALS['wgScript'] . '?title=special:requestaccount">
				' . $this->getMsg( 'requestaccount-login' )->text() . '
				</a>
				</div>';
		}

		echo '
			</div>
			</li>';
		/*
		echo '<script>
				$( document ).ready( function() {
					$( "#n-login" ).click( function() {
						if( ! $( this ).parent().hasClass( "open" ) ) {
							setTimeout( \'$( "#wpName2" ).focus();\', 500 );
							}
					});
				});
				</script>';
		 */
	}


	/**
	 * Render search
	 */
	public function renderSearch( $skin, $context ) {
		if( $context == 'subnav' ) {
			echo '<li class="nav dropdown">';
		}
		if( strpos( $context, 'navbar' ) === 0 ) {
			echo '</ul>';
		}
		echo '
			<form ';

		if( $context == 'navbar-left' ) {
			echo 'class="navbar-form navbar-left" ';
		}
		if( $context == 'navbar-right' ) {
			echo 'class="navbar-form navbar-right" ';
		}
		echo 'action="';
		$skin->text( 'wgScript' );
		echo '" id="searchform">
				<div class="form-inline">';

		echo $skin->makeSearchInput( [
			'id' => 'searchInput',
			'class' => 'search-query form-control',
			'placeholder' => $skin->getMsg( 'search' )->text()
		] );

		echo $skin->makeSearchButton( 'go', [
			'id' => 'mw-searchButton',
			'class' => 'searchButton btn d-none'
		] );

		echo '
				</div>
			</form>';
		if( $context == 'navbar-left' ) {
			echo '<ul class="nav navbar-nav">';
		}
		if( $context == 'navbar-right' ) {
			echo '<ul class="nav navbar-nav navbar-right">';
		}
		if( $context == 'subnav' ) {
			echo '</li>';
		} else {
            echo '
                <li class="nav-item dropdown">
                    <button class="btn btn-link nav-link px-0 px-lg-2 py-2 dropdown-toggle d-flex align-items-center" id="bd-theme" type="button" aria-expanded="false" data-bs-toggle="dropdown" data-bs-display="static" aria-label="Toggle theme">
                        <span class="fa fa-adjust" aria-hidden="true"></span>
                        <span class="d-lg-none ms-2" id="bd-theme-text">Toggle theme</span>
                    </button>
                    <ul class="dropdown-menu dropdown-menu-end" aria-labelledby="bd-theme-text">
                        <li>
                            <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="light" aria-pressed="false">
                                <span class="fa fa-sun" aria-hidden="true"></span>
                                <span class="ms-2">Light</span>
                                <span class="fa fa-check d-none ms-auto" aria-hidden="true"></span>
                            </button>
                        </li>
                        <li>
                            <button type="button" class="dropdown-item d-flex align-items-center" data-bs-theme-value="dark" aria-pressed="false">
                                <span class="fa fa-moon" aria-hidden="true"></span>
                                <span class="ms-2">Dark</span>
                                <span class="fa fa-check d-none ms-auto" aria-hidden="true"></span>
                            </button>
                        </li>
                        <li>
                            <button type="button" class="dropdown-item d-flex align-items-center active" data-bs-theme-value="auto" aria-pressed="true">
                                <span class="fa fa-adjust" aria-hidden="true"></span>
                                <span class="ms-2">Auto</span>
                                <span class="fa fa-check ms-auto" aria-hidden="true"></span>
                            </button>
                        </li>
                    </ul>
                </li>
            ';
        }
	}


	/**
	 * Render brand (linking to mainpage)
	 */
	public function renderBrand() {
		$brandmsg = wfMessage( 'nextbestnetwork-navbar-brand' );
		if( !$brandmsg->isDisabled() ) {
			$brand = $brandmsg->text();
			if( isset( $GLOBALS['wgNextBestNetworkSkinCustomNav']['navbar-brand'] ) ) {
				$brand = htmlspecialchars( $GLOBALS['wgNextBestNetworkSkinCustomNav']['navbar-brand'] );
			}
			/* is it a file? */
			$brandimageTitle = Title::newFromText( $brand );
			if ( ! is_null( $brandimageTitle ) && $brandimageTitle->exists() ) {
				$wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
				$brandimageWikiPage = $wikiPageFactory->newFromTitle( $brandimageTitle );
				if ( method_exists( $brandimageWikiPage, 'getFile' ) ) {
					$brandimage = $brandimageWikiPage->getFile()->getFullUrl();
					$brand = '<img src="' . $brandimage . '" alt="' . $this->data['sitename'] . '" />';
				}
			}
			$brandurl = $this->data['nav_urls']['mainpage']['href'];
			if( isset( $GLOBALS['wgNextBestNetworkSkinCustomNav']['navbar-brand-url'] ) ) {
				$brandurl = Title::newFromText( $GLOBALS['wgNextBestNetworkSkinCustomNav']['navbar-brand-url'] )->getLocalURL();
			}
			echo '<a href="' . htmlspecialchars( $brandurl ) . '" class="navbar-brand">' . $brand . '</a>';
		}
	}


	/**
	 * Render standard MediaWiki footer
	 */
	public function renderStandardFooter( $options ) {
		$options = $this->getParsingOptions( 'footer-standard' );
		$widget_class = 'col-12 col-sm footer-widget';

		foreach ( $this->getFooterLinks() as $category => $links ) {
			if ( $this->checkVisibility( 'footer-' . $category ) ) {
				echo '<div class="'.$widget_class.'"><ul id="footer-' . $category . '">';
				foreach ( $links as $link ) {
					if ( $this->checkVisibility( 'footer-' . $category . '-' . $link ) ) {
						echo '<li id="footer-' . $category . '-' . $link . '">';
						$this->html( $link );
						echo '</li>';
					}
				}
				echo '</ul></div>';
			}
		}

		if ( $this->checkVisibility( 'footer-custom' ) ) {
			if ( wfMessage ( 'nextbestnetwork-footer-custom' )->plain() !== "" ) {
				echo '<div class="'.$widget_class.'"><ul id="footer-custom">';
				$this->buildItems( wfMessage ( 'nextbestnetwork-footer-custom' )->plain(), $options, 'footer' );
				echo '</ul></div>';
			}
		}

		$footericons = $this->get('footericons');
		if ( count( $footericons ) > 0 && $this->checkVisibility( 'footer-icons' ) ) {
			echo '<div class="'.$widget_class.'"><ul id="footer-icons">';
			foreach ( $footericons as $blockName => $footerIcons ) {
				if ( $this->checkVisibility( 'footer-' . $blockName . 'ico' ) ) {
					echo '<li id="footer-' . htmlspecialchars( $blockName ) . 'ico">';
					foreach ( $footerIcons as $icon ) {
						if($this->config->get( 'NextBestNetworkSkinFooterIcons' ) ) {
							echo $this->getSkin()->makeFooterIcon( $icon );
						} else {
							echo '<span>' . $this->getSkin()->makeFooterIcon( $icon, 'withoutImage' ) . '</span>';
						}
					}
					echo '</li>';
				}
			}
			echo '</ul></div>';
		}
	}
}
