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

/**
 * This class is used to sort multiple dimension arrays.
 *
 * @package    lnApp
 * @subpackage Sort
 * @category   Helpers
 * @author     Deon George
 * @copyright  (c) 2010 Deon George
 * @license    http://dev.leenooks.net/license.html
 * @uses       Style
 */
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 or empty
		if (! $data)
			return;
	
		static $MASORT_CACHE = array();
	
		if (empty($MASORT_CACHE[$sortby])) {
			$code = "\$c=0;\n";
	
			foreach (explode(',',$sortby) as $key) {
				$code .= "if (is_object(\$a) || is_object(\$b)) {\n";
	
				$code .= "	if (is_array(\$a->$key)) {\n";
				$code .= "		asort(\$a->$key);\n";
				$code .= "		\$aa = array_shift(\$a->$key);\n";
				$code .= "	} else\n";
				$code .= "		\$aa = \$a->$key;\n";
	
				$code .= "	if (is_array(\$b->$key)) {\n";
				$code .= "		asort(\$b->$key);\n";
				$code .= "		\$bb = array_shift(\$b->$key);\n";
				$code .= "	} else\n";
				$code .= "		\$bb = \$b->$key;\n";
	
				$code .= "	if (\$aa != \$bb)";
				if ($rev)
					$code .= "	return (\$aa < \$bb ? 1 : -1);\n";
				else
					$code .= "	return (\$aa > \$bb ? 1 : -1);\n";
	
				$code .= "} else {\n";
	
				$code .= "	\$a = array_change_key_case(\$a);\n";
				$code .= "	\$b = array_change_key_case(\$b);\n";
	
				$key = strtolower($key);
	
				$code .= "	if ((! isset(\$a['$key'])) && isset(\$b['$key'])) return 1;\n";
				$code .= "	if (isset(\$a['$key']) && (! isset(\$b['$key']))) return -1;\n";
	
				$code .= "	if ((isset(\$a['$key'])) && (isset(\$b['$key']))) {\n";
				$code .= "		if (is_array(\$a['$key'])) {\n";
				$code .= "			asort(\$a['$key']);\n";
				$code .= "			\$aa = array_shift(\$a['$key']);\n";
				$code .= "		} else\n";
				$code .= "			\$aa = \$a['$key'];\n";
	
				$code .= "		if (is_array(\$b['$key'])) {\n";
				$code .= "			asort(\$b['$key']);\n";
				$code .= "			\$bb = array_shift(\$b['$key']);\n";
				$code .= "		} else\n";
				$code .= "			\$bb = \$b['$key'];\n";
	
				$code .= "		if (\$aa != \$bb)\n";
				$code .= "			if (is_numeric(\$aa) && is_numeric(\$bb)) {\n";
	
				if ($rev)
					$code .= "				return (\$aa < \$bb ? 1 : -1);\n";
				else
					$code .= "				return (\$aa > \$bb ? 1 : -1);\n";
	
				$code .= "			} else {\n";
	
				if ($rev)
					$code .= "				if ( (\$c = strcasecmp(\$bb,\$aa)) != 0 ) return \$c;\n";
				else
					$code .= "				if ( (\$c = strcasecmp(\$aa,\$bb)) != 0 ) return \$c;\n";
	
				$code .= "		}\n";
				$code .= "	}\n";
				$code .= "}\n";
			}
	
			$code .= 'return $c;';
	
			$MASORT_CACHE[$sortby] = create_function('$a, $b',$code);
		}
	
		uasort($data,$MASORT_CACHE[$sortby]);
	}
}
?>
