<?php
/**
 * PHPLib
 *
 * A PHP library to wrap php functions in a standard fashion
 *
 * @package		PHPLib
 * @author		Timothy J. Warren
 * @copyright	Copyright (c) 2013
 * @link 		https://github.com/aviat4ion/PHPLib
 * @license		MIT
 */

// --------------------------------------------------------------------------

namespace PHPUtil;

/**
 * Wrapper over array functions with a consistent interface
 */
class Arr {

	/**
	 * Original array to manipulate
	 * @var array
	 */
	protected $original;

	/**
	 * Constructor
	 *
	 * @param array $arr
	 * @return Arr
	 */
	public function __construct($arr)
	{
		$this->original = $arr;
	}

	/**
     * Enable using the object as a function
     *
     * @param string $arr
     * @return $this
     */
    public function __invoke($arr)
    {
	    $this->__construct($arr);
	    return $this;
    }

    /**
     * Return the keys or a subset of the keys of an array
     *
     * @see http://php.net/manual/function.array-keys.php
     * @param mixed $search_value
     * @param bool $strict
     * @return array
     */
    public function keys($search_value=NULL, $strict=FALSE)
    {
	    return array_keys($this->original, $search_value, $strict);
    }

    /**
     * Returns the values from the input array with a numeric index
     *
     * @return array
     */
    public function values()
    {
	    return array_values($this->original);
    }

	/**
     * Returns an array of elements from the input array that match the
     * specified pattern
     *
     * @param mixed $pattern
     * @param mixed $invert
     * @return array
     */
    public function grep($pattern, $invert=FALSE)
    {
        $flags = ($invert == TRUE) ? PREG_GREP_INVERT : 0;

    	return preg_grep($pattern, $this->original, $flags);
    }

    /**
     * Replace elements in the main array with the values in the passed arrays
     * (Takes a variable number of arguments)
     *
     * @see http://php.net/manual/function.array-replace.php
     * @return array
     */
    public function replace()
    {
    	$args = func_get_args();
    	array_unshift($args, $this->original);

    	return call_user_func_array('array_replace', $args);
    }

    /**
     * Combine arrays
     * (Takes a variable number of arguments)
     *
     * @see http://php.net/manual/function.array-merge.php
     * @return array
     */
    public function merge()
    {
    	$args = func_get_args();
    	array_unshift($args, $this->original);

    	return call_user_func_array('array_merge', $args);
    }

    /**
     * Return a new array from the original with duplicate items removed
     *
     * @see http://php.net/manual/function.array-unique.php
     * @param
     * @return array
     */
    public function unique($sort_flags=SORT_STRING)
    {
    	return array_unique($this->original, $sort_flags);
    }

    /**
     * Return an array with elements having the defined values
     *
     * @see http://php.net/manual/function.array-fill.php
     * @param int $start_index
     * @param int $num
     * @param mixed $value
     * @return array
     */
    public function fill($start_index, $num, $value)
    {
    	return array_file($start_index, $num, $value);
    }

    /**
     * Lengthen array to $pad_length with $pad_value
     *
     * @see http://php.net/manual/function.array-pad.php
     * @param int $pad_size
     * @param mixed $pad_value
     * @return array
     */
    public function pad($pad_size, $pad_value)
    {
    	return array_pad($this->original, $pad_size, $pad_value);
    }

    /**
     * Return an array with keys that are the values of the input
     * array, and values as the frequency of those values
     *
     * @see http://php.net/manual/function.array-count-values.php
     * @return array
     */
    public function count_values()
    {
    	return array_count_values($this->original);
    }

    /**
     * Return an array with keys and values reversed from the input array
     *
     * @see http://php.net/manual/function.array-flip.php
     * @return array
     */
    public function flip()
    {
    	return array_flip($this->original);
    }

    /**
     * Returns the sum of all the values in the array
     *
     * @see http://php.net/manual/function.array-sum.php
     * @return number
     */
    public function sum()
    {
    	return array_sum($this->original);
    }

    /**
     * Return a sorted array
     *
     * @see http://php.net/manual/function.asort.php
     * @param int $sort_flags
     * @return array
     */
    public function sort($sort_flags=SORT_REGULAR)
    {
    	asort($this->original, $sort_flags);
    	return $this->original;
    }

    /**
     * Return a reverse-sorted array
     *
     * @see http://php.net/manual/function.asort.php
     * @param int $sort_flags
     * @return array
     */
    public function reverse_sort($sort_flags=SORT_REGULAR)
    {
    	rsort($this->original, $sort_flags);
    	return $this->original;
    }

    /**
     * Reverse the order of the array
     *
     * @see http://php.net/manual/function.array-reverse.php
     * @param bool $preserve_keys
     * @return array
     */
    public function reverse($preserve_keys=FALSE)
    {
    	return array_reverse($this->original, $preserve_keys);
    }

    /**
     * Filter elements of the input array using a callback function
     *
     * @see http://php.net/manual/function.array-filter.php
     * @param callable $callback
     * @return array
     */
    public function filter(callable $callback=NULL)
    {
    	return array_filter($this->original, $callback);
    }
}
// End of arr.php