<?php

/**
 * Credits actions accessor class.
 *
 * @package Brivium_Credits_Actions
 */
class Brivium_Credits_Actions
{
	/**
	 * Collection of actions.
	 *
	 * @var array
	 */
	protected $_actions = array();

	/**
	 * Constructor. Sets up the accessor using the provided actions.
	 *
	 * @param array $actions Collection of actions. Keys represent action names.
	 */
	public function __construct(array $actions)
	{
		$this->setActions($actions);
	}

	/**
	 * Gets an action. If the action exists and is an array, then...
	 * 	* if no sub-action is specified but an $actionName key exists in the action, return the value for that key
	 *  * if no sub-action is specified and no $actionName key exists, return the whole action array
	 *  * if the sub-action === false, the entire action is returned, regardless of what keys exist
	 *  * if a sub-action is specified and the key exists, return the value for that key
	 *  * if a sub-action is specified and the key does not exist, return null
	 * If the action is not an array, then the value of the action is returned (provided no sub-action is specified).
	 * Otherwise, null is returned.
	 *
	 * @param string $actionName Name of the action
	 * @param null|false|string $subAction Sub-action. See above for usage.
	 *
	 * @return null|mixed Null if the action doesn't exist (see above) or the action's value.
	 */
	public function get($actionName)
	{
		if (!isset($this->_actions[$actionName]))
		{
			return null;
		}

		$action = $this->_actions[$actionName];

		if (is_array($action))
		{
			return $action;
		}
		else
		{
			return null;
		}
	}
	/**
	 * Gets all actions in their raw form.
	 *
	 * @return array
	 */
	public function getActions()
	{
		return $this->_actions;
	}

	/**
	 * Sets the collection of actions manually.
	 *
	 * @param array $actions
	 */
	public function setActions(array $actions)
	{
		$this->_actions = $actions;
	}

	/**
	 * Magic getter for first-order actions. This method cannot be used
	 * for getting a sub-action! You must use {@link get()} for that.
	 *
	 * This is equivalent to calling get() with no sub-action, which means
	 * the "main" sub-action will be returned (if applicable).
	 *
	 * @param string $action
	 *
	 * @return null|mixed
	 */
	public function __get($action)
	{
		return $this->get($action);
	}

	/**
	 * Returns true if the named action exists. Do not use this approach
	 * for sub-actions!
	 *
	 * This is equivalent to calling get() with no sub-action, which means
	 * the "main" sub-action will be returned (if applicable).
	 *
	 * @param string $action
	 *
	 * @return boolean
	 */
	public function __isset($action)
	{
		return ($this->get($action) !== null);
	}

	/**
	 * Sets an action or a particular sub-action (first level array key).
	 *
	 * @param string $action
	 * @param mixed $subAction If $value is null, then this is treated as the value; otherwise, a specific array key to change
	 * @param mixed|null $value If null, ignored
	 */
	public function set($action, $subAction, $value = null)
	{
		if ($value === null)
		{
			$value = $subAction;
			$subAction = false;
		}

		if ($subAction === false)
		{
			$this->_actions[$action] = $value;
		}
		else if (isset($this->_actions[$action]) && is_array($this->_actions[$action]))
		{
			$this->_actions[$action][$subAction] = $value;
		}
		else
		{
			throw new XenForo_Exception('Tried to write sub-action to invalid/non-array action.');
		}
	}

	/**
	 * Magic set method. Only sets whole actions.
	 *
	 * @param string $name
	 * @param mixed $value
	 */
	public function __set($name, $value)
	{
		$this->set($name, $value);
	}
}