<?php if (!defined('VB_ENTRY')) die('Access denied.');
/*======================================================================*\
|| #################################################################### ||
|| # vBulletin 4.0.0 Alpha 5
|| # ---------------------------------------------------------------- # ||
|| # Copyright ©2000-2009 Jelsoft Enterprises Ltd. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| #################################################################### ||
\*======================================================================*/

require_once DIR . '/includes/class_bbcode.php' ;

/**
* Extension of the general BB Code parser that parses CMS-specific tags, such
* as tables and pages. This will generally be used for article-like content.
*
* @package vBulletin
* @copyright Jelsoft Enterprises Ltd.
*/
class vBCms_BBCode_HTML extends vB_BbCodeParser
{
	/**
	* The page we wish to be outputted when parsing. Otherwise, all pages will be outputted.
	* If specified, a list of page titles will be collected and can be accessed by calling
	* getPageTitles(). Note that page 1 never has a title.
	*
	* @var	integer
	*/
	protected $output_page = 0;

	/**
	* Tracks the current page during parsing.
	*
	* @var	integer
	*/
	protected $current_page = 0;

	/**
	* Details about the pages. Only contains text if we are trying to retrieve
	* the information for the non-last page. Note that the first page never has
	* a title.
	*
	* @var	array
	*/
	protected $pages = array();

	/**
	* Logs whether the page that was requested was valid. Is always true if
	* no page is specified.
	*
	* @var	bool
	*/
	protected $fetched_valid_page = true;

	/**
	* Object to provide the implementation of the table helper to use.
	* See setTableHelper and getTableHelper.
	*
	* @var	vBCms_BBCodeHelper_Table
	*/
	protected $table_helper = null;

	/**
	* External method to set/change the table helper implementation if necessary.
	* Generally won't be used.
	*
	* @param	vBCms_BBCodeHelper_Table	Alternative helper
	*/
	public function setTableHelper(vBCms_BBCodeHelper_Table $helper)
	{
		$this->table_helper = $helper;
	}

	/**
	* Fetches the table helper in use. It also acts as a lazy initializer.
	* If no table helper has been explicitly set, it will instantiate
	* the class's default.
	*
	* @return	vBCms_BBCodeHelper_Table	Table helper object
	*/
	public function getTableHelper()
	{
		if (!$this->table_helper)
		{
			require_once DIR . '/packages/vbcms/bbcodehelper/table.php';
			$this->table_helper = new vBCms_BBCodeHelper_Table($this);
		}

		return $this->table_helper;
	}

	/**
	* Setter for the output page handler. Set the page we wish to be outputted when parsing.
	* If set to 0 (or never called), all pages will be outputted.
	* If specified, a list of page titles will be collected and can be accessed by calling
	* getPageTitles(). Note that page 1 never has a title.
	*
	* @param	integer	The page that you wish to be returned by parsing
	*/
	public function setOutputPage($page)
	{
		$this->output_page = intval($page);
	}

	/**
	* Gets the page titles. This function only works if a specific page is outputted.
	*
	* @return	array	Key: page num, value: title
	*/
	public function getPageTitles()
	{
		$titles = array();

		foreach ($this->pages AS $page_num => $info)
		{
			$titles[$page_num] = $info['title'];
		}

		return $titles;
	}

	/**
	* Returns whether the page that was requested was valid. Is always true if
	* no page is specified.
	*
	* @return	bool
	*/
	public function fetchedValidPage()
	{
		return $this->fetched_valid_page;
	}

	/**
	* Version of the parse function that simply prevents you from running it.
	* There's too much stuff for other content types that doesn't apply.
	*/
	public function parse($text, $forumid = 0, $allowsmilie = true, $isimgcheck = false, $parsedtext = '', $parsedhasimages = 3, $cachable = false)
	{
		trigger_error('You need to call do_parse() directly.', E_USER_ERROR);
	}

	/**
	* Parse an input string with BB code to a final output string of HTML
	*
	* @param	string	Input Text (BB code)
	* @param	bool	Whether to parse smilies
	* @param	bool	Whether to parse img (for the video bbcodes)
	* @param	bool	Whether to allow HTML (for smilies)
	*
	* @return	string|false	String output Text (HTML) if a valid page, false if invalid page
	*/
	function parse_bbcode($input_text, $do_smilies, $do_imgcode, $do_html = false)
	{
		if ($this->output_page)
		{
			$this->current_page = 1;
			$this->pages = array(1 => array('title' => ''));
		}
		else
		{
			$this->current_page = 0;
			$this->pages = array();
		}

		$last_page_text = parent::parse_bbcode($input_text, $do_smilies, $do_imgcode, $do_html);

		$this->parse_output = '';
		$this->fetched_valid_page = true;

		if ($this->output_page)
		{
			if ($this->output_page == $this->current_page)
			{
				return $last_page_text;
			}
			else if (isset($this->pages[$this->output_page]))
			{
				return $this->pages[$this->output_page]['text'];
			}
			else
			{
				$this->fetched_valid_page = false;
				return '';
			}
		}
		else
		{
			return $last_page_text;
		}
	}

	/**
	* Parses the [page] tag. If we're not looking for the output of a specific
	* page, the page tag is rendered as a header. If we're looking for a particular
	* page, only that text will be returned and the page titles will be stored.
	*
	* Note that if the page tag is not at the root, it will always be ignored.
	* This is because of differing behavior with single- and multi-page views.
	*
	* @param	string	Page title
	*
	* @return	string	Output of the page header in multi page views, nothing in single page views
	*/
	protected function parsePageTag($page_title)
	{
		if (sizeof($this->stack) != 1)
		{
			// put a page tag at the non-root level. Ignore it. (Note: the page tag is what's in the stack).
			// This approach works, but users might not even realize they've done this
			// and be confused when the tag is ignored.
			return "<div>$page_title</div>";
		}

		if (!$this->output_page)
		{
			return '<h3 style="border: 1px dashed #cccccc; border-top: 3px double black; padding: 4px;">' . $page_title . '</h3>';
		}

		// page text applies to current page, title to the upcoming page
		if ($this->output_page == $this->current_page)
		{
			$this->pages[$this->current_page]['text'] = $this->parse_output;
		}

		$this->pages[$this->current_page + 1] = array('title' => $page_title);

		$this->current_page++;
		$this->parse_output = '';

		return '';
	}

	/**
	* Parses the [table] tag and returns the necessary HTML representation.
	* TRs and TDs are parsed by this function (they are not real BB codes).
	* Classes are pushed down to inner tags (TRs and TDs) and TRs are automatically
	* valigned top.
	*
	* @param	string	Content within the table tag
	* @param	string	Optional set of parameters in an unparsed format. Parses "param: value, param: value" form.
	*
	* @return	string	HTML representation of the table and its contents.
	*/
	protected function parseTableTag($content, $params = '')
	{
		$helper = $this->getTableHelper();
		return $helper->parseTableTag($content, $params);
	}

	/**
	* Fetches the tags that are available for this CMS BB code parser.
	* Includes the default vB tags (if enabled).
	*
	* @return	array
	*/
	public static function fetchCmsTags()
	{
		$tag_list = fetch_tag_list();

		$tag_list['option']['h'] = array(
			'html' => '<h%2$s>%1$s</h%2$s>',
			'option_regex' => '#^[1-6]$#',
			'strip_space_after' => 2,
			'strip_empty' => true
		);

		$tag_list['no_option']['page'] = array(
			'callback' => 'parsePageTag',
			'strip_space_after' => 2,
			'stop_parse' => true,
			'disable_smilies' => true,
			'strip_empty' => true
		);

		$tag_list['no_option']['table'] = array(
			'callback' => 'parseTableTag',
			'strip_space_after' => 1,
			'strip_empty' => true
		);

		$tag_list['option']['table'] = array(
			'callback' => 'parseTableTag',
			'strip_space_after' => 1,
			'strip_empty' => true
		);

		$tag_list['no_option']['hr'] = array(
			'html' => '<hr />%1$s',
			'strip_empty' => false
		);

		$tag_list['no_option']['prbreak'] = array(
			'html' => '<hr class="previewbreak" />%1$s',
			'strip_empty' => false
		);

		$tag_list['no_option']['sub'] = array(
			'html' => '<sub>%1$s</sub>',
			'strip_empty' => true
		);

		$tag_list['no_option']['sup'] = array(
			'html' => '<sup>%1$s</sup>',
			'strip_empty' => true
		);

		return $tag_list;
	}

}

/*======================================================================*\
|| ####################################################################

|| # SVN: $Revision: 29533 $
|| ####################################################################
\*======================================================================*/