<?php

// h-source, a web software to build a community of people that want to share their hardware information.
// Copyright (C) 2010  Antonio Gallo (h-source-copyright.txt)
//
// This file is part of h-source
//
// h-source 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 3 of the License, or
// (at your option) any later version.
// 
// h-source 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 h-source.  If not, see <http://www.gnu.org/licenses/>.

if (!defined('EG')) die('Direct access not allowed!');


$decodeCounter = 0;
$decodeAnotherTime = false;

//decode the text of the wiki
function decodeWikiText($string)
{
	global $decodeAnotherTime;
	global $decodeCounter;

	$decodeCounter++;
	
	$decodeAnotherTime = false;
	
	$string = preg_replace('/(\[hr\])/', '<hr />',$string);

	$string = preg_replace_callback('/(\[\[)(.*?)\|(.*?)(\]\])/', 'linkToInternalPageWithText' ,$string);

	$string = preg_replace_callback('/(\[\[)(.*?)(\]\])/', 'linkToInternalPage' ,$string);
	
	$string = preg_replace_callback('/(\[a\])(.*?)(\[\/a\])/', 'linkTo',$string);

	$string = preg_replace_callback('/(\[a\])(.*?)\|(.*?)(\[\/a\])/', 'linkToWithText',$string);

	$string = preg_replace_callback('/(\[notebook\])([0-9]*?)(\[\/notebook\])/s', 'linkToNotebook',$string);
	
	$string = preg_replace_callback('/(\[wifi\])([0-9]*?)(\[\/wifi\])/s', 'linkToWifi',$string);
	
	$string = preg_replace_callback('/(\[videocard\])([0-9]*?)(\[\/videocard\])/s', 'linkToVideocard',$string);
	
	$string = preg_replace('/(\[b\])(.*?)(\[\/b\])/s', '<b>${2}</b>',$string);
	
	$string = preg_replace('/(\[u\])(.*?)(\[\/u\])/s', '<u>${2}</u>',$string);
	
	$string = preg_replace('/(\[i\])(.*?)(\[\/i\])/s', '<i>${2}</i>',$string);
	
	$string = preg_replace('/(\[del\])(.*?)(\[\/del\])/s', '<del>${2}</del>',$string);

	$string = preg_replace_callback('/(\[\*\])(.*?)(\[\/\*\])/s', 'createItem',$string);

	$string = preg_replace_callback('/(\[list\])(.*?)(\[\/list\])/s', 'createList',$string);

	$string = preg_replace_callback('/(\[enum\])(.*?)(\[\/enum\])/s', 'createEnum',$string);

	$string = preg_replace('/(\[code\])(.*?)(\[\/code\])/s', '<pre class="code_pre">${2}</pre>',$string);
	
	$string = preg_replace('/(\[p\])(.*?)(\[\/p\])/s', '<p>${2}</p>',$string);

	$string = preg_replace_callback('/(\[)(h)(1|2|3)(\])(.*?)(\[\/)(h)(1|2|3)(\])/s', 'createHeadGeneric',$string);
	
	$string = preg_replace_callback('/(\[tab )(lang=)([^\s]+)(\s*\])(.*?)(\[\/tab\])/s', 'createTabs',$string);

	$string = preg_replace_callback('/(__TOC__)/s', 'createToc',$string);
	
	$string = preg_replace('/(\[lang\])(.*?)(\[\/lang\])/s', '<div class="div_lang">${2}</div>',$string);

	$string = preg_replace('/(\{\{)/s', '[',$string);

	$string = preg_replace('/(\}\})/s', ']',$string);

	if ($decodeAnotherTime and $decodeCounter<=30)
	{
		return decodeWikiText(Tabs::render().$string);
	}
	else
	{
		return Tabs::render().$string;
	}
}

//create the list of the tabs in the description entry
function createTabs($match)
{
	$label = Lang::getLabel($match[3]);
	Tabs::$tabList[] = "<li class='desc_tabs ".$match[3]."'><a href='#".$match[3]."'>".$label."</a></li>\n";
	Tabs::$htmlList[] = "<div class='separation_line'>$label</div>\n<div class='description_tabs_page' id='".$match[3]."'>".$match[5]."</div>\n";
	return null;
}

//create the HTML of the tabs in the description entry
class Tabs
{
	public static $tabList = array();
	public static $htmlList = array();

	public static function render()
	{
		$html = null;
		if (count(self::$tabList) > 0)
		{
			$html .= "<div class='description_tabs'>\n";
			$html .= "<noscript><div class='noscript_notice'>".gtext("you need javascript enabled in order to correctly use the language's tabs (see below)")."</div></noscript>\n";
			$html .= "<ul class='desc_menu'>\n";
			foreach (self::$tabList as $label)
			{
				$html .= $label;
			}
			$html .= "</ul>\n<div id='description_tabs_content'>\n";
			foreach (self::$htmlList as $content)
			{
				$html .= $content;
			}
			$html .= "</div>\n</div>\n";
		}
		self::$tabList = array();
		self::$htmlList = array();
		return $html;
	}

}

function checkUrl($url)
{
	$match = '/^http(s)?\:\/\/(www\.)?[a-zA-Z0-9\-\_]+(\.[a-zA-Z0-9\-\_]+)*\.([a-z]{2,4})((\/[a-zA-Z0-9\_\.\-\:\%\+]+)*(\/([a-zA-Z0-9\_\:\-\.\+]+\.(php|html|htm|asp|aspx|jsp|cgi))?)?)?(\?([a-zA-Z0-9\_\-\+\s]+\=[a-zA-Z0-9\_\-\s\%\+\&amp;]+)+)?(#[a-zA-Z0-9\_\-\+\s\%]+)?([\s]*)?$/';
	
	if (preg_match($match,$url))
	{
		return true;
	}
	else
	{
		return false;
	}
}

function vitalizeUrl($string)
{
	if (checkUrl($string))
	{
		return "<a title = '".$string."' href='".$string."'>".$string."</a>";
	}
	return $string;
}

function linkTo($match)
{
	if (checkUrl($match[2]))
	{
		return "<a title = '".$match[2]."' href='".$match[2]."'>".$match[2]."</a>";
	}
	else
	{
		return $match[0];
	}
}

function createNode($match,$hnodeTag,$htmlTagBegin,$htmlTagEng)
{
	$numb = strlen($hnodeTag);
	global $decodeAnotherTime;

	if (strstr($match[2],$hnodeTag))
	{
		$string = substr($match[0],$numb);
		$string = decodeWikiText($string);
		$decodeAnotherTime = true;
		return $hnodeTag.$string;
	}
	else
	{
// 		$decodeAnotherTime = false;
		return $htmlTagBegin.$match[2].$htmlTagEng;
	}
}

function createToc($match)
{
	return Toc::render();
}

//table of contents
class Toc
{

	public static $links = array();
	public static $level = 1;
	
	private static $html = null;
	
	public function render()
	{
		$c=0;
		foreach (self::$links as $link)
		{
			if ((int)substr($link,0,1) === 1)
			{
				break;
			}
			$c++;
		}

		self::$links = array_slice(self::$links,$c);

		$res = array();
		
		if (count(self::$links) > 0)
		{
			self::$links[] = '1fine';

			$res[] = "<div class='tables_of_contents'><div class='tables_of_contents_title'>".gtext("Table of contents")."</div><ul>";
			foreach (self::$links as $link)
			{
				$startChar = (int)substr($link,0,1);

				if (strcmp(self::$level,$startChar) === 0)
				{
					$res[] = "<li><a href='#".substr($link,1)."'>".substr($link,1)."</a></li>";
				}
				else if ($startChar > self::$level)
				{
					$diff = (int)$startChar - (int)self::$level;
					if ($diff !== 1)
					{
						return null;
					}
					
					self::$level = $startChar;
					$res[] = "<ul><li><a href='#".substr($link,1)."'>".substr($link,1)."</a></li>";
				}
				else
				{
					$diff = (int)self::$level - (int)$startChar;

					for ($i=0;$i<$diff;$i++)
					{
						$res[] = "</ul>";
					}
					self::$level = $startChar;
					$res[] = "<li><a href='#".substr($link,1)."'>".substr($link,1)."</a></li>";
				}
			}
			array_pop($res);
			$res[] = "</ul></div>";
		}
		self::$links = array();
		return implode('',$res);
	}
}

//create h1, h2, h3 ($level=1,2,3)
function createHead($match,$level)
{
	Toc::$links[] = $level.$match[5];

	return "<div id='".$match[5]."' class='div_h$level'>".$match[5]."</div>";
}

//create <h1></h1>,<h2></h2>,<h3></h3>
function createHeadGeneric($match)
{
	if (strcmp($match[3],'1') === 0)
	{
		return createHead($match,'1');
	}
	else if (strcmp($match[3],'2') === 0)
	{
		return createHead($match,'2');
	}
	else
	{
		return createHead($match,'3');
	}
}

//create <li></li>
function createItem($match)
{
	return createNode($match,'[*]',"<li>","</li>");
}

//create <ul></ul>
function createList($match)
{
	return createNode($match,'[list]',"<ul>","</ul>");
}

//create <ol></ol>
function createEnum($match)
{
	return createNode($match,'[enum]',"<ol>","</ol>");
}

function linkToInternalPage($match)
{
	return "<a title = '".$match[2]."' href='http://".DOMAIN_NAME."/wiki/page/".Lang::$current."/".encodeUrl($match[2])."'>".$match[2]."</a>";
}

function linkToInternalPageWithText($match)
{
	return "<a title = '".$match[2]."' href='http://".DOMAIN_NAME."/wiki/page/".Lang::$current."/".encodeUrl($match[2])."'>".$match[3]."</a>";
}

function linkToWithText($match)
{
	if (checkUrl($match[2]))
	{
		
		return "<a title = '".$match[2]."' href='".$match[2]."'>".$match[3]."</a>";
	}
	else
	{
		return $match[0];
	}
}

//create the link to the wiki page of the notebook
function linkToNotebook($match)
{
	$hardware = new HardwareModel();
	$clean['id_hard'] = (int)$match[2];
	$name = encodeUrl($hardware->getTheModelName($clean['id_hard']));
	$href = "HTTP://".DOMAIN_NAME."/notebooks/view/".Lang::$current."/".$clean['id_hard']."/$name";
	return (strcmp($name,'') !== 0) ? "<a title = 'link to notebook $name:  $href' href='$href'>".$name."</a>" : $match[0];
}

//create the link to the wiki page of the wifi
function linkToWifi($match)
{
	$hardware = new HardwareModel();
	$clean['id_hard'] = (int)$match[2];
	$name = encodeUrl($hardware->getTheModelName($clean['id_hard']));
	$href = "HTTP://".DOMAIN_NAME."/wifi/view/".Lang::$current."/".$clean['id_hard']."/$name";
	return (strcmp($name,'') !== 0) ? "<a title = 'link to wifi card $name:  $href' href='$href'>".$name."</a>" : $match[0];
}

//create the link to the wiki page of the videocard
function linkToVideocard($match)
{
	$hardware = new HardwareModel();
	$clean['id_hard'] = (int)$match[2];
	$name = encodeUrl($hardware->getTheModelName($clean['id_hard']));
	$href = "HTTP://".DOMAIN_NAME."/videocards/view/".Lang::$current."/".$clean['id_hard']."/$name";
	return (strcmp($name,'') !== 0) ? "<a title = 'link to video card $name:  $href' href='$href'>".$name."</a>" : $match[0];
}