<?php
/*
 * This file is part of the easy-CMS project.
 * easy-CMS 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.
 *
 * easy-CMS 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 easy-CMS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

/**
 * @package    Core
 * @subpackage Parser
 */

include_once('classes/core/CoreObject.class.php');
include_once('classes/core/Site.class.php');
include_once('classes/core/parser/tags/Attribute.class.php');

/**
 * Tag Class
 *
 * Tag element
 *
 * @access     public
 * @author	   Cedric Francoys <cedric.francoys@easy-cms.org>
 * @version	   Tag.class, Sun Dec 19 11:07:35 CET 2004
 * @package	   Core
 * @subpackage Parser
 */
class Tag extends CoreObject {
	var $name;
	var $type;
	var $offset;
	var $length;

	/**
	 * @var object
	 */
	var $site;

	/**
	 * @var object
	 */
	var $page;

	/**
	 * @var string
	 */
	var $mode;

	/**
	 * User
	 *
	 * @var object
	 */
	var $user;

	/**
	 * ACL
	 *
	 * @var object
	 */
	var $acl;

	var $tagString;

	var $attributesTable;

	/**
	 * Constructor
	 *
	 * @access   public
 	 * @param    string  The complete tag syntax (i.e. : <tagname attr1="value1" attr2="value2">, <br />, </a>, ...)
 	 * @param    integer The position of the tag in the xml document
 	 * @return   void
	 */
	function Tag($tagString='', $name='', $type='', $offset=0, $length=0) {
		$this->tagString = $tagString;
		$this->name = $name;
		$this->type = $type;
		$this->offset = $offset;
		//$this->length = $length;
		$this->length = strlen($tagString);

		$this->site = &Site::getInstance();
		$aclManager = &$this->site->getACLManager();

		$this->page = &$this->site->getCurrentPage(false, false);
		$this->mode = &$this->site->getCurrentMode();
		$this->user = &$this->site->getCurrentUser();
		$this->acl = &$aclManager->getACL($this->page->getPageAclId());
		$this->attributesTable = array();

		$matches = array();

		if(preg_match_all('`([a-zA-Z-_]+)="([^"]+)"`', $tagString, $matches, PREG_SET_ORDER)){
			$matchesCount = count($matches);
			for($i = 0; $i < $matchesCount; $i++){
				$attrName  = $matches[$i][1];
				$attrValue = $matches[$i][2];
				$attrKey   = strtolower($attrName);
				$this->attributesTable[$attrKey] = &new Attribute($attrName, $attrValue);
			}
		}
	}

	/**
	 * @static
	 */
	function normalizeTagString($tagString){
	}

	/**
	 * @static
	 */
	function getTagNameFromString($tagString){
		$match = array();
		preg_match('`[a-zA-Z-_]+:([a-zA-Z-_]+)\s*`', $tagString, $match);
		if(!isset($match[0])){
			return null;
		}
		return $match[0];
	}

	/**
	 * @static
	 */
	function getTagTypeFromString($tagString){
		if(substr($tagString, 0, 2) == '</'){
			return CLOSE_TAG;
		}elseif(substr($tagString, -2) == '/>'){
			return SINGLE_TAG;
		}else{
			return OPEN_TAG;
		}
	}

	/**
	 * Performs actions specific to the tag
	 *
	 * @access   public
	 * @abstract
 	 * @return   mixed Returns a bool in case of a conditional tag, a string otherwise (html output)
	 */
	function evaluate() {
		return true;
	}

	/**
	 * Name getter
	 *
	 * @access   public
 	 * @return   string The name of the tag
	 */
	function getName() {
		return $this->name;
	}

	function getTagName(){
		return $this->name;
	}

	/**
	 * Type getter
	 *
	 * @access   public
 	 * @return   string The type of the tag
	 */
	function getType() {
		return $this->type;
	}

	function getTagType(){
		return $this->type;
	}

	/**
	* Offset getter
	*
	* @access   public
 	* @return   string The offset of the tag
	*/
	function getOffset(){
		return $this->offset;
	}

	function getTagOffset(){
		return $this->offset;
	}

	/**
	* Length getter
	*
	* @access   public
 	* @return   string The length of the tag
	*/
	function getLength(){
		return $this->length;
	}

	function getTagLength(){
		return $this->length;
	}

	/**
	* Returns the value of the specified attribute
	*
	* @access   public
 	* @return   string The value of the specified attribute if it exists, null otherwise.
	*/
	function getAttribute($attrName, $default_value=null){
		$attrKey = strtolower($attrName);
		if(!isset($this->attributesTable[$attrKey])){
			return $default_value;
		}
		return $this->attributesTable[$attrKey]->getAttributeValue();
	}

	/**
	* Return an attibute object
	*
	* @access   public
 	* @return   string The value of the specified attribute if it exists, null otherwise.
	*/
	function &getTagAttribute($attrName){
		$attrKey = strtolower($attrName);
		if(!isset($this->attributesTable[$attrKey])){
			return null;
		}
		return $this->attributesTable[$attrKey];
	}

	/**
	* Obtain tag infos
	*
	* @access   public
	* @static
 	* @param    string  The tag found
 	* @param    string  A reference to a string to store the name value.
 	* @param    string  A reference to a string to store the type value.
 	* @return   void
	*/
	function getTagInfos($tag, &$name, &$type, &$length){
		$length = strlen($tag);
		$type = 'openTag';
		for($begin = 1; $begin < strlen($tag) && $tag[$begin] == ' '; ++$begin){}
		if($tag[$begin] == '/'){
			$type = 'closeTag';
			++$begin;
		}
		for($end = $begin; $end < strlen($tag) && $tag[$end] != ' ' && $tag[$end] != '>'; ++$end){}
		if($tag[strlen($tag)-2] == '/')
			$type = 'singleTag';
		$name = substr($tag, $begin, $end-$begin);
	}

	/**
	* Returns the regular expression to get the value of an attribute
	*
	* @static
	* @access   private
 	* @return   string
	*/
	function getERegValue(){
		$ereg = "(\\\"[^\\\"]+\\\")";
		return $ereg;
	}

	/**
	* Returns the regular expression for getting the substring of a tag containing the name and the associated value of a specified attribute
	*
	* @access   private
	* @static
 	* @param    string The name of the wanted attribute
 	* @return   string The associated regular expression
	*/
	function getERegAttr($attrName){
		$ereg = '(';
		for($i = 0; $i < strlen($attrName);++$i){
			$ereg .= '['.strtoupper($attrName[$i]).strtolower($attrName[$i]).']';
		}
		$ereg .= '\s*=".*")';
		return $ereg;
	}

	/**
	* Returns the value substring of an attribute
	*
	* @access   private
	* @static
 	* @param    string The attribute and its value (i.e. : attr="value")
 	* @return   string The value of the specified attribute
	*/
	function getValue($attribute){
		if ( ($res = preg_match($this->getERegValue(), $attribute, $matches)) ){
			return substr($matches[0], 1, strlen($matches[0])-2);
		}
		return null;
	}
}
?>