<?php
/**
 * Define a page.
 * @author Valentin CARRUESCO
 * @category Plugin
 * @license MIT
 */
class WikiPage extends Entity{
    public $id,$label,$content,$state,$path,$category,$slug,$sort = 0;
    const PUBLISHED = 'published';
    const DRAFT = 'draft';
    protected $TABLE_NAME = 'wiki_page';

    public $fields =
    array(
        'id' => 'key',
        'label' => 'string',
        'state' => 'string',
        'category' => array('type'=>'int','link'=>'plugin/wiki/WikiCategory.class.php'),
        'slug' => 'string',
        'sort' => 'int',
        'path' => 'string'
    );

    public static function defaultContent(){
        $default = 'Mon contenu ici...';
        $defaultFile = File::dir().'wiki'.SLASH.'default.md';
        if(file_exists($defaultFile)) $default = file_get_contents($defaultFile);
        return $default;
    }

    public static function workspace(){
        return File::dir().'wiki'.SLASH.'pages';
    }

    public static function uploads(){
        return File::dir().'wiki'.SLASH.'uploads';
    }

    public static function path_from_label($label){
        return preg_replace('|[\?\\\/\*\:\|\<\>]|i', '-',$label);
    }

    public function author(){
        return User::byLogin($this->creator, false)->fullName();
    }
    public function created(){
        return relative_time($this->created);
    }
    public function updater(){
        return User::byLogin($this->updater, false)->fullName();
    }
    public function updated(){
        return relative_time($this->updated);
    }
    public function html(){
        
        $markdown = new WikiPageParsedown();
        $markdown->setBreaksEnabled(true);

        $rawText = $this->content;
        Plugin::callHook('wiki_page_pre_html',array(&$rawText));

        $html = $markdown->text($rawText);

        Plugin::callHook('wiki_page_post_html',array(&$html));

       

        return $html;
    }
    public function content(){
        $this->content = file_get_contents(self::workspace().SLASH.wiki_os_encode($this->path));
    }

}

require_once(__DIR__.SLASH.'lib'.SLASH.'Parsedown.php');
//Etend la classe parsedown pour y ajouter des features (ex:le souligné (__texte souligné__))
class WikiPageParsedown extends Parsedown{


    protected function paragraph($Line)
    {
        if (substr($Line['text'], -1) === '#')
        {
            $closed = true;

            $Line['text'] = substr($Line['text'], 0, -1);
        }

        $Block = parent::paragraph($Line);

        if (isset($closed))
        {
            $Block['closed'] = true;
        }

        return $Block;
    }

    protected function paragraphContinue($Line, array $Block)
    {
        if (isset($Block['closed']))
        {
            return;
        }

        if (isset($Block['interrupted']))
        {
            $Block['element']['handler']['argument'] .= '  '.str_repeat("\n  ", $Block['interrupted']);
            unset($Block['interrupted']);
        }

        if (substr($Line['text'], -1) === '#')
        {
            $Block['closed'] = true;

            $Line['text'] = substr($Line['text'], 0, -1);
        }

        $Block['element']['handler']['argument'] .= "\n".$Line['text'];

        return $Block;
    }
   
    protected function blockCode($Line, $Block = null)
    {
        if (isset($Block) and $Block['type'] === 'Paragraph' and ! isset($Block['interrupted']))
        {
            return;
        }

        if ($Line['indent'] >= 4)
        {
            $text = substr($Line['body'], 4);

            $Block = array(
                'element' => array(
                    'name' => 'pre',
                    'element' => array(
                        'name' => 'code',
                        'attributes' => array('class' => "block-code"), 
                        'text' => $text,
                    ),
                ),
            );

            return $Block;
        }
    }


    protected function blockQuote($Line)
    {
        if (preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
        {
            $Block = array(
                'element' => array(
                    'name' => 'blockquote',
                    'attributes' => array('class' => "blockquote"), 
                    'handler' => array(
                        'function' => 'linesElements',
                        'argument' => (array) $matches[1],
                        'destination' => 'elements',
                    )
                ),
            );

            return $Block;
        }
    }


    protected function blockTable($Line, array $Block = null)
    {
        if ( ! isset($Block) or $Block['type'] !== 'Paragraph' or isset($Block['interrupted']))
        {
            return;
        }

        if (
            strpos($Block['element']['handler']['argument'], '|') === false
            and strpos($Line['text'], '|') === false
            and strpos($Line['text'], ':') === false
            or strpos($Block['element']['handler']['argument'], "\n") !== false
        ) {
            return;
        }

        if (chop($Line['text'], ' -:|') !== '')
        {
            return;
        }

        $alignments = array();

        $divider = $Line['text'];

        $divider = trim($divider);
        $divider = trim($divider, '|');

        $dividerCells = explode('|', $divider);

        foreach ($dividerCells as $dividerCell)
        {
            $dividerCell = trim($dividerCell);

            if ($dividerCell === '')
            {
                return;
            }

            $alignment = null;

            if ($dividerCell[0] === ':')
            {
                $alignment = 'left';
            }

            if (substr($dividerCell, - 1) === ':')
            {
                $alignment = $alignment === 'left' ? 'center' : 'right';
            }

            $alignments []= $alignment;
        }

        # ~

        $HeaderElements = array();

        $header = $Block['element']['handler']['argument'];

        $header = trim($header);
        $header = trim($header, '|');

        $headerCells = explode('|', $header);

        if (count($headerCells) !== count($alignments))
        {
            return;
        }

        foreach ($headerCells as $index => $headerCell)
        {
            $headerCell = trim($headerCell);

            $HeaderElement = array(
                'name' => 'th',
                'handler' => array(
                    'function' => 'lineElements',
                    'argument' => $headerCell,
                    'destination' => 'elements',
                )
            );

            if (isset($alignments[$index]))
            {
                $alignment = $alignments[$index];

                $HeaderElement['attributes'] = array(
                    'style' => "text-align: $alignment;"
                );
            }

            $HeaderElements []= $HeaderElement;
        }

        # ~

        $Block = array(
            'alignments' => $alignments,
            'identified' => true,
            'element' => array(
                'name' => 'table',
                'attributes' => array('class' => "table"), /* + core */
                'elements' => array(),
            ),
        );

        $Block['element']['elements'] []= array(
            'name' => 'thead',
        );

        $Block['element']['elements'] []= array(
            'name' => 'tbody',
            'elements' => array(),
        );

        $Block['element']['elements'][0]['elements'] []= array(
            'name' => 'tr',
            'elements' => $HeaderElements,
        );

        return $Block;
    }

    protected function blockFencedCode($Line)
    {
        $marker = $Line['text'][0];

        $openerLength = strspn($Line['text'], $marker);

        if ($openerLength < 3)
        {
            return;
        }

        $infostring = trim(substr($Line['text'], $openerLength), "\t ");

        if (strpos($infostring, '`') !== false)
        {
            return;
        }

        $Element = array(
            'name' => 'code',
            'attributes' => array('class' => "block-code"),
            'text' => '',
        );

        if ($infostring !== '')
        {
            $Element['attributes'] = array('class' => "language-$infostring");
        }

        $Block = array(
            'char' => $marker,
            'openerLength' => $openerLength,
            'element' => array(
                'name' => 'pre',
                'element' => $Element,
            ),
        );

        return $Block;
    }

    protected function inlineCode($Excerpt)
    {
        $marker = $Excerpt['text'][0];

        if (preg_match('/^(['.$marker.']++)[ ]*+(.+?)[ ]*+(?<!['.$marker.'])\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
        {
            $text = $matches[2];
            $text = preg_replace('/[ ]*+\n/', ' ', $text);

            return array(
                'extent' => strlen($matches[0]),
                'element' => array(
                    'name' => 'code',
                    'attributes' => array('class' => "inline-code"), 
                    'text' => $text,
                ),
            );
        }
    }

    protected function inlineEmphasis($Excerpt)
    {
        if ( ! isset($Excerpt['text'][1]))
        {
            return;
        }
        $marker = $Excerpt['text'][0];
        if(preg_match('/^__([^__]*)__/us', $Excerpt['text'], $matches)){
            $emphasis = 'u';
        }else if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
        {
            $emphasis = 'strong';
        }
        elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
        {
            $emphasis = 'em';
        }
        else
        {
            return;
        }

        return array(
            'extent' => strlen($matches[0]),
            'element' => array(
                'name' => $emphasis,
                'attributes' => array(
                        'class' => 'emphasis-underscore' ,
                ),
                'handler' => array(
                    'function' => 'lineElements',
                    'argument' => $matches[1],
                    'destination' => 'elements',
                )
            ),
        );
    }
}


?>