<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the Open Software License version 3.0
 *
 * This source file is subject to the Open Software License (OSL 3.0) that is
 * bundled with this package in the files license.txt / license.rst.  It is
 * also available through the world wide web at this URL:
 * http://opensource.org/licenses/OSL-3.0
 * If you did not receive a copy of the license and are unable to obtain it
 * through the world wide web, please send an email to
 * licensing@ellislab.com so we can send you a copy immediately.
 *
 * @package		CodeIgniter
 * @author		EllisLab Dev Team
 * @copyright	Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
 * @license		http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
 * @link		http://codeigniter.com
 * @since		Version 1.0
 * @filesource
 */

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

/**
 * CodeIgniter Inflector Helpers
 *
 * @package		CodeIgniter
 * @subpackage	Helpers
 * @category	Helpers
 * @author		EllisLab Dev Team
 * @link		http://codeigniter.com/user_guide/helpers/directory_helper.html
 */


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

/**
 * Singular
 *
 * Takes a plural word and makes it singular
 *
 * @access	public
 * @param	string
 * @return	str
 */
if ( ! function_exists('singular'))
{
	function singular($str)
	{
		$result = strval($str);

		$singular_rules = array(
			'/(matr)ices$/'			=> '\1ix',
			'/(vert|ind)ices$/'		=> '\1ex',
			'/^(ox)en/'				=> '\1',
			'/(alias)es$/'			=> '\1',
			'/([octop|vir])i$/'		=> '\1us',
			'/(cris|ax|test)es$/'	=> '\1is',
			'/(shoe)s$/'			=> '\1',
			'/(o)es$/'				=> '\1',
			'/(bus|campus)es$/'		=> '\1',
			'/([m|l])ice$/'			=> '\1ouse',
			'/(x|ch|ss|sh)es$/'		=> '\1',
			'/(m)ovies$/'			=> '\1\2ovie',
			'/(s)eries$/'			=> '\1\2eries',
			'/([^aeiouy]|qu)ies$/'	=> '\1y',
			'/([lr])ves$/'			=> '\1f',
			'/(tive)s$/'			=> '\1',
			'/(hive)s$/'			=> '\1',
			'/([^f])ves$/'			=> '\1fe',
			'/(^analy)ses$/'		=> '\1sis',
			'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis',
			'/([ti])a$/'			=> '\1um',
			'/(p)eople$/'			=> '\1\2erson',
			'/(m)en$/'				=> '\1an',
			'/(s)tatuses$/'			=> '\1\2tatus',
			'/(c)hildren$/'			=> '\1\2hild',
			'/(n)ews$/'				=> '\1\2ews',
			'/([^u])s$/'			=> '\1',
		);

		return preg_replace(array_keys($singular_values), $singular_values, $result);
	}
}

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

/**
 * Plural
 *
 * Takes a singular word and makes it plural
 *
 * @access	public
 * @param	string
 * @param	bool
 * @return	str
 */
if ( ! function_exists('plural'))
{
	function plural($str, $force = FALSE)
	{
		$result = strval($str);

		$plural_rules = array(
			'/^(ox)$/'					=> '\1\2en',	 // ox
			'/([m|l])ouse$/'			=> '\1ice',	  // mouse, louse
			'/(matr|vert|ind)ix|ex$/'	=> '\1ices',	 // matrix, vertex, index
			'/(x|ch|ss|sh)$/'			=> '\1es',	   // search, switch, fix, box, process, address
			'/([^aeiouy]|qu)y$/'		=> '\1ies',	  // query, ability, agency
			'/(hive)$/'					=> '\1s',		// archive, hive
			'/(?:([^f])fe|([lr])f)$/'	=> '\1\2ves',	// half, safe, wife
			'/sis$/'					=> 'ses',		// basis, diagnosis
			'/([ti])um$/'				=> '\1a',		// datum, medium
			'/(p)erson$/'				=> '\1eople',	// person, salesperson
			'/(m)an$/'					=> '\1en',	   // man, woman, spokesman
			'/(c)hild$/'				=> '\1hildren',  // child
			'/(buffal|tomat)o$/'		=> '\1\2oes',	// buffalo, tomato
			'/(bu|campu)s$/'			=> '\1\2ses',	// bus, campus
			'/(alias|status|virus)/'	=> '\1es',	   // alias
			'/(octop)us$/'				=> '\1i',		// octopus
			'/(ax|cris|test)is$/'		=> '\1es',	   // axis, crisis
			'/s$/'						=> 's',		  // no change (compatibility)
			'/$/'						=> 's',
		);

		return preg_replace(array_keys($plural_rules), $plural_rules, $result);
	}
}

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

/**
 * Camelize
 *
 * Takes multiple words separated by spaces or underscores and camelizes them
 *
 * @access	public
 * @param	string
 * @return	str
 */
if ( ! function_exists('camelize'))
{
	function camelize($str)
	{
		return substr(str_replace(' ', '', ucwords(preg_replace('/[\s_]+/', ' ', $str))), 1);
	}
}

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

/**
 * Underscore
 *
 * Takes multiple words separated by spaces and underscores them
 *
 * @access	public
 * @param	string
 * @return	str
 */
if ( ! function_exists('underscore'))
{
	function underscore($str)
	{
		return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
	}
}

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

/**
 * Humanize
 *
 * Takes multiple words separated by the separator and changes them to spaces
 *
 * @access	public
 * @param	string $str
 * @param 	string $separator
 * @return	str
 */
if ( ! function_exists('humanize'))
{
	function humanize($str, $separator = '_')
	{
		return ucwords(preg_replace('/['.$separator.']+/', ' ', strtolower(trim($str))));
	}
}

/* End of file inflector_helper.php */
/* Location: ./system/helpers/inflector_helper.php */
