<?php

class DateController
{
	private static $weekday = array("", "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So");

	private static $yesNo = array(false => "N", true => "J");

	private static $stringVars = array(
		"jahr" => "Year",
		"quartal" => "Quarter",
		"monat" => "Month",
		"tag" => "Day",
		"datum" => "Today",
		"zeit" => "TimeHm",
		"wochedesmonats" => "WeekOfMonth",
		"wochentag" => "Weekday",
		"tagdesjahres" => "DayOfYear",
		"ymd" => "FullDate",
		"vortag" => "FullDateYesterday"
	);

	private static $boolVars = array(
		"mo-fr" => "MoFr",
		"mo-sa" => "MoSa",
		"mo-so" => "MoSo",
		"di-sa" => "DiSa",
		"di-so" => "DiSo",
		"ersterwerktag" => "IsFirstWeekdayOfMonth",
		"ungeradewoche" => "OddWeek"
	);

	public static function Run ($argv)
	{
		$date = (count($argv) > 1) ? $argv[1] : "";

		$dateCtrl = new DateController($date);
		echo $dateCtrl->GetVariables();
	}


	private $timestamp;

	public function __construct ($date = "")
	{
		$this->timestamp = ($date == "") ? time() : strtotime($date);
	}

	public function GetVariables ()
	{
		$result = "Jahr=" . $this->Year() . "\r\n";
		$result .= "Quartal=" . $this->Quarter() . "\r\n";
		$result .= "Monat=" . $this->Month() . "\r\n";
		$result .= "Tag=" . $this->Day() . "\r\n";
		$result .= "Zeit=" . $this->TimeHm() . "\r\n";

		$result .= "WocheDesMonats=" . $this->WeekOfMonth() . "\r\n";
		$result .= "Wochentag=" . $this->Weekday() . "\r\n";

		$result .= "Mo-Fr=" . DateController::$yesNo[$this->MoFr()] . "\r\n";
		$result .= "Mo-Sa=" . DateController::$yesNo[$this->MoSa()] . "\r\n";
		$result .= "Mo-So=" . DateController::$yesNo[$this->MoSo()] . "\r\n";
		$result .= "Di-Sa=" . DateController::$yesNo[$this->DiSa()] . "\r\n";
		$result .= "Di-So=" . DateController::$yesNo[$this->DiSo()] . "\r\n";
		$result .= "ErsterWerktag=" . DateController::$yesNo[$this->IsFirstWeekdayOfMonth()] . "\r\n";
		$result .= "TagDesJahres=" . $this->DayOfYear() . "\r\n";
		$result .= "UngeradeWoche=" . DateController::$yesNo[$this->OddWeek()] . "\r\n";
		
		$result .= "datum=" . $this->Today() . "\r\n";
		$result .= "ymd=" . $this->FullDate() . "\r\n";
		$result .= "Vortag=" . $this->FullDateYesterday() . "\r\n";

		return $result;
	}

	public function GetValue ($key)
	{
		$key = trim(strtolower($key));

		if (isset(DateController::$stringVars[$key])) {
			return call_user_func(array($this, DateController::$stringVars[$key]));
		}

		if (isset(DateController::$boolVars[$key])) {
			return DateController::$yesNo[call_user_func(array($this, DateController::$boolVars[$key]))];
		}
		return "?";
	}

	public function Today ()
	{
		return date("d.m.Y", $this->timestamp);
	}
	
	public function FullDate ()
	{
		return date("Y-m-d", $this->timestamp);
	}

	public function FullDateYesterday ()
	{
		$yesterday = strtotime("-1 day", $this->timestamp);
		return date("Y-m-d", $yesterday);
	}
	
	public function Year ()
	{
		return date("Y", $this->timestamp);
	}

	public function Quarter ()
	{
		$month = $this->Month();
		if ($month <= "03") return "1";
		if ($month <= "06") return "2";
		if ($month <= "09") return "3";
		return "4";
	}

	public function Month ()
	{
		return date("m", $this->timestamp);
	}

	public function Day ()
	{
		return date("d", $this->timestamp);
	}
	
	public function TimeHm ()
	{
		return date("H:i", $this->timestamp);
	}

	public function Week ()
	{
		return date("W", $this->timestamp);
	}

	public function WeekOfMonth ()
	{
		$weekdayOfFirst = $this->WeekdayOfFirst();
		$weekOffset = ($weekdayOfFirst > 1 && $weekdayOfFirst < 6) ? 1 : 0;
		$offset = 7 - date("N", $this->timestamp);
		return floor((date("j", $this->timestamp) + $offset) / 7) + $weekOffset;
	}

	private function WeekdayOfFirst ()
	{
		return date("N", strtotime($this->Year()."-".$this->Month()."-01"));
	}

	public function Weekday ()
	{
		return DateController::$weekday[date("N", $this->timestamp)];
	}

	public function MoFr ()
	{
		return date("N", $this->timestamp) < 6;
	}

	public function MoSa ()
	{
		return date("N", $this->timestamp) != 7;
	}

	public function MoSo ()
	{
		return true;
	}
	
	public function DiSa ()
	{
		return date("N", $this->timestamp) != 1 && date("N", $this->timestamp) != 7;
	}
	
	public function DiSo ()
	{
		return date("N", $this->timestamp) != 1;
	}

	public function FirstWeekdayOfMonth ()
	{
		$weekdayOfFirst = $this->WeekdayOfFirst();
		if ($weekdayOfFirst == 6) return "03";
		if ($weekdayOfFirst == 7) return "02";
		return "01";
	}

	public function IsFirstWeekdayOfMonth ()
	{
		return $this->FirstWeekdayOfMonth() == $this->Day();
	}

	public function DayOfYear ()
	{
		return date("z", $this->timestamp) + 1;
	}

	public function OddWeek ()
	{
		return ($this->Week() % 2) == 1;
	}
}