<?php
/**
 * @copyright  2013 Roberto Perpuly
 *
 * This source may not be redistributed without prior consent.  Access to the 
 * source does not imply that you have consent to redistribute either this source
 * code or the generated binary. See LICENSE file for details.
 */

/**
 * A detected tag is a tag artifact.  The Triumph will use the list of detected tags to aid
 * in code completion.  The tag detectors will only augment what the Triumph does; Triumph will already
 * gather tags the source code (classes, methods, functions) and will gather tag types
 * from the PHPDoc comments; but sometimes some tags may not be caught because they are created 
 * at run-time and with variable names. In this case, the PHP tag detectors can tell the editor 
 * what those dynamic resources are.
 */
class Triumph_DetectedTag {

	/**
	 * The lexeme of the tag; the identifier name only. For example, if the resource was 'MY_Email::read'
	 * then the identifer would be 'read'
	 * @var string
	 */
	public $identifier;
	
	/**
	 * The class of the tag; the class name only. For example, if the resource was 'MY_Email::read'
	 * then the identifer would be 'MY_Email'
	 * @var string
	 */
	public $className;
	
	/**
	 * The fully qualified namespace name of the tag; For example, if the resource was '\Zend\Email::read'
	 * then the identifer would be '\Zend'
	 * @var string
	 */
	public $namespaceName;
	
	/**
	 * The fully qualified name of the return type of this tag. If the return type is a class
	 * it should contain the fully qualified namespace name. 
	 * @var string
	 */
	public $returnType;
	
	/**
	 * For a class property; signature will just be the same as resource. For a method or functions, this will have the 
	 * function arguments.
	 * @var string
	 */
	public $signature;
	
	/**
	 * A friendly message that is displayed to the user when this tag is shown.
	 * @var string
	 */
	public $comment;
	
	/**
	 * Whether this member or method is a static method.
	 * this is important, as triumph is smart enough to show only static members / methods
	 * when a static call is being made. Defaults to FALSE
	 * @var boolean TRUE if this is a static member/method
	 */
	public $isStatic;
		
	/**
	 * The type of this resource. One of the type constants.
	 */
	public $type;
	
	const TYPE_CLASS = 0;
	const TYPE_METHOD = 1;
	const TYPE_FUNCTION = 2;
	const TYPE_MEMBER = 3;
	const TYPE_DEFINE = 4;
	const TYPE_CLASS_CONSTANT = 5;
	
	/**
	 * Create a property resource(a class member). For now this property is assumed to have public access.
	 */
	public static function CreateMember($className, $propertyName, $propertyType, $namespaceName = '\\', $comment = '') {
		$member = new Triumph_DetectedTag();
		$member->MakeMember($className, $propertyName, $propertyType, $namespaceName, $comment);
		return $member;
	}
	
	/**
	 * Create a method resource(a class member). For now this method is assumed to have public access.
	 */
	public static function CreateMethod($className, $methodName, $methodReturnType, $namespaceName = '\\', $comment = '') {
		$method = new Triumph_DetectedTag();
		$method->MakeMethod($className, $methodName, $methodReturnType, $namespaceName, $comment);
		return $method;
	}
	
	/**
	 * create a filled or empty instance. If creating an empty instance, the MakeXXX methods will be useful.
	 */
	public function __construct($resource = '', $identifier = '', $returnType = '', $type = '', $namespaceName = '\\', $comment = '') {
		$this->resource = $resource;
		$this->identifier = $identifier;
		$this->returnType = $returnType;
		$this->type = $type;
		$this->className = '';
		$this->namespaceName = $namespaceName;
		$this->signature = '';
		$this->comment = $comment;
		$this->isStatic = FALSE;
	}

	/**
	 * Create a property resource(a class member). For now this property is assumed to have public access.
	 */
	public function MakeMember($className, $propertyName, $propertyType, $namespaceName, $comment) {
		$this->className = $className;
		$this->identifier = $propertyName;
		$this->returnType = $propertyType;
		$this->namespaceName = $namespaceName;
		$this->comment = $comment;
		$this->type = self::TYPE_MEMBER;
	}
	
	/**
	 * Create a class method. For now this method is assumed to have public access.
	 */
	public function MakeMethod($className, $methodName, $methodReturnType, $namespaceName, $comment) {
		$this->className = $className;
		$this->identifier = $methodName;
		$this->returnType = $methodReturnType;
		$this->namespaceName = $namespaceName;
		$this->comment = $comment;
		$this->type = self::TYPE_METHOD;
	}
	
	/**
	 * Sets the properties so that this resource is a function.
	 * @return void
	 */
	public function MakeFunction($functionName, $returnType, $namespaceName, $comment) {
		$resource = $functionName;
		$this->identifier = $functionName;
		$this->returnType = $returnType;
		$this->namespaceName = $namespaceName;
		$this->type = self::TYPE_FUNCTION;
	}
	
	public function Clear() {
		$this->identifier = '';
		$this->returnType = '';
		$this->comment = '';
		$this->type = '';
	}
		
	public static function typeString($type) {
		if (self::TYPE_CLASS == $type) {
			return "CLASS";
		}
		else if (self::TYPE_CLASS_CONSTANT == $type) {
			return "CLASS_CONSTANT";
		}
		else if (self::TYPE_DEFINE == $type) {
			return "DEFINE";
		}
		else if (self::TYPE_FUNCTION == $type) {
			return "FUNCTION";
		}
		else if (self::TYPE_MEMBER == $type) {
			return "MEMBER";
		}
		else if (self::TYPE_METHOD == $type) {
			return "METHOD";
		}
	}
}