<?php
namespace SabaiApps\Framework\Application;

/**
 * Context class representing the current application state.
 * Manages request, route, status, and arbitrary attributes.
 */
class Context {

	// Status constants for the context
	const STATUS_ERROR = 1, STATUS_SUCCESS = 2, STATUS_VIEW = 3;

	/**
	 * @var int Current status of the context.
	 */
	protected $_status = self::STATUS_VIEW;

	/**
	 * @var AbstractRequest|null The current request object.
	 */
	private $_request;

	/**
	 * @var array Associative array of context attributes.
	 */
	private $_attributes = array();

	/**
	 * @var IRoute|null The current route object.
	 */
	private $_route;

	/**
	 * Sets the request object for this context.
	 *
	 * @param AbstractRequest $request
	 * @return $this
	 */
	public function setRequest( AbstractRequest $request ) {
		$this->_request = $request;

		return $this;
	}

	/**
	 * Gets the request object.
	 *
	 * @return AbstractRequest|null
	 */
	public function getRequest() {
		return $this->_request;
	}

	/**
	 * Gets all context attributes.
	 *
	 * @return array
	 */
	public function getAttributes() {
		return $this->_attributes;
	}

	/**
	 * Sets context attributes.
	 * If $merge is true, merges with existing attributes.
	 *
	 * @param array $attributes
	 * @param bool  $merge
	 * @return $this
	 */
	public function setAttributes( array $attributes, $merge = true ) {
		$this->_attributes = $merge ? array_merge( $this->_attributes, $attributes ) : $attributes;

		return $this;
	}

	/**
	 * Sets the route object for this context.
	 *
	 * @param IRoute $route
	 * @return $this
	 */
	public function setRoute( IRoute $route ) {
		$this->_route = $route;

		return $this;
	}

	/**
	 * Gets the route object.
	 *
	 * @return IRoute|null
	 */
	public function getRoute() {
		return $this->_route;
	}

	/**
	 * Sets the status to success.
	 *
	 * @return $this
	 */
	public function setSuccess() {
		$this->_status = self::STATUS_SUCCESS;

		return $this;
	}

	/**
	 * Checks if the status is success.
	 *
	 * @return bool
	 */
	public function isSuccess() {
		return $this->_status === self::STATUS_SUCCESS;
	}

	/**
	 * Sets the status to error.
	 *
	 * @return $this
	 */
	public function setError() {
		$this->_status = self::STATUS_ERROR;

		return $this;
	}

	/**
	 * Checks if the status is error.
	 *
	 * @return bool
	 */
	public function isError() {
		return $this->_status === self::STATUS_ERROR;
	}

	/**
	 * Sets the status to view.
	 *
	 * @return $this
	 */
	public function setView() {
		$this->_status = self::STATUS_VIEW;

		return $this;
	}

	/**
	 * Checks if the status is view.
	 *
	 * @return bool
	 */
	public function isView() {
		return $this->_status === self::STATUS_VIEW;
	}

	/**
	 * Gets the current status.
	 *
	 * @return int
	 */
	public function getStatus() {
		return $this->_status;
	}

	/**
	 * Magic getter for context attributes.
	 *
	 * @param string $name
	 * @return mixed
	 */
	public function &__get( $name ) {
		return $this->_attributes[ $name ];
	}

	/**
	 * Magic setter for context attributes.
	 *
	 * @param string $name
	 * @param mixed  $value
	 */
	public function __set( $name, $value ) {
		$this->_attributes[ $name ] = $value;
	}

	/**
	 * Magic isset for context attributes.
	 *
	 * @param string $name
	 * @return bool
	 */
	public function __isset( $name ) {
		return isset( $this->_attributes[ $name ] );
	}

	/**
	 * Magic unset for context attributes.
	 *
	 * @param string $name
	 */
	public function __unset( $name ) {
		unset( $this->_attributes[ $name ] );
	}
}
