<?php

class XTemplate {

	var $varkeys = array();
	var $varvals = array();
	var $blocks_templates = array();
	var $blocks_tree = array();
	var $TemplateID = '';
	var $Db;
	public static $FeedsLinks = array();

	function __construct($template) {
		global $DatabaseBroker;
		$this->Db = $DatabaseBroker;
		$this->setTemplate($template);
	}

	function &getElements() {
		global $REGISTRY;
		$prep = &$REGISTRY['PreparedTemplates'];
		if(empty($this->TemplateID) or empty($prep[$this->TemplateID])) {
			$blocks_tree = array();
			debug('XTemplate','Building tree<br>');
			$this->buildBlocksTree('_template', $blocks_tree);
//print $this->TemplateID;printArray($blocks_tree);	
			if(!empty($this->TemplateID)) {
				$prep[$this->TemplateID]['Tree'] = $blocks_tree['_template'];
				$prep[$this->TemplateID]['Blocks'] = $this->blocks_templates;
				$this->blocks_tree = &$prep[$this->TemplateID]['Tree'];
			} else {
				$this->blocks_tree = &$blocks_tree['_template'];
//printArray($prep);				
//printArray($this->blocks_tree);		exit;		
			}
		}
		else {
			debug('XTemplate','Getting tree from Cache');
			$this->blocks_tree = &$prep[$this->TemplateID]['Tree'];
			$this->blocks_templates = &$prep[$this->TemplateID]['Blocks'];
		}
		return $this->blocks_tree;
	}

	function buildBlocksTree($varname,&$parent) {
		$reg = '/<!--\s+BEGIN ([^\s]+)\s+-->(.*)<!--\s+END \1\s+-->/s';
		$template = $this->get_var($varname);
		$parent[$varname] = array();
		if(preg_match_all($reg,$template,$m)) {
			foreach(array_keys($m[2]) as $k) {
				$name = $m[1][$k];
				$this->set_var($name,$m[2][$k]);
				$template = preg_replace("/<!--\s+BEGIN $name\s+-->(.*)<!--\s+END $name\s+-->/sm", "{" . $name . "}", $template);
				$this->buildBlocksTree($name,$parent[$varname]);
			}
		}
		$this->blocks_templates[$varname] = $template;
		foreach($this->get_undefined($varname) as $var){
			$parent[$varname][$var] = preg_match("/[:?]/",$var)? 'slot' : '';
			//------added for Templates in layouts
			if(empty($parent[$varname][$var])) {
				$sub = preg_match('/^[\da-zA-Z\-_]+\*([\da-zA-Z\-_]+)\*(\d+)\*(\d+)\*(\d+)$/', $var, $matches);
				$parent[$varname][$var] = $sub ? 'subobject' : '';
			}
			//----------- 
		}
	}

	function setTemplateID($id = '') {
		$this->TemplateID = $id;
	}

	function setTemplate(&$template) {
		$this->varkeys = array();
		$this->varvals = array();
		$this->set_var("_template",$template);
	}

	function parseTemplate(&$filled) {
		$this->reset_vars();
//	printArray($this->blocks_tree);
		$ret = $this->parseRecursive("_template",array(&$filled),$this->blocks_tree);
		$ret=$this->pasteDefaultJs($ret);
		return $ret;
	}
	
	function pasteDefaultJs($ret){
		global $REGISTRY;
		if(preg_match('~(<html)~i',$ret)){
			if(@$REGISTRY['Request']['LocalTarget'][1]!='Registar'){
				if(empty($REGISTRY['subdomain'])) {
					$this->getModule();
					empty($selected2[0]) and $selected2['0'] = array('type' => 1,'value' => ' ');
					empty($selected2[1]) and $selected2['1'] = array('type' => 2,'value' => ' ');
					empty($selected2[2]) and $selected2['2'] = array('type' => 3,'value' => ' ');
					foreach($selected2 as $key => $val){
						if($val['type']==1) {
							switch(@$selected[$key]['use_default']) {
								default: case 0: case 3: $ret = preg_replace('~</head>~i',$val['value']."\r\n".'</head>',$ret,1); break;
								case 2:
									if(preg_match('~(<!-- start head JS -->)~i',$ret))
										$ret = preg_replace('~(<!-- start head JS -->)~i',$val['value'].'$1',$ret,1);
									else $ret = preg_replace('~</head>~i',$val['value'].'</head>',$ret,1);
								break;
								case 1: break;
							}
						}
						if($val['type']==2) {
							switch(@$selected[$key]['use_default']) {
								default: case 0: case 2: $ret = preg_replace('~(<body.*?>)~i','$1'.$val['value'],$ret,1); break;
								case 3:
									if(preg_match('~(<!-- finish body_before JS -->)~i',$ret))
										$ret = preg_replace('~(<!-- finish body_before JS -->)~i','$1'.$val['value'],$ret,1);
									else $ret = preg_replace('~(<body.*?>)~i','$1'.$val['value'],$ret,1);
								break;
								case 1: break;
							}
						}
						if($val['type']==3) {
							switch(@$selected[$key]['use_default']) {
								default: case 0: case 3: $ret = preg_replace('~</body>~i',$val['value'].'</body>',$ret,1); break;
								case 2:
									if(preg_match('~(<!-- start body_after JS -->)~i',$ret))
										$ret = preg_replace('~(<!-- start body_after JS -->)~i',$val['value'].'$1',$ret,1);
									else $ret = preg_replace('~</body>~i',$val['value'].'</body>',$ret,1);
								break;
								case 1: break;
							}
						}
					}
					
				}
//				$ret = preg_replace('~</head>~i','<script src="/registarJS/inc/dynamicTemplate.js" type="text/javascript"></script>'."\r\n".'</head>',$ret,1);
				self::$FeedsLinks = array_unique(self::$FeedsLinks);
				if(isset($this->_js) && $this->_js == 50) {
					if(!empty($this->Target[2])) {
						$city = $this->Db->SelectAny('select * from city where name_in_url=\''.$this->Target[2].'\'');
						if(!empty($city[0])) {
							$area_codes = eregi_replace('{|}','',$city[0]['area_codes']);
							$code = explode(',',$area_codes);
							$ret = preg_replace('~</head>~i','<script type="text/javascript"> var CityAreaCode = '.$code[0].'; var CityName = \''.$city[0]['name_in_text'].'\';</script>'."\r\n".'</head>', $ret,1);
						}
						else $ret = preg_replace('~</head>~i','<script type="text/javascript"> var CityAreaCode; var CityName;</script>'."\r\n".'</head>', $ret,1);
					}
					else $ret = preg_replace('~</head>~i','<script type="text/javascript"> var CityAreaCode; var CityName;</script>'."\r\n".'</head>', $ret,1);
				}
				$ret = preg_replace('~</head>~i', implode("\r\n", self::$FeedsLinks)."\r\n".'</head>', $ret,1);
				$ret = preg_replace('~(<!-- start .*? JS -->)~i','',$ret,-1);
				$ret = preg_replace('~(<!-- finish .*? JS -->)~i','',$ret,-1);
			}
		}
		return $ret;
	}

	function parseRecursive($varname,$filled,$tree = '') {
		global $REGISTRY;
		$tmpvar = '_temp'.$varname;
		$this->set_var($tmpvar,'');
		$this->set_var($varname,isset($this->blocks_templates[$varname])? $this->blocks_templates[$varname] : '');
		$subobject = false;
				
		foreach(array_keys($filled) as $i) {
			$vars = array();
			foreach(array_keys($tree) as $key) {
				if ($tree[$key] == 'slot') {
					debug ("parseRecursive", "Slot found: " . $key . "<br>");
					$extra = isset ($filled[$i][$key]) ? $filled[$i][$key] : "";
					$render = renderSlot ($key, $extra, FALSE, $this->Passing);
					if ($this->useCache) {
						if ($render["Pass"] or !$render["Cache"]) $this->Pass = 1;
						if (!$render["Cache"] and !$this->Passing) {
							$vars[$key] = '{' . unparseQuery (parseQuery($key), $extra) . '}';
						} else {
							$this->CacheTarget = count($this->CacheTarget) > count($render["CacheTarget"])? $this->CacheTarget : $render["CacheTarget"];
							$render["CacheInherit"] or $this->CacheInherit = FALSE;
							$vars[$key] = $render["Content"];
						 }
					}
					else $vars[$key] = $render["Content"];
				} elseif(isset($filled[$i][$key])) {
						$vars[$key] = is_array($tree[$key])? $this->parseRecursive($key,$filled[$i][$key],$tree[$key]) : $filled[$i][$key];
					} else if($tree[$key] == 'subobject' ) { 				//--added for Template in Layout
		   					$subobject = true;
		   			  }	else { //print $tree[$key]; 
								$vars[$key] = is_array($tree[$key])? $this->parseRecursive($key,array(),$tree[$key]) : $this->parseLanguage($key);
								$this->unset_var($key);
						}
			}
			if ($this->Cache or $this->Passing) {
				$this->set_var ($vars);
				$this->parse ($tmpvar, $varname, TRUE);
			}
		}
//printArray($REGISTRY['Request']['Target']);		
		$rezult=$this->get_var($tmpvar);
		$url = @parse_url(getenv('HTTP_REFERER'));
		if(empty($url['path'])) $url['path'] = '/';
		if(isset($url['host']) && $url['host'] != $_SERVER['HTTP_HOST']) $url['path'] = $url['scheme'].'://'.$url['host'].$url['path'];
		if(empty($REGISTRY['Request']['Target'][2])
		|| !in_array($REGISTRY['Request']['Target'][2], array('ContentManager', 'LayoutManager', 'DefaultPage'))
		|| (isset($REGISTRY['Request']['Target'][3]) && $REGISTRY['Request']['Target'][3] == 'Preview')){
			preg_match_all('~{Template\*([\da-zA-Z\-_]+)\*(\d+)\*(\d+)\*(\d+)}~', $this->get_var($tmpvar), $arr_vars);
			foreach ($arr_vars[0] as $ind => $val) $rezult = preg_replace('~'.preg_replace('~\*~', '\*', $val).'~is', $this->getTemplates($arr_vars[2][$ind], $url['path']), $rezult);
			preg_match_all('~{ImportedFeed\*([\da-zA-Z\-_]+)\*(\d+)\*(\d+)\*(\d+)}~', $this->get_var($tmpvar), $arr_vars);
			foreach ($arr_vars[0] as $ind => $val) $rezult = preg_replace('~'.preg_replace('~\*~', '\*', $val).'~is', $this->getImportedFeed($arr_vars[2][$ind]), $rezult);
			preg_match_all('~{Feed\*([\da-zA-Z\-_]+)\*(\d+)\*(\d+)\*(\d+)}~', $this->get_var($tmpvar), $arr_vars);
			foreach ($arr_vars[0] as $ind => $val) $rezult = preg_replace('~'.preg_replace('~\*~', '\*', $val).'~is', $this->getFeed($arr_vars[2][$ind]), $rezult);
			preg_match_all('~{CitiesSet\*([A-Z]+)}~', $this->get_var($tmpvar), $arr_vars);
			foreach ($arr_vars[0] as $ind => $val) $rezult = preg_replace('~'.preg_replace('~\*~', '\*', $val).'~is', $this->getCitiesSet($arr_vars[1][$ind]), $rezult);
		}
		return $rezult;
	}

	function getTemplates($id, $refer = ''){
			$template = $this->Db->SelectAny('SELECT value FROM templateitem WHERE ownerid = '.$id.' LIMIT 1');
			return empty($template) ? '' : $template[0]['value'];
	}
	
	function getImportedFeed($id) {
		GLOBAL $REGISTRY;
		$importedfeed = $this->Db->SelectAny('SELECT link, title FROM importedfeed WHERE id = '.$id.' LIMIT 1');
		if(empty($importedfeed)) return '';
		$selected = $this->Db->SelectAny('SELECT title, link, description FROM importedfeeddata WHERE ownerid IN (SELECT id FROM importedfeedsource WHERE ownerid = '.$id.')');
		if(empty($selected)) return '';
		$result = '<table class="impf" cellpadding=0 cellspacing=0>';
		$result .= '<tr><th class="impf_title"><a href="/'.$importedfeed[0]['link'].'" class="impf_link"><img src="'.$REGISTRY['Globals']['static']['adminpicPath'].'/rss/rss1.gif" title="RSS Feed" style="border: 0;"> '.$importedfeed[0]['title'].'</a></th></tr>';
		self::$FeedsLinks[] = '<link rel="alternate" type="application/rss+xml" title="'.htmlspecialchars($importedfeed[0]['title']).'" href="/'.$importedfeed[0]['link'].'">';
		$count = count($selected);
		for ($i = 0; $i < $count; $i++) {
			$short_description = strip_tags($selected[$i]['description']);
			if(empty($short_description)) continue;
			$result .= '<tr><td class="impf_item_title"><a href="'.$selected[$i]['link'].'" class="impf_item_link">'.(strlen($selected[$i]['title']) > 80 ? substr($selected[$i]['title'], 0, 80).'...' : $selected[$i]['title']).'</a></td></tr>';
			$result .= '<tr><td class="impf_item_descr">'.(strlen($short_description) > 300 ? substr($short_description, 0, 300).'...' : $short_description).'</td></tr>';
		}
		$result .= '</table>';
		return $result;
	}

	function getCitiesSet($id) {
		global $REGISTRY;
		$set = $this->Db->SelectAny('SELECT c.*, s.name as state FROM city c, state s WHERE s.shortname = \''.$id.'\' and s.id = c.state');
		if(empty($set)) return '';
		$count = sizeof($set);
		for($i = 0; $i < $count; $i++) $links[] = makeLink($this->Home.'/cities/'.$set[$i]['name_in_url'],$set[$i]['name_in_text']);
		return implode(', ',$links);
	}
	
	function getFeed($id) {
		GLOBAL $REGISTRY;
		$feed = $this->Db->SelectAny('SELECT link, title, on_web_max_count FROM feed WHERE id = '.$id.' LIMIT 1');
		if(empty($feed)) return '';
		$selected = $this->Db->SelectAny('SELECT title, link, description FROM feeditem WHERE ownerid  = '.$id.' AND canceled = 0 ORDER BY pubdate DESC LIMIT '.$feed[0]['on_web_max_count']);
		if(empty($selected)) return '';
		$result = '<table class="feed" cellpadding=0 cellspacing=0>';
		$result .= '<tr><th class="feed_title"><a href="/'.$feed[0]['link'].'" class="feed_link"><img src="'.$REGISTRY['Globals']['static']['adminpicPath'].'/rss/rss1.gif" title="RSS Feed" style="border: 0;"> '.$feed[0]['title'].'</a></th></tr>';
		self::$FeedsLinks[] = '<link rel="alternate" type="application/rss+xml" title="'.htmlspecialchars($feed[0]['title']).'" href="/'.$feed[0]['link'].'">';
		$count = count($selected);
		for ($i = 0; $i < $count; $i++) {
			$short_description = strip_tags($selected[$i]['description']);
			if(empty($short_description)) continue;
			$result .= '<tr><td class="feed_item_title"><a href="'.$selected[$i]['link'].'" class="feed_item_link">'.(strlen($selected[$i]['title']) > 80 ? substr($selected[$i]['title'], 0, 80).'...' : $selected[$i]['title']).'</a></td></tr>';
			$result .= '<tr><td class="feed_item_descr">'.(strlen($short_description) > 300 ? substr($short_description, 0, 300).'...' : $short_description).'</td></tr>';
		}
		$result .= '</table>';
		return $result;
	}

	function parseLanguage($key,$value = '') {
		if(strstr($key,'local.')) {
			list($local,$type,$var) = explode('.',$key);
			$value = isset($this->localLangContent[$type][$var])? $this->localLangContent[$type][$var] : '';
		}
		if(strstr($key,'global.')) {
			list($global,$type,$var) = explode('.',$key);
			$value = isset($this->globalLangContent[$type][$var])? $this->globalLangContent[$type][$var] : '';
		}
		return $value;
	}

	function getTemplate() {
		return $this->get_var("_template");
	}

	function reset_vars() {
		$this->varkeys = array();
		$this->varvals = array();
		$this->set_var($this->blocks_templates);
	}

	//============ from Template.class.inc ==============

	function set_var($varname,$value = '') {
		if(!is_array($varname)) {
			$this->varkeys[$varname] = '/'.$this->varname($varname).'/';
			$this->varvals[$varname] = $value;
			return $value;
		}
		else
			foreach($varname as $k => $v) {
				$this->varkeys[$k] = '/'.$this->varname($k).'/';
				$this->varvals[$k] = $v;
		}
	}

	function prepare_value($value) {
		return str_replace('$','\$',$value);
	}

	function unset_var($varnames) {
		is_array($varnames) or $varnames = array($varnames);
		foreach($varnames as $varname) {
			if(isset($this->varkeys[$varname])) unset($this->varkeys[$varname]);
			if(isset($this->varvals[$varname])) unset($this->varvals[$varname]);
		}
	}

	function varname($varname) {
			return preg_quote('{'.$varname.'}');
	}

	function parse($target,$varname,$append = false) {
		if(!is_array($varname))
			return $this->set_var($target,($append? $this->get_var($target) : '').$this->subst($varname));
		else {
			foreach($varname as $h) {
				$str = $this->subst($h);
				$this->set_var($target,$str);
			}
			return $str;
		}
	}

	function subst($varname) {
		return @preg_replace($this->varkeys,$this->prepare_value($this->varvals),$this->get_var($varname));
	}

	function get_var($varname) {
		if(!is_array($varname)) return $this->varvals[$varname];
		else {
			foreach($varname as $v) $result[$v] = $this->varvals[$v];
			return empty($result)? array() : $result;
		}
	}

	function get_undefined($varname) {
		$result = array();
		preg_match_all("/\{([^}]+)\}/",$this->get_var($varname),$m);
		if(is_array($m[1]))
			foreach($m[1] as $v)
				if(!isset($this->varkeys[$v]))
					$result[$v] = $v;
		return empty($result)? array() : $result;
	}

	function get_vars() {
		foreach(array_keys($this->varkeys) as $k)
			$result[$k] = $this->get_var($k);
		return empty($result)? array() : $result;
	}

	function getModule($id = 0) {
		global $REGISTRY;
		$value = '';
		$path = '';
		if(!empty($REGISTRY['Request']['RawTarget'])) $path = $REGISTRY['Request']['RawTarget'];
		if(!empty($REGISTRY['Request']['Search'])) {
			foreach($REGISTRY['Request']['Search'] as $k => $v) {
				if(isset($REGISTRY['VirtualSlotTarget']['main'][$path.'?'.$k.'='.$v])) {
					$value = $REGISTRY['VirtualSlotTarget']['main'][$path.'?'.$k.'='.$v];
				}
			}
		}
		if(empty($value)) {
			foreach($REGISTRY['VirtualSlotTarget']['main'] as $k => $v) {
				if(equals($k,$path)) $value = $v;
			}
		}
		$query = explode('?',$value);
		$target = explode(':',array_shift($query));
		$properties = array_shift($query);
		$pair = explode('=',$properties);
		$name = array_shift($target);
		$this->_js = !empty($pair[1])? $pair[1] : 0;
	}
}
?>
