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

/**
 * Test that PeriodTest is doing as expected
 *
 * @group osb
 * @group osb.helpers
 */
class PeriodTest extends UnitTest_TestCase {
	private $DATE = '2012-07-20'; // Fri (5)
	private $TIME;

	public function __construct() {
		parent::__construct();

		$this->TIME = strtotime($this->DATE);
		$this->w = date('w',$this->TIME);
	}

	// Weekly
	public function test_weekly() {
		# +7 week
		foreach (array(0,2,6) as $x) {
			$p = Period::details(0,NULL,$this->TIME+86400*$x,TRUE,FALSE);
			$this->assertEquals(date('d-M-Y',$this->TIME+86400*(7+$x-1)),$p['end']);
		}

		# +7 week, SUN
		foreach (array(0,2,6) as $x) {
			$p = Period::details(0,0,$this->TIME+86400*$x,TRUE,FALSE);
			$this->assertEquals(date('d-M-Y',$this->TIME+86400*(7-($this->w+$x)%7+$x-1)),$p['end']); // Sat
		}

		# +7 week, TUE
		foreach (array(0,2,6) as $x) {
			$p = Period::details(0,2,$this->TIME+86400*$x,TRUE,FALSE);
			$this->assertEquals(date('d-M-Y',$this->TIME+86400*(7-($this->w+$x)%7+$x-1+2)),$p['end']); // Sat
		}
	}

	public function test_monthly() {
		# +1 month
		$p = Period::details(1,NULL,strtotime('2012-07-20'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-08-19')),$p['end']);

		$p = Period::details(1,NULL,strtotime('2012-07-01'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		$p = Period::details(1,NULL,strtotime('2012-07-31'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-08-30')),$p['end']);

		# +1 month, 1st of the month
		$p = Period::details(1,1,strtotime('2012-07-20'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		$p = Period::details(1,1,strtotime('2012-07-01'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		$p = Period::details(1,1,strtotime('2012-07-31'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		# +1 month, 15th of the month
		$p = Period::details(1,15,strtotime('2012-07-20'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-08-14')),$p['end']);

		$p = Period::details(1,15,strtotime('2012-02-20'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-03-14')),$p['end']);

		$p = Period::details(1,15,strtotime('2012-02-14'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-02-14')),$p['end']);

		$p = Period::details(1,15,strtotime('2012-02-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-03-14')),$p['end']);

		# +1 month, 1st of the month, strict doesnt have any affect
		$p = Period::details(1,1,strtotime('2012-07-20'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		$p = Period::details(1,1,strtotime('2012-07-01'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		$p = Period::details(1,1,strtotime('2012-07-31'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);
	}

	public function test_quarterly() {
		# +3 months
		$p = Period::details(2,NULL,strtotime('2012-02-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-05-14')),$p['end']);

		$p = Period::details(2,NULL,strtotime('2012-11-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-02-14')),$p['end']);

		$p = Period::details(2,NULL,strtotime('2012-08-20'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-11-19')),$p['end']);

		# +3 months, 1st of the month
		$p = Period::details(2,1,strtotime('2012-08-20'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-10-31')),$p['end']);

		$p = Period::details(2,1,strtotime('2012-11-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-01-31')),$p['end']);

		# +3 months, 1st of the month, strict JAN-MAR,APR-JUN,JUL-SEP,OCT-DEC
		$p = Period::details(2,1,strtotime('2012-11-15'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-12-31')),$p['end']);

		$p = Period::details(2,1,strtotime('2013-01-01'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-03-31')),$p['end']);
	}

	public function test_halfyearly() {
		# +6 months
		$p = Period::details(3,NULL,strtotime('2012-02-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-08-14')),$p['end']);

		$p = Period::details(3,NULL,strtotime('2011-09-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-03-14')),$p['end']);

		# +6 months, 1st of the month
		$p = Period::details(3,1,strtotime('2012-02-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-07-31')),$p['end']);

		$p = Period::details(3,1,strtotime('2011-09-15'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-02-29')),$p['end']);

		# +6 months, 1st of the month, strict JAN-JUN,JUL-DEC
		$p = Period::details(3,1,strtotime('2012-02-15'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-06-30')),$p['end']);

		$p = Period::details(3,1,strtotime('2012-01-01'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-06-30')),$p['end']);
	}

	public function test_yearly() {
		# +1 year
		$p = Period::details(4,NULL,strtotime('2012-02-29'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-02-28')),$p['end']);

		# +1 year, 1st of the month
		$p = Period::details(4,1,strtotime('2012-02-29'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-01-31')),$p['end']);

		$p = Period::details(4,1,strtotime('2012-02-01'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-01-31')),$p['end']);

		# +1 year, 1st of the month, strict JAN-DEC
		$p = Period::details(4,1,strtotime('2012-02-29'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-12-31')),$p['end']);

		$p = Period::details(4,1,strtotime('2012-12-31'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2012-12-31')),$p['end']);

		$p = Period::details(4,1,strtotime('2013-02-28'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-12-31')),$p['end']);

		$p = Period::details(4,1,strtotime('2013-12-31'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-12-31')),$p['end']);
	}

	public function test_twoyear() {
		# +2 year
		$p = Period::details(5,NULL,strtotime('2012-02-29'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2014-02-28')),$p['end']);

		# +2 year, 1st of the month
		$p = Period::details(5,1,strtotime('2012-02-29'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2014-01-31')),$p['end']);

		$p = Period::details(5,1,strtotime('2012-02-01'),TRUE,FALSE);
		$this->assertEquals(date('d-M-Y',strtotime('2014-01-31')),$p['end']);

		# +2 year, 1st of the month, strict JAN/YEAR%2
		$p = Period::details(5,1,strtotime('2012-02-29'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-12-31')),$p['end']);

		$p = Period::details(5,1,strtotime('2012-01-31'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-12-31')),$p['end']);

		$p = Period::details(5,1,strtotime('2013-01-31'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2014-12-31')),$p['end']);

		$p = Period::details(5,1,strtotime('2012-12-31'),TRUE,TRUE);
		$this->assertEquals(date('d-M-Y',strtotime('2013-12-31')),$p['end']);
	}
}
?>
