<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class is used to sort multiple dimension arrays.
 *
 * @package    lnApp
 * @category   lnApp/Helpers
 * @author     Deon George
 * @copyright  (c) 2009-2013 Deon George
 * @license    http://dev.leenooks.net/license.html
 * @uses       Style
 */
abstract class lnApp_Sort {
	/**
	 * Sort a multi dimensional array.
	 *
	 * @param array Multi demension array passed by reference
	 * @param string Comma delimited string of sort keys.
	 * @param boolean Whether to reverse sort.
	 * @return array Sorted multi demension array.
	 */
	public static function MAsort(&$data,$sortby,$rev=0) {
		// if the array to sort is null
		if (! $data)
			return;
		// if the array to sort is null or empty, or our sortby is bad
	#	if (! preg_match('/^([a-zA-Z0-9_]+(\([a-zA-Z0-9_,]*\)(->[a-zA-Z0-9])?)?,?)+$/',$sortby) || ! $data)
	#		return;

		$code = '$c=0;';

		foreach (explode(',',$sortby) as $key) {
			$code .= 'if (is_object($a) || is_object($b)) {';
			foreach (array('a','b') as $x) {
				$code .= 'if (is_array($'.$x.'->'.$key.')) {';
				$code .= 'asort($'.$x.'->'.$key.');';
				$code .= '$x'.$x.' = array_shift($'.$x.'->'.$key.');';
				$code .= '} else';
				$code .= '$x'.$x.' = $'.$x.'->'.$key.';';
			}

			$code .= 'if ($xa != $xb)';
			if ($rev)
				$code .= 'return ($xa < $xb ? 1 : -1);';
			else
				$code .= 'return ($xa > $xb ? 1 : -1);';

			$code .= '} else {';

			foreach (array('a','b') as $x)
				$code .= '$'.$x.' = array_change_key_case($'.$x.');';

			$key = strtolower($key);

			$code .= 'if ((! isset($a[\''.$key.'\'])) && isset($b[\''.$key.'\'])) return 1;';
			$code .= 'if (isset($a[\''.$key.'\']) && (! isset($b[\''.$key.'\']))) return -1;';

			$code .= 'if ((isset($a[\''.$key.'\'])) && (isset($b[\''.$key.'\']))) {';
			foreach (array('a','b') as $x) {
				$code .= 'if (is_array($'.$x.'[\''.$key.'\'])) {';
				$code .= 'asort($'.$x.'[\''.$key.'\']);';
				$code .= '$x'.$x.' = array_shift($'.$x.'[\''.$key.'\']);';
				$code .= '} else';
				$code .= '$x'.$x.' = $'.$x.'[\''.$key.'\'];';
			}

			$code .= 'if ($xa != $xb)';
			$code .= 'if (is_numeric($xa) && is_numeric($xb)) {';

			if ($rev)
				$code .= 'return ($xa < $xb ? 1 : -1);';
			else
				$code .= 'return ($xa > $xb ? 1 : -1);';

			$code .= '} else {';

			if ($rev)
				$code .= 'if (($c = strcasecmp($xb,$xa)) != 0) return $c;';
			else
				$code .= 'if (($c = strcasecmp($xa,$xb)) != 0) return $c;';

			$code .= '}}}';
		}

		$code .= 'return $c;';

		$result = create_function('$a, $b',$code);

		uasort($data,$result);
	}
}
?>
