<?php
/**
 * Plugin hcalendar: Using Microformat Calendar
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Juergen A. Lamers <jaloma.ac@googlemail.com>
 * @seealso    (http://jaloma.ac.googlepages.com/plugin:hcalendar)
 * @seealso    (http://microformats.org/wiki/internet-explorer-extensions)
 * @seealso    (http://microformats.org/wiki/firefox-extensions)
 */
 
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
require_once(DOKU_PLUGIN.'hcalendar/syntax/helper.php'); 
require_once(DOKU_PLUGIN.'hcalendar/syntax/hcal_renderer_helper.php'); 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_hcalendar_hcal2 extends DokuWiki_Syntax_Plugin {
 
  /**
   * default parameters of the jalbum tag
   */
  var $dflt = array(
		    'start_date' => 'off',
		    'start_time' => 'off',
		    'end_date' => 'off',
			'end_time' => 'off',
		    'summary' => 'off',
		    'location' => 'off',
			'inline' => 'off',
		    );
  var $rendering = true;
  var $is_inline = false;
  
  function getInfo(){
    return array(
		 'author' => 'Juergen A. Lamers',
		 'email'  => 'jaloma.ac@googlemail.com',
		 'date'   => @file_get_contents(DOKU_PLUGIN . 'hcalendar/VERSION'),
		 'name'   => 'HCalendar HCal2 Plugin',
		 'desc'   => 'Adds a HCalendar Items 
                     syntax: <hcal startdate="yyyy/mm/dd" starthour="hh:mm:ss"
					 enddate="yyyy/mm/dd" endhour="hh:mm:ss" summary="" location=""></hcal>
                     See: http://microformats.org/wiki/',
		 'url'    => 'http://www.dokuwiki.org/plugin:hcalendar',
		 );
  }
 
  function getType() { return  'substition'; } //'formatting';}//
  function getSort() { return 351; }
  function getPType() { return 'normal'; }
//  function getAllowedTypes() { return array('formatting', 'substition', 'disabled'); }
  function connectTo($mode) {
//    $this->Lexer->addSpecialPattern('<hcal ?[^>\n]*>.*?</hcal>',$mode,'plugin_hcalendar_hcal2');
  $this->Lexer->addEntryPattern('<hcal.*?>(?=.*?</hcal>)',$mode,'plugin_hcalendar_hcal2'); 

  }
    function postConnect() {
    $this->Lexer->addExitPattern('</hcal>','plugin_hcalendar_hcal2');
  }

	function matchLength() {
		return strlen("<hcal");
	}
    /**
     * Handle the match
     */
  function handle($match, $state, $pos, &$handler){
    // break matched cdata into its components
    switch ($state) {
      case DOKU_LEXER_ENTER :
	  	list($str_params, $background) = preg_split("/<\//u", substr($match, $this->matchLength()+1, -1), 2);
    	$cinfo = $this->_extract_params($str_params);
    	return array($state, $cinfo);
      case DOKU_LEXER_UNMATCHED :  return array($state, $match);
      case DOKU_LEXER_EXIT :       return array($state, '');
	}
	return array();
  }

	/**
	 * Create output
	 */
	function render($mode, & $renderer, $match) {
	global $conf;
	    setlocale(LC_ALL,$this->getConf('locale'));
		if ($mode == 'xhtml') {
			list($state, $data) = $match;
            switch ($state) {
              case DOKU_LEXER_ENTER :      
		  		$renderer->doc .= $this->_connectData($data);
                break;
              case DOKU_LEXER_UNMATCHED :  
			  	if ($this->rendering) {
			  		$r = p_render('xhtml',p_get_instructions($data),$info);
//			  		$renderer->doc .= $renderer->_xmlEntities($data);
		            $renderer->doc .= $r;
				}
				$renderer->nocache();
			  	break;
              case DOKU_LEXER_EXIT :       
			  	if ($this->rendering) {
			  		if (!$this->is_inline) {
			  		$renderer->doc .= helper_plugin_hcal::buildTextEnd('tag_vevent');
					}
				}
			  	break;
            }
		  return true;
		}
		return false;
	}

	function _connectData($data) {
		$mm_start=  $ss_start= '00';
	  	$yy_start =$mth_start= $dy_start =
			$hh_start= 
	 		$tm_start=
	  		$yy_end=   $mth_end=   $dy_end=
	  		$hh_end=   $mm_end=    $ss_end=
	  		$tm_end= '';
		  $this->rendering = true;
		  $start_date = $data['start_date'];
		  if ($start_date != '' && $start_date != 'off') {
		  	$time = strtotime($start_date);
		  	list($yy_start, $mth_start, $dy_start) = hcal_parseDateEntry($start_date);
		  
		  	$start_time = $data['start_time'];
			if ($start_time == 'hh:mm') { $start_time = 'off';}
		  	if ($start_time != 'off') {
				list($hh_start, $mm_start, $ss_start) = hcal_parseTimeEntrie($start_time);
				if ($mm_start == null || $mm_start == '') {
					$mm_start = '00';
				}
				if ($ss_start == null || $ss_start == '') {
					$ss_start = '00';
				}
		  		$time = strtotime($start_date." ".$hh_start.":".$mm_start);
		  		$tm_start = $hh_start.":".$mm_start;
		  	}
			$dt_start = $time;
		  }
		  $end_date = $data['end_date'];
 		  if ($end_date == 'yyyy/mm/dd') { $end_date = 'off';}

		  if ($end_date != 'off') {
		  	$time = strtotime($end_date);
		  	list($yy_end, $mth_end, $dy_end) = hcal_parseDateEntry($end_date);
		  
		  	$end_time = $data['end_time'];
			if ($end_time == 'hh:mm') { $end_time = 'off';}
		  	if ($end_time != 'off') {
				list($hh_end, $mm_end, $ss_end) =  hcal_parseTimeEntrie($end_time);
				if ($mm_end == null || $mm_end == '') {
					$mm_end = '00';
				}
				if ($ss_end == null || $ss_end == '') {
					$ss_end = '00';
				}
		  		$time = strtotime($end_date." ".$hh_end.":".$mm_end);
		  		$tm_end = $hh_end.":".$mm_end;
		  	}
			$dt_end = $time;
		  }
		  $location = $data['location'];
		  if ($location == 'off') { $location = '';}
		  $summary = $data['summary'];
		  if ($summary == 'off') { $summary = '';}
		$this->is_inline = $data['inline'] != 'off';
		  if (!$this->is_inline) {
    	  if ($this->getConf('filterdate') == true) {
      		$dt_now = strtotime("now");
      		if ($dt_start < $dt_now && $dt_end < $dt_now) { 
			  $this->rendering = false;
			  return "";
			}
    	  }
		  }
		  if ($this->is_inline) { $tag_prefix = 'i';} else { $tag_prefix ='';}
		  $txt = helper_plugin_hcal::buildText(
		     $yy_start,$mth_start,$dy_start,$hh_start,$mm_start,$ss_start,$dt_start,
		     $yy_end  ,$mth_end  ,$dy_end  ,$hh_end,  $mm_end,  $ss_end,  $dt_end,
		     $summary ,$location, $this->is_inline,
		     $tag_prefix.'tag_vevent',
		     $tag_prefix.'tag_summary',
		     $tag_prefix.'tag_dtstart',
		     $tag_prefix.'tag_dtend',
		     $tag_prefix.'tag_location',
		     $tag_prefix.'tag_uid',
		     $tag_prefix.'tag_dtstamp',
			 !$this->is_inline
		     );
			 return $txt;
}
  /**
   * extract parameters for the googlemap from the parameter string
   *
   * @param   string    $str_params   string of key="value" pairs
   * @return  array                   associative array of parameters key=>value
   */
  function _extract_params($str_params) {
    $param = array();
    preg_match_all('/(\w*)="(.*?)"/us',$str_params,$param,PREG_SET_ORDER);
    if (sizeof($param) == 0) {
      preg_match_all("/(\w*)='(.*?)'/us",$str_params,$param,PREG_SET_ORDER);
    }
    // parse match for instructions, break into key value pairs      
    $gmap = $this->dflt;
    foreach($param as $kvpair) {
      list($match,$key,$val) = $kvpair;
//    $key = strtolower($key);
      if (isset($gmap[$key])) $gmap[$key] = $val;        
    }

    return $gmap;
  }
  
} // class
