<?php if (!defined('PmWiki')) exit();

####### DESCRIPTION:  The Hg recipe adds Hierarchical Groups capabilities to PmWiki.  For info, see http://www.pmwiki.org/wiki/Cookbook/Hg.  Author: Dan Vis  <editor àt fast döt st>, Copyright 2007.

####### Set up various variables
$RecipeInfo['Hg']['Version'] = '2007-04-26';
SDV($hgseparator, '-');
SDV($hgmaxlevels, 7);
SDV($hglinkprefix, '');
SDV($hgprefixcode, 'Hg');
SDV($hgname, '');
SDV($hggroup, '');
SDV($hgbreadcrumbseparator, ' > ');
SDV($EnableBreadCrumbName, true);
SDV($EnableHgCleanUrls, false);

$pagename = hgResolvePageName($pagename);
$FmtPV['$PageUrl'] = 'PUE("$ScriptUrl?n=" . hgUrl($group, $name))';
$LinkPageCreateFmt = hgCreateFmt("{\$PageUrl}");
$PagePathFmt = array('{$Group}.$1', '$1.{$DefaultName}', '$1.$1');

$FmtPV['$g0'] = 'hgCountLevels($group)';
$FmtPV['$n0'] = 'hgCountLevels($name)';
for ($i=0; $i < $hgmaxlevels; $i++) {
	$hg = "g" . ($i + 1);
	$hn = "n" . ($i + 1);
	$FmtPV['$' . $hg] = 'hgSplitName($group,' . $i . ')';
	$FmtPV['$' . $hn] = 'hgSplitName($name,' . $i . ')';
	}
$FmtPV['$grouptitle'] = 'hgGroupTitles($group)';

####### The following are set by default to function hierarchically, others can be set in config.php.
$FmtPV['$SideBar'] = 'HierarchicalPagenames($group, "SideBar")';
$FmtPV['$SideMenu'] = 'HierarchicalPagenames($group, "SideMenu")';

####### Set up hierarchical configs, headers, footers, attributes & styles
$EnablePGCust = 0;
$hgc = 0; $hgh = 0; $hgf = 0; $hgs = 0; $hgm = 0; $hga = 0;
if (file_exists("$LocalDir/$hggroup.$hgname.php")) {
	include_once("$LocalDir/$hggroup.$hgname.php");
	$hgc = 1;
	}
$hggroups = explode($hgseparator, $hggroup);
while (count($hggroups) != 0) {
	$hg = implode ($hgseparator, $hggroups);
	if ($hgc == 0 && file_exists("$LocalDir/$hg.php")) {
		include_once("$LocalDir/$hg.php");
		$hgc = 1;
		}
	if ($hgh == 0 && PageExists("$hg.GroupHeader")) {
		$GroupHeaderFmt = "(:include $hg.GroupHeader:)";
		$hgh = 1;
		}
	if ($hgf == 0 && PageExists("$hg.GroupFooter")) {
		$GroupFooterFmt = "(:include $hg.GroupFooter:)";
		$hgf = 1;
		}
	if ($hga == 0 && PageExists("$hg.GroupAttributes")) {
		$GroupAttributesFmt = "$hg/GroupAttributes";
		$hga = 1;
		}
	$PageCSSListFmt["pub/css/$hg.css"] = "$PubDirUrl/css/$hg.css"; 
	array_pop($hggroups);
	}

####### Set up default configs, headers, footers, sidebars & styles
if ($hgc == 0 && file_exists("$LocalDir/default.php")) include_once("$LocalDir/default.php");
if ($hgh == 0 && PageExists("Site.GroupHeader")) $GroupHeaderFmt = "(:include Site.GroupHeader:)";
if ($hgf == 0 && PageExists("Site.GroupFooter")) $GroupFooterFmt = "(:include Site.GroupFooter:)";
$PageCSSListFmt["pub/css/local.css"] = "$PubDirUrl/css/local.css"; 
$PageCSSListFmt = array_reverse($PageCSSListFmt, true);

####### Set's up hierarchical pagenames like SideBar and SideMenu
function HierarchicalPagenames($group, $name) {
	global $hgseparator, $SiteGroup;
	$groups = explode($hgseparator, $group);
	while (count($groups) != 0) {
		$hg_group = implode ($hgseparator, $groups);
		if (PageExists("$hg_group.$name")) return "$hg_group.$name";
		array_pop($groups);
 		}
	return "$SiteGroup.$name";
	}

####### Sets up {$g0} and {$n0} page variables
function hgCountLevels($name) {
    global $hgseparator;
    $parts = explode($hgseparator, $name);
    return count($parts);
	}

####### Sets up {$g2} and {$n3} page variables
function hgSplitName($name, $i) {
    global $hgseparator, $SiteGroup;
    $parts = explode($hgseparator, $name);
    if ($i < 0 || $i >= count($parts)) return '';
	$title = PageTextVar("$SiteGroup.HgGroupTitles", $parts[$i]);
	if ($title != '') return $title;
    return $parts[$i];
	}

####### Returns fixed page name 1) with prefixing, 2) if not cleanurls, and 3) if cleanurls
function hgResolvePageName($pagename) {
	global $hglinkprefix, $hgprefixcode, $hgseparator, $hgname, $hggroup;
	if (substr($pagename, 0, strlen($hgprefixcode)) == $hgprefixcode) $pagename = substr($pagename, strlen($hgprefixcode));
	$r = '/';
	if (! strpos($pagename, $r)) {
		$pagename = ResolvePageName($pagename);
		$hggroup = FmtPageName('$Group', $pagename);
		$hgname = FmtPageName('$Name', $pagename);
		return $pagename;
		}
	$hgpagename = explode($r, $pagename);
	if ($hgpagename[count($hgpagename) - 1 ] == '') array_pop($hgpagename);
	$hgname = $hgpagename[count($hgpagename) - 1];
	array_pop($hgpagename);
	$hggroup = implode($hgseparator, $hgpagename);
	$pagename = ResolvePageName("$hggroup.$hgname");
	return "$pagename";
	}

####### Fixes URL's to allow for prefixing and cleanurls, otherwise no effect
function hgURL($group, $name) {
	global $ScriptUrl, $hglinkprefix, $hgprefixcode, $EnableHgCleanUrls;
	$r = '/';
	if (substr($group, 0, strlen($hgprefixcode)) == $hgprefixcode) {
		$group = substr($group, strlen($hgprefixcode));
		if (substr($name, 0, strlen($hgprefixcode)) == $hgprefixcode) $name = substr($name, strlen($hgprefixcode));
		}
	elseif (($hglinkprefix != '') && (substr($group, 0, strlen($hglinkprefix)) != $hglinkprefix)) $group = $hglinkprefix . "-" . $group;
	if ($EnableHgCleanUrls == true) $group = str_replace("-", $r, $group);
	return "$group$r$name";
	}

####### Strips off prefix if linkprefixing if used from link display
function hgCreateFmt($x) {
	global $hglinkprefix;
	$x = substr($x, strlen($hglinkprefix));
	return "<a class='wikilink' rel='nofollow' href=$x>\$LinkText</a>";
	}

####### Hierarchical links shortcut notation.
Markup('[[hg','<links', '/\\[\\[(-|[\\*\\^]+)(.*?)\\]\\]/e', "hgLinks1('$1', PSS('$2'))");
function hgLinks1($x,$y) {
	global $hglinkprefix, $hgseparator, $hggroup;
	if (substr($x, 0, 1) == "-") return "[[$hggroup-$y]]";
	$hggroups = explode($hgseparator, $hggroup);
	$link = '';
	$c = strlen($x);
	if (substr($x, -1) == '-') $c = $c - 1;
	$i = 0;
	while ($i < $c) {
		if (substr($x, 0, 1) == "*") $link = $link . $hggroups[$i] . $hgseparator;
		if (substr($x, 0, 1) == "^") array_pop($hggroups);
		$i = $i + 1;
		}
	if (substr($x, 0, 1) == "*") $link = substr ($link, 0, - strlen($hgseparator)) . $hgseparator;
	if (substr($x, 0, 1) == "^") $link = implode($hgseparator, $hggroups) . $hgseparator;
	return "[[$link$y]]";
	}
	
####### Breadcrumb markup
Markup('hgbreadcrumb', '>var', '/\(:breadcrumb:\)/e', 'hgBreadCrumb()');
function hgBreadCrumb() {
	global $hgseparator, $hgbreadcrumbseparator, $hgmaxlevels, $hggroup, $hgname, $pagename, $SiteGroup, $EnableBreadCrumbName, $DefaultName;
	$groups = explode($hgseparator, $hggroup);
	if (PageExists("$SiteGroup.HgBreadCrumbs")) $t = "true";
	while (count($groups) != 0) {
		$hg_group = implode ($hgseparator, $groups);
		$hg_title = PageTextVar("$SiteGroup.HgBreadCrumbs", $groups[count($groups) - 1]);
		if (($t == "true") && ($hg_title != '')) $outgroup = $hg_title . $outgroup;
		else $outgroup = "[[$hg_group/$DefaultName|".$groups[count($groups)-1]."]]" . $hgbreadcrumbseparator . $outgroup;
		array_pop($groups);
 		}
	if ($EnableBreadCrumbName == false) return substr($outgroup, 0, - strlen($hgbreadcrumbseparator));
	$outname = PageTextVar($pagename, 'Title');
	if ($outname == '') $outname = PageTextVar($pagename, 'title');
	if ($outname == '') $outname = $hgname;
	return AsSpaced("$outgroup$outname");
	}	
	
####### GroupTitle page variables
function hgGroupTitles($group) {
	global $SiteGroup, $hgseparator;
	$groups = explode($hgseparator, $group);
	$hg_name = $groups[count($groups) - 1];
	if (PageExists("$SiteGroup.HgGroupTitles")) {
		while (count($groups) != 0) {
			$hg_group = implode ($hgseparator, $groups);
			$hg_title = PageTextVar("$SiteGroup.HgGroupTitles", $hg_group);
			if ($hg_title != '') break;
			array_pop($groups);
 			}
		if ($hg_title != '' && $hg_title != ' ') return $hg_title;
		}
	return $hg_name;
	}