<?php
/**
 * This file is part of the set of generic classes available for implementations
 * of the DDR Simple API to speed up implementation. It contains a generic
 * implementation of the {@link PropertyValue} interface.
 * 
 * @author Sylvain Lequeux
 * @author Francois Daoust <fd@w3.org>
 * @package AskPythia
 * @subpackage Implementation
 * @version $Revision: 1.11 $
 * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231.html W3C Software Notice and License
 * @copyright Copyright (c) 2009, W3C (MIT, ERCIM, Keio)
 */

/**
 * Include the {@link PropertyValue} interface description.
 */
require_once(dirname(__FILE__).'/../../interface/propertyValue.php');
/**
 * Include the {@link PropertyRef} interface description.
 */
require_once(dirname(__FILE__).'/../../interface/propertyRef.php');
/**
 * Include the {@link SystemException} class description.
 */
require_once(dirname(__FILE__).'/../../interface/systemException.php');
/**
 * Include the {@link ValueException} class definition as
 * getter methods raise this exception when the value is empty or
 * not of the requested type.
 */
require_once(dirname(__FILE__)."/../../interface/valueException.php");

/**
 * A basic {@link PropertyValue} holds a {@link PropertyRef} and string pair,
 * where the string represents the value of the property identified by the
 * PropertyRef key.
 * 
 * @author Sylvain Lequeux
 * @author Francois Daoust <fd@w3.org>
 * @package AskPythia
 * @subpackage Implementation
 * @link http://www.w3.org/TR/DDR-Simple-API/ Device Description Repository Simple API
 * @version $Revision: 1.11 $
 * @license http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231.html W3C Software Notice and License
 * @copyright Copyright (c) 2009, W3C (MIT, ERCIM, Keio)
 */
class BasicPropertyValue implements PropertyValue{
	/**
	 * @var PropertyRef The property reference.
	 */
	private $propertyRef;
	/**
	 * @var string The value of the property.
	 */
	private $value;
	
	/**
	 * Creates an instance of the BasicPropertyValue class initialized with
	 * the given property reference and value.
	 * 
	 * @param PropertyRef $propertyRef The property reference.
	 * @param mixed $value The property value.
	 * @return BasicPropertyValue The property as a new instance of BasicPropertyValue.
	 * @exception SystemException The property reference is not of the excpected type.
	 */
	public function __construct($propertyRef, $value){
		if(!isset($propertyRef)){
			throw new SystemException(
				'Property name cannot be NULL.',
				SystemException::$ILLEGAL_ARGUMENT);
		}
		if(!($propertyRef instanceof PropertyRef)){
			throw new SystemException(
				'The property reference does not implement the PropertyRef interface.',
				SystemException::$ILLEGAL_ARGUMENT);
		}
		$this->propertyRef = $propertyRef;
		$this->value = $value;
	}
	
	public function getDouble(){
		$this->checkExistence();
		if (!is_double($this->value)) {
			throw new ValueException(
				"Property value is not a double.",
				ValueException::$INCOMPATIBLE_TYPES);
		}
		return $this->value;
	}
	
	public function getLong(){
		$this->checkExistence();
		if (!is_long($this->value)) {
			throw new ValueException(
				"Property value is not a long.",
				ValueException::$INCOMPATIBLE_TYPES);
		}
		return $this->value;
	}
	
	public function getString(){
		$this->checkExistence();
		if (is_array($this->value)) {
			$res = '';
			foreach ($this->value as $key=>$value) {
				$res .= (string)$value . ',';
			}
			$res = substr($res, 0, strlen($res) - 1);
			return $res;
		}
		else {
			return (string)$this->value;
		}
	}
	
	public function getBoolean(){
		$this->checkExistence();
		if (!is_bool($this->value)) {
			throw new ValueException(
				"Property value is not a boolean.",
				ValueException::$INCOMPATIBLE_TYPES);
		}
		return $this->value;
	}
	
	public function getInteger(){
		$this->checkExistence();
		if (!is_int($this->value)) {
			throw new ValueException(
				"Property value is not an int.",
				ValueException::$INCOMPATIBLE_TYPES);
		}
		return $this->value;
	}
	
	public function getEnumeration(){
		$this->checkExistence();
		if (!is_array($this->value)) {
			throw new ValueException(
				"Property value is not an enumeration.",
				ValueException::$INCOMPATIBLE_TYPES);
		}
		return $this->value;
	}
	
	public function getFloat(){
		$this->checkExistence();
		if (!is_float($this->value)) {
			throw new ValueException(
				"Property value is not a float.",
				ValueException::$INCOMPATIBLE_TYPES);
		}
		return $this->value;
	}
	
	public function exists(){
		return isset($this->value);	
	}
	
	public function getPropertyRef(){
		return $this->propertyRef;
	}
	
	/**
	 * Checks that the property value is defined.
	 * 
	 * The function is identical to the {@link exists()} method, except it
	 * throws a ValueException when the property value is not defined.
	 *   
	 * @exception ValueException The property value is empty.
	 */
	private function checkExistence(){
		if (!$this->exists()) {
			throw new ValueException(
				"Property value is empty and cannot be retrieved.",
				ValueException::$NOT_KNOWN);
		}
	}
}
?>