<?php
/**
 * Plugin SVG: Converts inline SVG images
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 */
 
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');

/**
 * Include an external file to reduce some clutter and define some
 * functions.
 */
require_once(DOKU_PLUGIN.'svg/header.php');

/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_svg extends DokuWiki_Syntax_Plugin {
 
 	var $xml_data;
 
    function getInfo(){
        return array(
            'author' => 'Austen Dicken',
            'email'  => 'admin@cvpcs.org',
            'date'   => '2007-05-16',
            'name'   => 'DokuWiki SVG Plugin',
            'desc'   => 'Supplies a way to render SVG images inline within a document.',
            'url'    => 'http://www.cvpcs.org/dokuwiki/lib/exe/fetch.php?id=project%3Adokuwiki-svg&cache=cache&media=project:dokuwiki-svg.tar.gz',
        );
    }
 
    function getType(){
        return 'protected';
    }

    function getSort(){
        return 999;
    }
 
    function connectTo($mode) {
        $this->Lexer->addEntryPattern('<svgimage>',$mode,'plugin_svg');
    }
 
    function postConnect() {
        $this->Lexer->addExitPattern('</svgimage>','plugin_svg');
    }

    function handle($match, $state, $pos, &$handler){
        switch ($state) {
          case DOKU_LEXER_ENTER : 
            break;
          case DOKU_LEXER_MATCHED :
            break;
          case DOKU_LEXER_UNMATCHED :
            break;
          case DOKU_LEXER_EXIT :
            break;
          case DOKU_LEXER_SPECIAL :
            break;
        }
        return array( $state, $match );
    }

    function render($mode, &$renderer, $data) {
    	  global $syntax_plugin_svg_pcount;
        if($mode == 'xhtml'){
            list( $state, $match ) = $data;
            switch( $state )
            {
            case DOKU_LEXER_ENTER :
            	$this->xml_data = '';
            	break;
            case DOKU_LEXER_EXIT :
            	if( $syntax_plugin_svg_pcount == 0 )
            	{
            		$this->clearImages();
            	}
            	$this->save();
            	$this->renderSVG( $renderer );
            	$syntax_plugin_svg_pcount++;
            	break;
            default:
            	$this->xml_data .= $match;
            	break;
            }
            return true;
        }
        return false;
    }
    
    function clearImages()
    {
  		foreach( glob(
  			SYNTAX_PLUGIN_SVG_MEDIADIR .
  			'media/' .
  			md5( getID() ) .
  			'*'
  			) as $filename )
  		{
  			unlink( $filename );
  		}
    }
    
    function save()
    {
    	global $syntax_plugin_svg_pcount;
    	
    	$this->xml_data = ltrim( $this->xml_data );

	$filename = md5( getID() ) . $syntax_plugin_svg_pcount . '.svg';

    	switch( $this->getConf( 'output' ) )
    	{
    	case 'imagick':
    		if( extension_loaded( 'imagick' ) )
    		{
			$ih = new Imagick();
			$ih->readImageBlob( $this->xml_data );
			$ih->setImageFormat( $this->getConf( 'im_format' ) );
			$ih->writeImage(
				SYNTAX_PLUGIN_SVG_MEDIADIR .
					'media/' .
					substr( $filename, 0, -3 ) .
					strtolower( $this->getConf( 'im_format' ) )
				);
			$ih->destroy();
    			break;
    		}
    	case 'magickwand':
    		if( extension_loaded( 'magickwand' ) )
    		{
	    		$mwh = NewMagickWand();
	    		MagickReadImageBlob( $mwh, $this->xml_data );
	    		MagickSetFormat( $mwh, $this->getConf( 'mw_format' ) );
	    		MagickPaintTransparentImage( $mwh, NewPixelWand( '#FFFFFF' ) );
	    		MagickWriteImage(
	    			$mwh,
	    			SYNTAX_PLUGIN_SVG_MEDIADIR .
	    				'media/' . 
	    				substr( $filename, 0, -3 ) .
	    				strtolower( $this->getConf( 'mw_format' ) )
	    			);
	    		DestroyMagickWand( $mwh );
    			break;
    		}
    	case 'embed':
    	case 'object':
    	case 'iframe':
    		$fh = fopen( SYNTAX_PLUGIN_SVG_MEDIADIR . 'media/' . $filename, 'w' );
    		fwrite( $fh, $this->xml_data );
    		fclose( $fh );
    		break;
    	}
    }
    
    function renderSVG( &$renderer )
    {
    	global $syntax_plugin_svg_pcount;
    	
    	$svgp = new syntax_plugin_svg_parser();
    	$svgp->parse( $this->xml_data );
    	
    	switch( $this->getConf( 'output' ) )
    	{
    	case 'imagick':
    		if( extension_loaded( 'imagick' ) )
    		{
    			$renderer->doc .= '<img src="'
    								.  getBaseURL( true )
    								.  'data/svg/media/'
    								.  md5( getID() ) . $syntax_plugin_svg_pcount
    								.  '.' . strtolower( $this->getConf( 'im_format' ) )
    								.  '" width="'
    								.  $svgp->width . '" height="'
    								.  $svgp->height . '" alt="SVGImage'
    								.  $syntax_plugin_svg_pcount . '" />';
    			
    			break;
    		}
    	case 'magickwand':
    		if( extension_loaded( 'magickwand' ) )
    		{
    			$renderer->doc .= '<img src="'
    								.  getBaseURL( true )
    								.  'data/svg/media/'
    								.  md5( getID() ) . $syntax_plugin_svg_pcount
    								.  '.' . strtolower( $this->getConf( 'mw_format' ) )
    								.  '" width="'
    								.  $svgp->width . '" height="'
    								.  $svgp->height . '" alt="SVGImage'
    								.  $syntax_plugin_svg_pcount . '" />';
    			
    			break;
    		}
    	case 'embed':
    		$renderer->doc .= '<embed src="'
    							.  getBaseURL( true )
    							.  'data/svg/media/'
    							.  md5( getID() ) . $syntax_plugin_svg_pcount . '.svg" width="'
    							.  $svgp->width . '" height="'
    							.  $svgp->height . '" '
    							.  'type="image/svg+xml" '
    							.  'pluginspage="http://www.adobe.com/svg/viewwer/install/" />';
    		break;
    	case 'object':
    		$renderer->doc .= '<object data="'
    							.  getBaseURL( true )
    							.  'data/svg/media/'
    							.  md5( getID() ) . $syntax_plugin_svg_pcount . '.svg" width="'
    							.  $svgp->width . '" height="'
    							.  $svgp->height . '" '
    							.  'type="image/svg+xml" '
    							.  'pluginspage="http://www.adobe.com/svg/viewwer/install/" />';
    	case 'iframe':
    		$renderer->doc .= '<iframe style="border: none;" src="'
    							.  getBaseURL( true )
    							.  'data/svg/media/'
    							.  md5( getID() ) . $syntax_plugin_svg_pcount . '.svg" width="'
    							.  $svgp->width . '" height="'
    							.  $svgp->height . '" '
    							.  'type="image/svg+xml"></iframe>';
    		break;
    	}
    }
}

