<?php

/**
 * 
 *
 * @version $Id$
 * @copyright 2003 
 **/

class plugin_rhc_next_upcoming {
	var $timezone = false;
	function __construct(){
		//-- return a value when get_post_meta is called
		add_filter("get_post_metadata", array($this,'get_post_metadata'),10,4);
		
		//"get_{$meta_type}_metadata", null, $object_id, $meta_key, $single
		add_filter('generate_calendarize_meta', array(&$this,'generate_calendarize_meta'), 20, 2);
		
		//-- add postmeta to post info metabox 
		add_filter('rhc_post_info_quick_icons', array(&$this,'rhc_post_info_quick_icons'), 10, 1);
		add_filter('postinfo_postmeta_include', array(&$this,'postinfo_postmeta_include'), 10, 1);
		//-- formatting
		add_filter('rhc_post_info_value', array(&$this,'rhc_post_info_value'), 10, 3);
		
		add_shortcode('rhc_next_upcoming_dates', array(&$this,'handle_shortcode'));
	}
	
	function handle_shortcode($atts,$content=null,$code=""){
		extract(shortcode_atts(array(
			'since'		=> date('Y-m-d'), 
			'max'		=> 10,
			'end_label' => '',//if specified	and there are no more repetitions as of argument date, will show this label instead.	
			'format'	=> '',  //date format for php date() //if using local_tz this format is ignored.
			'class'		=> 'next-upcoming-date',
			'tags' 		=> 'ul,li',//comma separated tags to use a container an item tag
			'post_id'	=> '',
			'local_tz'	=> '',
			'local_tz_format' => 'MMMM d, yyyy h:mmtt' // this only applies  to local_tz dates.
		), $atts));		
	
		$extra_parameters = '';
		$data_format_options = '';
		if( '1' == $local_tz ){
			$class.=' rhc-local-tz';
			global $rhc_plugin;	
		
			$monthnames = $rhc_plugin->get_option( 'cal_monthnames', __('January,February,March,April,May,June,July,August,September,October,November,December','rhc'), true );
			$monthnamesshort = $rhc_plugin->get_option( 'cal_monthnamesshort', __('Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec','rhc'), true );
			$daynames = $rhc_plugin->get_option( 'cal_daynames', __('Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday','rhc'), true );
			$daynamesshort = $rhc_plugin->get_option( 'cal_daynamesshort', __('Sun,Mon,Tue,Wed,Thu,Fri,Sat','rhc'), true );
		
			$format_options = json_encode( (object)array(
				'monthNames' 		=> explode(',',$monthnames),
				'monthNamesShort' 	=> explode(',',$monthnamesshort),
				'dayNames' 			=> explode(',',$daynames),
				'dayNamesShort'		=> explode(',',$daynamesshort)		
			));		
			
			$data_format_options = sprintf("data-format_options=\"%s\"",
				esc_attr( $format_options )
			);	
		}

		$post_id = intval($post_id) > 0 ? intval( $post_id ) : get_the_ID() ;
		if( $post_id > 0 ){
			if(empty($format)){
				global $rhc_plugin;	
				$allday = get_post_meta( $post_id, 'fc_allday', true );
				if($allday=='1'){
					$format = $rhc_plugin->get_option('date_format', get_option('date_format'), true  );	
				}else{
					$format = $rhc_plugin->get_option('datetime_format', get_option('date_format').' '.get_option('time_format'), true  );
				}		
			}		
			
			$tags_arr = explode(',',$tags);
			
			$dates = $this->get_upcoming( $post_id, false, intval($max), $since );
			if( is_array($dates) && count($dates)>0 ){
				$out = sprintf('<%s class="%s" %s>', $tags_arr[0], $class, $data_format_options );
				foreach($dates as $d){
					if( !method_exists( $d, 'format' ) ){				
						if( '1' == $local_tz ){
							$udate = get_gmt_from_date( date('Y-m-d H:i:s', strtotime($d) ), 'U' );						
							$extra_parameters .= ' ' . sprintf( 'data-udate="%s"', $udate );
							$extra_parameters .= ' ' . sprintf( 'data-fc_date_format="%s"', esc_attr( $local_tz_format ) );
							$extra_parameters .= ' class="rhc_date"';
						}
						
						$out.= sprintf('<%s %s>%s</%s>',
							$tags_arr[1],
							$extra_parameters,
							date_i18n($format,strtotime($d)),
							$tags_arr[1] 
						);	
					}else{
						if( '1' == $local_tz ){
							$udate = get_gmt_from_date( $d->format( 'U' ) );					
							$extra_parameters .= ' ' . sprintf( 'data-udate="%s"', $udate );
							$extra_parameters .= ' ' . sprintf( 'data-fc_date_format="%s"', esc_attr( $local_tz_format ) );
							$extra_parameters .= ' class="rhc_date"';
						}						
						
						$out.= sprintf('<%s %s>%s</%s>',
							$tags_arr[1],
							$extra_parameters,
							$d->format($format),
							$tags_arr[1] 
						);					
					}						
				}
				$out.= sprintf('</%s>',$tags_arr[0] );
				return $out;
			}else{
				return $end_label;
			}
		}
		
		return '';
	}
	
	function rhc_post_info_value($value,$o,$for_filter){
		if($o->type=='postmeta' && $o->postmeta=='rhc_next_upcoming_date' && !empty($value)){
			global $rhc_plugin;	
			$allday = get_post_meta( $o->post_ID, 'fc_allday', true );
			if($allday=='1'){
				$format = $rhc_plugin->get_option('date_format', get_option('date_format'), true  );	
			}else{
				$format = $rhc_plugin->get_option('datetime_format', get_option('date_format').' '.get_option('time_format'), true  );
			}
		
			$value = date( $format, strtotime($value) );
		}else if($o->type=='postmeta' && $o->postmeta=='rhc_next_upcoming_date_date' && !empty($value)){
			global $rhc_plugin;	
			$format = $rhc_plugin->get_option('date_format', get_option('date_format'), true  );
			$value = date( $format, strtotime($value) );
		}else if($o->type=='postmeta' && $o->postmeta=='rhc_next_upcoming_date_times' && !empty($value)){
			global $rhc_plugin;	
			$format = $rhc_plugin->get_option('time_format', get_option('time_format'), true  );
			if(is_array($value)){
				$tmp = array();
				foreach($value as $v){
					$tmp[] = sprintf("<span class=\"rhc-next-date-time\">%s</span>",
						date( $format, strtotime($v) )
					);
				}
				$value = sprintf('<div class="rhc-next-date-time-holder">%s</div>',
					implode("",$tmp)
				);				
			}else{
				$arr = explode(',',$value);
				$tmp = array();
				foreach($arr as $v){
					$tmp[] = sprintf("<span class=\"rhc-next-date-time\">%s</span>",
						date( $format, strtotime($v) )
					);
				}
				$value = sprintf('<div class="rhc-next-date-time-holder">%s</div>',
					implode("",$tmp)
				);	
			}
		}			
		
		if( $o->type == 'custom' ){
			if( 0===strpos( $o->value, '[rhc_next_upcoming_dates' ) ){

				if( false===strpos( $o->value, 'post_id=' ) ){
					$value = str_replace( '[rhc_next_upcoming_dates', sprintf('[rhc_next_upcoming_dates post_id="%s"',$o->post_ID),  $o->value );
				}
			} 
		}
		
		return $value;
	}
	
	function get_post_metadata($unused, $post_id, $meta_key, $single=true){

		if( $meta_key=='rhc_next_upcoming_date' || $meta_key=='rhc_next_upcoming_date_date' ){
			$upcoming = $this->get_upcoming( $post_id, $single );
			if(count($upcoming)==0){
				return $single ? '' : array();
			}else{
				$dates = $upcoming;	
				
				return $single ? $dates[0] : $dates;
			}
		}else if($meta_key=='rhc_next_upcoming_date_times'){
			$upcoming = $this->get_next_upcoming_date_times( $post_id );
			return implode(',',$upcoming);
		}
		return null;
	}
	
	function get_next_upcoming_date_times( $post_id, $since=false ){
		$upcoming_date = $this->get_upcoming( $post_id, true, 1, $since );
		if( isset($upcoming_date[0]) ){
			$like_time = strtotime($upcoming_date[0]);
			$like = date('Y-m-d', $like_time);
			global $wpdb;
			$sql = sprintf("SELECT event_start FROM `{$wpdb->prefix}rhc_events` WHERE post_id=%d AND event_start LIKE '%s%%' ORDER BY event_start ASC",
				intval($post_id),
				$like
			);
			return $wpdb->get_col($sql,0);				
		}else{
			return array();
		}
	}
	
	function get_upcoming( $post_id, $single=true, $limit=5, $since=false ){	
		//---	
		if(false!==$since){
			$time = strtotime($since);
			if(false===$time||-1===$time){
				$time=time();
			}
		}else{
			$time=time();
		}
		
		$limit = $single ? 1 : $limit;
		global $wpdb;
		$sql = sprintf("SELECT event_start FROM `{$wpdb->prefix}rhc_events` WHERE post_id=%d AND event_start>'%s' ORDER BY event_start ASC LIMIT %d",
			intval($post_id),
			date('Y-m-d H:i:s',$time),
			intval($limit)
		);
		$upcoming_events = $wpdb->get_col($sql,0);		
		
		return $upcoming_events;
	}
	
	function get_recurr_dates( $post_id ){
		if(!class_exists('RecurrenceRule')){
			require_once RHCNUP_PATH.'recurr/TransformerConfig.php';
			require_once RHCNUP_PATH.'recurr/DateUtil.php';
			require_once RHCNUP_PATH.'recurr/Weekday.php';
			require_once RHCNUP_PATH.'recurr/DateInfo.php';
			require_once RHCNUP_PATH.'recurr/DaySet.php';
			require_once RHCNUP_PATH.'recurr/Time.php';
			require_once RHCNUP_PATH.'recurr/RecurrenceRule.php';
			require_once RHCNUP_PATH.'recurr/RecurrenceRuleTransformer.php';
		}
		$rrule = get_post_meta($post_id, 'fc_rrule', true);
		$start = get_post_meta($post_id,'fc_start_datetime',true);
		if(empty($start)){
			return array();
		}
		$ts = strtotime($start);
		//--
		$timezone = $this->get_timezone();
		//--		
//echo "Start: ".$start." $ts<br>";		
		$startDate   = new \DateTime($start, new \DateTimeZone($timezone));
		$rule        = new \Recurr\RecurrenceRule($rrule, $startDate, $timezone);
		$transformer = new \Recurr\RecurrenceRuleTransformer($rule);
		
		$dates = $transformer->getComputedArray();

		$dates = is_array($dates)?$dates:array();
	
		//--- add repeat dates
		$rdate = get_post_meta($post_id, 'fc_rdate', true);
		$rdate_arr = array();
		if(''!=trim($rdate)){
			$rdate_arr = explode(',',$rdate);
			if(count($rdate_arr)>0){
				foreach($rdate_arr as $date_str){
					$tmp_date = new \DateTime($date_str, new \DateTimeZone($timezone));
					if(is_object($tmp_date)){
						$dates[]=$tmp_date;
					}
				}
				sort($dates);
			}
		}
	
		//--- exclude
		$exdate = get_post_meta($post_id, 'fc_exdate', true);

		$exdate_arr = array();
		if(count($dates)>0 && ''!=trim($rdate)){
			$exdate_arr = explode(',', $exdate );			
			if(count($exdate_arr)>0){
				$exclude_date_objects = array();
				foreach($exdate_arr as $date_str){
					$tmp_date = new \DateTime($date_str, new \DateTimeZone($timezone));
					if(is_object($tmp_date)){
						$exclude_date_objects[]=$tmp_date;
					}
				}			

				$dates = array_udiff( $dates, $exclude_date_objects, function($a, $b){
					if($a->format('U')<$b->format('U')){
						return -1;
					}else if($a->format('U')==$b->format('U')){
						return 0;
					}else{
						return 1;
					}
				});
			}
		}
			
		return $dates;
	}
	
	function generate_calendarize_meta($post_id, $post){
		return $post_id;
	}
	
	function get_timezone(){
		if(false!==$this->timezone)return $this->timezone;
		//---
		$timezone = get_option('timezone_string');
		if(empty($timezone)){
			$gmt_offset = get_option('gmt_offset');
			if(!empty($gmt_offset)){
				$timezone = timezone_name_from_abbr("", ($gmt_offset*3600), 0);	
			}
		}
		$timezone = empty($timezone) || false===$timezone? 'America/New_York' :$timezone;
		$this->timezone = $timezone;
		//---
		return $timezone;
	}
	
	function rhc_post_info_quick_icons( $quick_icons ){
		foreach($quick_icons as $i => $group){
			if($group->id=='event_info_icons'){
				$group->items[]=				new quick_icon_item(array(
					'label'	=> __('Next Date(Datetime)','rhc'),
					'post_extrainfo_type'			=> 'postmeta',
					'post_extrainfo_label'			=> __('Next Date','rhc'),
					'post_extrainfo_taxonomy'		=> '',
					'post_extrainfo_taxonomymeta'	=> '',
					'post_extrainfo_postmeta'		=> 'rhc_next_upcoming_date'
				));
				$group->items[]=				new quick_icon_item(array(
					'label'	=> __('Next Date(Date)','rhc'),
					'post_extrainfo_type'			=> 'postmeta',
					'post_extrainfo_label'			=> __('Next Date','rhc'),
					'post_extrainfo_taxonomy'		=> '',
					'post_extrainfo_taxonomymeta'	=> '',
					'post_extrainfo_postmeta'		=> 'rhc_next_upcoming_date_date'
				));
				$group->items[]=				new quick_icon_item(array(
					'label'	=> __('Next Date Times','rhc'),
					'post_extrainfo_type'			=> 'postmeta',
					'post_extrainfo_label'			=> __('Next Date Times','rhc'),
					'post_extrainfo_taxonomy'		=> '',
					'post_extrainfo_taxonomymeta'	=> '',
					'post_extrainfo_postmeta'		=> 'rhc_next_upcoming_date_times'
				));

				$group->items[]=				new quick_icon_item(array(
					'label'							=> __('Upcoming dates','rhc'),
					'post_extrainfo_type'			=> 'custom',
					'post_extrainfo_label'			=> __('Upcoming dates','rhc'),
					'post_extrainfo_value'			=> '[rhc_next_upcoming_dates max="10"]'				
				));				
			}

		}
		return $quick_icons;
	}

	function postinfo_postmeta_include( $options ){
		$options['rhc_next_upcoming_date'] = __('Next Date (Datetimes)','rhc');
		$options['rhc_next_upcoming_date_date'] = __('Next Date (Date)','rhc');
		$options['rhc_next_upcoming_date_times'] = __('Next Date Times','rhc');
		return $options;
	}
}
?>