Calendar.php

<?php

namespace ROF\Calendar;

class Calendar {
  
  private static $activeCalendar = NULL;
  private static $index = 0;
  private static $timeZone = NULL;
    
  private $date = NULL;
  private $activeTimestamp = NULL;
  private $activeDay = NULL;
  private $calendarDays = NULL;
  private $selectedDayIndex = NULL;
  
  
  private function __construct($data = array()){
    if (isset($_GET['month'])&&isset($_GET['year'])){
      $date = \DateTime::createFromFormat('n-Y',$_GET['month'].'-'.$_GET['year']);
      $date->setTimeZone(self::getTimeZone());
      $timestamp = $date->getTimestamp();
    } else if (in_array('timestamp',$data)&&$data['timestamp']!=NULL){
      $timestamp = $data['timestamp'];
    } else if (in_array('timestamp',$_GET)&&$_GET['timestamp']!=NULL){
      $timestamp = $_GET['timestamp'];
    } else {
      $timestamp = time();
    }
    
    $this->date = \DateTime::createFromFormat('U',$timestamp);
    $this->date->setTimeZone(self::getTimeZone());
    $dayOfMonth = $this->date->format('j');
    $dayOfMonth--;
    $theFirst = \DateTime::createFromFormat('Y-m-j',$this->date->format('Y-m-').'1');
    $theFirst->setTimeZone(self::getTimeZone());
    $dayOfWeek = $theFirst->format('w');
    $calendarStart = \DateTime::createFromFormat('U',$theFirst->getTimestamp()-60*60*24*($dayOfWeek));
    $calendarStart->setTimeZone(self::getTimeZone());
    $calendarStartDayOfMonth = $calendarStart->format('j');
    
    
    
    $daysInMonth = \DateTime::createFromFormat('U',$timestamp, new \DateTimeZone("America/Chicago"))->format('t');
    $monthEnd = \DateTime::createFromFormat('U',$timestamp+ 60*60*24*($daysInMonth-1));
    $monthEnd->setTimeZone(self::getTimeZone());
    $monthEndWeekday = $monthEnd->format('w');
    $monthEnd->setTime(23,59,59,999);
    $lastDayOfCalendarTimestamp = $monthEnd->getTimestamp()+60*60*24*(6-$monthEndWeekday);
    $nextTimestamp = $calendarStart->getTimestamp();
    $this->calendarDays = array();
    $index = 0;
    
    
    
    while($nextTimestamp<=$lastDayOfCalendarTimestamp){
      $this->calendarDays[$index] = new Day($nextTimestamp,array());
      $nextTimestamp += 60*60*24;
      $index++;
    }
    $this->selectedDayIndex = 0;
  }
  public function getYear(){
    return $this->date->format("Y");
  }
  public function getPreviousMonth(){
    $newDate = \DateTime::createFromFormat('U',$this->date->getTimestamp());
    $newDate->setTimeZone(self::getTimeZone());
    $newDate->modify('-1 month');
    return $newDate;
  }
  public function getNextMonth(){
    $newDate = \DateTime::createFromFormat('U',$this->date->getTimestamp());
    $newDate->setTimeZone(self::getTimeZone());
    $newDate->modify('+1 month');
    return $newDate;
  }
  public function getNextYear(){
    $newDate = \DateTime::createFromFormat('U',$this->date->getTimestamp());
    $newDate->setTimeZone(self::getTimeZone());
    $newDate->modify('+1 year');
    return $newDate;
  }
  public function getPreviousYear(){
    $newDate = \DateTime::createFromFormat('U',$this->date->getTimestamp());
    $newDate->setTimeZone(self::getTimeZone());
    $newDate->modify('-1 year');
    return $newDate;
  }
  public function getPreviousMonthName(){
    return $this->getPreviousMonth()->format("F");
  }
  public function getNextMonthName(){
    return $this->getNextMonth()->format("F");
  }
  public function getPreviousMonthUrl(){
    $newDate = $this->getPreviousMonth();
    $month = $newDate->format('n');
    $year = $newDate->format('Y');
    return $_SERVER['REDIRECT_URL'].'?month='.$month.'&year='.$year;
  }
  public function getNextMonthUrl(){
    $newDate = $this->getNextMonth();
    $month = $newDate->format('n');
    $year = $newDate->format('Y');
    return $_SERVER['REDIRECT_URL'].'?month='.$month.'&year='.$year;
  }
  public function getNextYearUrl(){
    $date = $this->getNextYear();
    return $_SERVER['REDIRECT_URL']
        .'?month='.$date->format('n')
        .'&year='.$date->format('Y');
  }
  public function getPreviousYearUrl(){
    $date = $this->getPreviousYear();
    return $_SERVER['REDIRECT_URL']
        .'?month='.$date->format('n')
        .'&year='.$date->format('Y');
  }
  public function getDay(){
    $index = $this->selectedDayIndex;
    $day = $this->calendarDays[$index];
    return $day;
  }
  public function getNextDay(){
    $index = $this->selectedDayIndex;
    if ($index>=(count($this->calendarDays))){
      //$day = new Day(time());
      throw new \Exception("Next day {$index} is outside of this calendar");
    } else {
      $day = $this->calendarDays[$index];
    }
    
    $this->selectedDayIndex = $index+1;
    return $day;
  }
  public function numWeeks(){
    return count($this->calendarDays)/7;
  }
  public function getNameOfMonth(){
    return $this->date->format("F");
  }
  public function display(){
      $view = new \ROF\View\Controller(realpath(__DIR__.'/../'));
      $view->displayView('Calendar');
  }
  
  static public function getTimeZone(){
    if (self::$timeZone==NULL){
      self::$timeZone = new \DateTimeZone("America/Chicago");  
    }
    return self::$timeZone;
  }
  static public function resetIndex(){
    self::$index = 0;
  }
  static public function getActiveCalendar(){
    
    if (self::$activeCalendar==NULL){
      self::$activeCalendar = new Calendar();
    }
    return self::$activeCalendar;
  }
}