<?php

/**
 *
 * @author Peter Csubak (chuby)
 * @copyright Peter Csubak (chuby)
 */

class CProperty extends Annotation{
	public $getter = "--default--"; // --none-- == writeonly property
	public $setter = "--default--"; // --none-- == readonly property
	public $type = "--notobject--"; // {<class> | --notobject-- by default} expected instance of a class or a super class' subclass  
}

abstract class PComponent{

	/** @CProperty(getter="getBindedTo", setter="bind") */
	protected $bindedTo;
	/** @CProperty(getter="--none--", setter="activateEvents") */
	protected $activeEvents;
	/** @CProperty */
	protected $eventsLock;
	/** @CProperty */
	protected $cssclazz;
	/** @CProperty */
	protected $id;
	
	public abstract function render();
	
	public function __toString(){
		return "<![CDATA[".$this->render()."]]>";
	}
	
	public function __get($name){
		$annot = new ReflectionAnnotatedProperty(get_class($this), $name);
		if ($annot->isProtected() && $annot->hasAnnotation("CProperty")){
			$prop = $annot->getAnnotation("CProperty");
			if ($prop->getter == "--default--"){
				return $this->$name;
			}elseif ($prop->getter == "--none--"){
				throw new ComponentException("A <<name>> csak írható property, nem lehet lekérdezni.", array("name" => $name), 700);
			}else{
				$meth = new ReflectionMethod(get_class($this), $prop->getter);
				$meth->invoke($this);
			}
		}
	}
	
	public function __set($name, $value){
		$annot = new ReflectionAnnotatedProperty(get_class($this), $name);
		if ($annot->isProtected() && $annot->hasAnnotation("CProperty")){
			$prop = $annot->getAnnotation("CProperty");
			if ($prop->setter == "--default--"){
				if ($prop->type == "--notobject--"){
					$this->$name = $value;
				}else{
					$reftype = new ReflectionClass($prop->type);
					if ($reftype->isInstance($value)){
						$this->$name = $value;
					}else{
						throw new ComponentException("A <<name>> property elvárt típusa különbözik a megadott érték típusától.", array("name" => $name), 704);
					}
				}
			}elseif ($prop->setter == "--none--"){
				throw new ComponentException("A <<name>> csak olvasható property, nem lehet beállítani.", array("name" => $name), 701);
			}else{
				$ref = new ReflectionClass(get_class($this));
				if ($ref->hasMethod($prop->setter)){
					$meth = $prop->setter;
					$this->$meth($value);
				}else{
					throw new ComponentException("Nem található a <<prop>> nevű property beállító metódusa.", array("prop" => $name), 703);
				}
			}
		}
	}
	
	public function bind($id){
		$this->bindedTo = $id;
	}
	
	public function getBindedTo(){
		return $this->bindedTo;
	}
	
	public function activateEvents($eventTypes){
		if (is_array($eventTypes)){
			$this->activeEvents = $eventTypes;
		}else{
			$this->activeEvents = array();
			$this->activeEvents[0] = $eventTypes;
		}
	}
	
	public function isActive($eventType){
		if (is_array($this->activeEvents)){
			foreach ($this->activeEvents as $evt){
				if ($eventType == $evt){
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 * 
	 * @deprecated 
	 */
	public function setCSSClass($clss){
		$this->cssclazz = $clss;
	}
	
	/**
	 * 
	 * @deprecated 
	 */
	public function getCSSClass(){
		return $this->cssclazz;
	}
	
	/**
	 * 
	 * @deprecated 
	 */
	public function setId($id){
		$this->id = $id;
	}
	
	/**
	 * 
	 * @deprecated 
	 */
	public function getId(){
		return $this->id;
	}
	
	/**
	 * 
	 * @deprecated 
	 */
	public function setEventsLock($lock){
		$this->eventsLock = $lock;
	}
	
	/**
	 * 
	 * @deprecated 
	 */
	public function getEventsLock(){
		return $this->eventsLock;
	}
	
}
?>