<?php

/**

 * PHPExcel

 *

 * Copyright (c) 2006 - 2014 PHPExcel

 *

 * This library is free software; you can redistribute it and/or

 * modify it under the terms of the GNU Lesser General Public

 * License as published by the Free Software Foundation; either

 * version 2.1 of the License, or (at your option) any later version.

 *

 * This library is distributed in the hope that it will be useful,

 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU

 * Lesser General Public License for more details.

 *

 * You should have received a copy of the GNU Lesser General Public

 * License along with this library; if not, write to the Free Software

 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

 *

 * @category	PHPExcel

 * @package		PHPExcel_Worksheet

 * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)

 * @license		http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt	LGPL

 * @version		1.8.0, 2014-03-02

 */





/**

 * PHPExcel_Worksheet_AutoFilter_Column_Rule

 *

 * @category	PHPExcel

 * @package		PHPExcel_Worksheet

 * @copyright	Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)

 */

class PHPExcel_Worksheet_AutoFilter_Column_Rule

{

	const AUTOFILTER_RULETYPE_FILTER		= 'filter';

	const AUTOFILTER_RULETYPE_DATEGROUP		= 'dateGroupItem';

	const AUTOFILTER_RULETYPE_CUSTOMFILTER	= 'customFilter';

	const AUTOFILTER_RULETYPE_DYNAMICFILTER	= 'dynamicFilter';

	const AUTOFILTER_RULETYPE_TOPTENFILTER	= 'top10Filter';



	private static $_ruleTypes = array(

		//	Currently we're not handling

		//		colorFilter

		//		extLst

		//		iconFilter

		self::AUTOFILTER_RULETYPE_FILTER,

		self::AUTOFILTER_RULETYPE_DATEGROUP,

		self::AUTOFILTER_RULETYPE_CUSTOMFILTER,

		self::AUTOFILTER_RULETYPE_DYNAMICFILTER,

		self::AUTOFILTER_RULETYPE_TOPTENFILTER,

	);



	const AUTOFILTER_RULETYPE_DATEGROUP_YEAR	= 'year';

	const AUTOFILTER_RULETYPE_DATEGROUP_MONTH	= 'month';

	const AUTOFILTER_RULETYPE_DATEGROUP_DAY		= 'day';

	const AUTOFILTER_RULETYPE_DATEGROUP_HOUR	= 'hour';

	const AUTOFILTER_RULETYPE_DATEGROUP_MINUTE	= 'minute';

	const AUTOFILTER_RULETYPE_DATEGROUP_SECOND	= 'second';



	private static $_dateTimeGroups = array(

		self::AUTOFILTER_RULETYPE_DATEGROUP_YEAR,

		self::AUTOFILTER_RULETYPE_DATEGROUP_MONTH,

		self::AUTOFILTER_RULETYPE_DATEGROUP_DAY,

		self::AUTOFILTER_RULETYPE_DATEGROUP_HOUR,

		self::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE,

		self::AUTOFILTER_RULETYPE_DATEGROUP_SECOND,

	);



	const AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY		= 'yesterday';

	const AUTOFILTER_RULETYPE_DYNAMIC_TODAY			= 'today';

	const AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW		= 'tomorrow';

	const AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE	= 'yearToDate';

	const AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR		= 'thisYear';

	const AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER	= 'thisQuarter';

	const AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH		= 'thisMonth';

	const AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK		= 'thisWeek';

	const AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR		= 'lastYear';

	const AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER	= 'lastQuarter';

	const AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH		= 'lastMonth';

	const AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK		= 'lastWeek';

	const AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR		= 'nextYear';

	const AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER	= 'nextQuarter';

	const AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH		= 'nextMonth';

	const AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK		= 'nextWeek';

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1		= 'M1';

	const AUTOFILTER_RULETYPE_DYNAMIC_JANUARY		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2		= 'M2';

	const AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3		= 'M3';

	const AUTOFILTER_RULETYPE_DYNAMIC_MARCH			= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4		= 'M4';

	const AUTOFILTER_RULETYPE_DYNAMIC_APRIL			= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5		= 'M5';

	const AUTOFILTER_RULETYPE_DYNAMIC_MAY			= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6		= 'M6';

	const AUTOFILTER_RULETYPE_DYNAMIC_JUNE			= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7		= 'M7';

	const AUTOFILTER_RULETYPE_DYNAMIC_JULY			= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8		= 'M8';

	const AUTOFILTER_RULETYPE_DYNAMIC_AUGUST		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9		= 'M9';

	const AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10		= 'M10';

	const AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11		= 'M11';

	const AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11;

	const AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12		= 'M12';

	const AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER		= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12;

	const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1		= 'Q1';

	const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2		= 'Q2';

	const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3		= 'Q3';

	const AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4		= 'Q4';

	const AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE	= 'aboveAverage';

	const AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE	= 'belowAverage';



	private static $_dynamicTypes = array(

		self::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY,

		self::AUTOFILTER_RULETYPE_DYNAMIC_TODAY,

		self::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW,

		self::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE,

		self::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR,

		self::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER,

		self::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH,

		self::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK,

		self::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR,

		self::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER,

		self::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH,

		self::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK,

		self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR,

		self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER,

		self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH,

		self::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11,

		self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12,

		self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1,

		self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2,

		self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3,

		self::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4,

		self::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE,

		self::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE,

	);



	/*

	 *	The only valid filter rule operators for filter and customFilter types are:

	 *		<xsd:enumeration value="equal"/>

	 *		<xsd:enumeration value="lessThan"/>

	 *		<xsd:enumeration value="lessThanOrEqual"/>

	 *		<xsd:enumeration value="notEqual"/>

	 *		<xsd:enumeration value="greaterThanOrEqual"/>

	 *		<xsd:enumeration value="greaterThan"/>

	 */

	const AUTOFILTER_COLUMN_RULE_EQUAL				= 'equal';

	const AUTOFILTER_COLUMN_RULE_NOTEQUAL			= 'notEqual';

	const AUTOFILTER_COLUMN_RULE_GREATERTHAN		= 'greaterThan';

	const AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL	= 'greaterThanOrEqual';

	const AUTOFILTER_COLUMN_RULE_LESSTHAN			= 'lessThan';

	const AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL	= 'lessThanOrEqual';



	private static $_operators = array(

		self::AUTOFILTER_COLUMN_RULE_EQUAL,

		self::AUTOFILTER_COLUMN_RULE_NOTEQUAL,

		self::AUTOFILTER_COLUMN_RULE_GREATERTHAN,

		self::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,

		self::AUTOFILTER_COLUMN_RULE_LESSTHAN,

		self::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,

	);



	const AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE	= 'byValue';

	const AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT		= 'byPercent';



	private static $_topTenValue = array(

		self::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,

		self::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,

	);



	const AUTOFILTER_COLUMN_RULE_TOPTEN_TOP			= 'top';

	const AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM		= 'bottom';



	private static $_topTenType = array(

		self::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP,

		self::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM,

	);





	/* Rule Operators (Numeric, Boolean etc) */

//	const AUTOFILTER_COLUMN_RULE_BETWEEN			= 'between';		//	greaterThanOrEqual 1 && lessThanOrEqual 2

	/* Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values */

//	const AUTOFILTER_COLUMN_RULE_TOPTEN				= 'topTen';			//	greaterThan calculated value

//	const AUTOFILTER_COLUMN_RULE_TOPTENPERCENT		= 'topTenPercent';	//	greaterThan calculated value

//	const AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE		= 'aboveAverage';	//	Value is calculated as the average

//	const AUTOFILTER_COLUMN_RULE_BELOWAVERAGE		= 'belowAverage';	//	Value is calculated as the average

	/* Rule Operators (String) which are set as wild-carded values */

//	const AUTOFILTER_COLUMN_RULE_BEGINSWITH			= 'beginsWith';			// A*

//	const AUTOFILTER_COLUMN_RULE_ENDSWITH			= 'endsWith';			// *Z

//	const AUTOFILTER_COLUMN_RULE_CONTAINS			= 'contains';			// *B*

//	const AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN		= 'notEqual';			//	notEqual *B*

	/* Rule Operators (Date Special) which are translated to standard numeric operators with calculated values */

//	const AUTOFILTER_COLUMN_RULE_BEFORE				= 'lessThan';

//	const AUTOFILTER_COLUMN_RULE_AFTER				= 'greaterThan';

//	const AUTOFILTER_COLUMN_RULE_YESTERDAY			= 'yesterday';

//	const AUTOFILTER_COLUMN_RULE_TODAY				= 'today';

//	const AUTOFILTER_COLUMN_RULE_TOMORROW			= 'tomorrow';

//	const AUTOFILTER_COLUMN_RULE_LASTWEEK			= 'lastWeek';

//	const AUTOFILTER_COLUMN_RULE_THISWEEK			= 'thisWeek';

//	const AUTOFILTER_COLUMN_RULE_NEXTWEEK			= 'nextWeek';

//	const AUTOFILTER_COLUMN_RULE_LASTMONTH			= 'lastMonth';

//	const AUTOFILTER_COLUMN_RULE_THISMONTH			= 'thisMonth';

//	const AUTOFILTER_COLUMN_RULE_NEXTMONTH			= 'nextMonth';

//	const AUTOFILTER_COLUMN_RULE_LASTQUARTER		= 'lastQuarter';

//	const AUTOFILTER_COLUMN_RULE_THISQUARTER		= 'thisQuarter';

//	const AUTOFILTER_COLUMN_RULE_NEXTQUARTER		= 'nextQuarter';

//	const AUTOFILTER_COLUMN_RULE_LASTYEAR			= 'lastYear';

//	const AUTOFILTER_COLUMN_RULE_THISYEAR			= 'thisYear';

//	const AUTOFILTER_COLUMN_RULE_NEXTYEAR			= 'nextYear';

//	const AUTOFILTER_COLUMN_RULE_YEARTODATE			= 'yearToDate';			//	<dynamicFilter val="40909" type="yearToDate" maxVal="41113"/>

//	const AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH	= 'allDatesInMonth';	//	<dynamicFilter type="M2"/> for Month/February

//	const AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER	= 'allDatesInQuarter';	//	<dynamicFilter type="Q2"/> for Quarter 2



	/**

	 * Autofilter Column

	 *

	 * @var PHPExcel_Worksheet_AutoFilter_Column

	 */

	private $_parent = NULL;





	/**

	 * Autofilter Rule Type

	 *

	 * @var string

	 */

	private $_ruleType = self::AUTOFILTER_RULETYPE_FILTER;





	/**

	 * Autofilter Rule Value

	 *

	 * @var string

	 */

	private $_value = '';



	/**

	 * Autofilter Rule Operator

	 *

	 * @var string

	 */

	private $_operator = '';



	/**

	 * DateTimeGrouping Group Value

	 *

	 * @var string

	 */

	private $_grouping = '';





	/**

	 * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule

	 *

	 * @param PHPExcel_Worksheet_AutoFilter_Column $pParent

	 */

	public function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL)

	{

		$this->_parent = $pParent;

	}



	/**

	 * Get AutoFilter Rule Type

	 *

	 * @return string

	 */

	public function getRuleType() {

		return $this->_ruleType;

	}



	/**

	 *	Set AutoFilter Rule Type

	 *

	 *	@param	string		$pRuleType

	 *	@throws	PHPExcel_Exception

	 *	@return PHPExcel_Worksheet_AutoFilter_Column

	 */

	public function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) {

		if (!in_array($pRuleType,self::$_ruleTypes)) {

			throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.');

		}



		$this->_ruleType = $pRuleType;



		return $this;

	}



	/**

	 * Get AutoFilter Rule Value

	 *

	 * @return string

	 */

	public function getValue() {

		return $this->_value;

	}



	/**

	 *	Set AutoFilter Rule Value

	 *

	 *	@param	string|string[]		$pValue

	 *	@throws	PHPExcel_Exception

	 *	@return PHPExcel_Worksheet_AutoFilter_Column_Rule

	 */

	public function setValue($pValue = '') {

		if (is_array($pValue)) {

			$grouping = -1;

			foreach($pValue as $key => $value) {

				//	Validate array entries

				if (!in_array($key,self::$_dateTimeGroups)) {

					//	Remove any invalid entries from the value array

					unset($pValue[$key]);

				} else {

					//	Work out what the dateTime grouping will be

					$grouping = max($grouping,array_search($key,self::$_dateTimeGroups));

				}

			}

			if (count($pValue) == 0) {

				throw new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.');

			}

			//	Set the dateTime grouping that we've anticipated

			$this->setGrouping(self::$_dateTimeGroups[$grouping]);

		}

		$this->_value = $pValue;



		return $this;

	}



	/**

	 * Get AutoFilter Rule Operator

	 *

	 * @return string

	 */

	public function getOperator() {

		return $this->_operator;

	}



	/**

	 *	Set AutoFilter Rule Operator

	 *

	 *	@param	string		$pOperator

	 *	@throws	PHPExcel_Exception

	 *	@return PHPExcel_Worksheet_AutoFilter_Column_Rule

	 */

	public function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) {

		if (empty($pOperator))

			$pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL;

		if ((!in_array($pOperator,self::$_operators)) &&

			(!in_array($pOperator,self::$_topTenValue))) {

			throw new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.');

		}

		$this->_operator = $pOperator;



		return $this;

	}



	/**

	 * Get AutoFilter Rule Grouping

	 *

	 * @return string

	 */

	public function getGrouping() {

		return $this->_grouping;

	}



	/**

	 *	Set AutoFilter Rule Grouping

	 *

	 *	@param	string		$pGrouping

	 *	@throws	PHPExcel_Exception

	 *	@return PHPExcel_Worksheet_AutoFilter_Column_Rule

	 */

	public function setGrouping($pGrouping = NULL) {

		if (($pGrouping !== NULL) &&

			(!in_array($pGrouping,self::$_dateTimeGroups)) &&

			(!in_array($pGrouping,self::$_dynamicTypes)) &&

			(!in_array($pGrouping,self::$_topTenType))) {

			throw new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.');

		}



		$this->_grouping = $pGrouping;



		return $this;

	}



	/**

	 *	Set AutoFilter Rule

	 *

	 *	@param	string				$pOperator

	 *	@param	string|string[]		$pValue

	 *	@param	string				$pGrouping

	 *	@throws	PHPExcel_Exception

	 *	@return PHPExcel_Worksheet_AutoFilter_Column_Rule

	 */

	public function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) {

		$this->setOperator($pOperator);

		$this->setValue($pValue);

		//	Only set grouping if it's been passed in as a user-supplied argument,

		//		otherwise we're calculating it when we setValue() and don't want to overwrite that

		//		If the user supplies an argumnet for grouping, then on their own head be it

		if ($pGrouping !== NULL)

			$this->setGrouping($pGrouping);



		return $this;

	}



	/**

	 * Get this Rule's AutoFilter Column Parent

	 *

	 * @return PHPExcel_Worksheet_AutoFilter_Column

	 */

	public function getParent() {

		return $this->_parent;

	}



	/**

	 * Set this Rule's AutoFilter Column Parent

	 *

	 * @param PHPExcel_Worksheet_AutoFilter_Column

	 * @return PHPExcel_Worksheet_AutoFilter_Column_Rule

	 */

	public function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) {

		$this->_parent = $pParent;



		return $this;

	}



	/**

	 * Implement PHP __clone to create a deep clone, not just a shallow copy.

	 */

	public function __clone() {

		$vars = get_object_vars($this);

		foreach ($vars as $key => $value) {

			if (is_object($value)) {

				if ($key == '_parent') {

					//	Detach from autofilter column parent

					$this->$key = NULL;

				} else {

					$this->$key = clone $value;

				}

			} else {

				$this->$key = $value;

			}

		}

	}



}

