<?php
require_once('config.php');

/**
 * @author Gernot WALZL
 */
class FileSystemObject {

    function order_by(&$table, $field, $sort_type=SORT_ASC) {
        foreach ($table as $row) {
            $keys[] = $row[$field];
        }
        array_multisort($keys, $sort_type, $table);
    }

    function group_by_dirname($files) {
        $result = array();
        $group = array();
        $prevdir = dirname($files[0]['path']);
        foreach ($files as $file) {
            $currdir = dirname($file['path']);
            if ($prevdir != $currdir) {
                array_push($result, $group);
                $group = array();
            }
            array_push($group, $file);
            $prevdir = $currdir;
        }
        array_push($result, $group);
        return $result;
    }

    function get_files($path='.') {
        $result = null;
        if ($handle = opendir($path)) {
            $result = array();
            while (false !== ($filename = readdir($handle))) {
                if (substr($filename,0,1) != '.') {
                    $pathfile = $path.'/'.$filename;
                    if (is_file($pathfile) &&
                            is_readable($pathfile)) {
                        $file = array();
                        $file['path'] = $pathfile;
                        $file['time'] = filemtime($pathfile);
                        $file['size'] = filesize($pathfile);
                        array_push($result, $file);
                    }
                }
            }
            closedir($handle);
        }
        return $result;
    }

    function is_ignored($ignored_dirnames, $dir) {
        $result = false;
        if (is_array($ignored_dirnames)) {
            foreach ($ignored_dirnames as $ignored) {
                if ($ignored == $dir) {
                    $result = true;
                    break;
                }
            }
        }
        return $result;
    }

    function get_files_rec(&$result, $path='.', $ignored_dirnames=null) {
        if ($handle = opendir($path)) {
            $files = $this->get_files($path);
            foreach ($files as $file) {
                array_push($result, $file);
            }
            while (false !== ($file = readdir($handle))) {
                if (substr($file,0,1) != '.') {
                    if (is_dir($path.'/'.$file)) {
                        if (!$this->is_ignored($ignored_dirnames, $file)) {
                            $this->get_files_rec($result, $path.'/'.$file, $ignored_dirnames);
                        }
                    }
                }
            }
            closedir($handle);
        }
    }

}

/**
 * @author Gernot WALZL
 */
class ChangesRSS {

    function __construct($config) {
        $this->config = $config;
    }

    function println($msg) {
        print($msg."\n");
    }

    function print_head() {
        $this->println('<?xml version="1.0" encoding="utf-8"?>');
        $this->println('<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">');
        $this->println('<channel>');
        $this->println('<title>'.$this->config->title.'</title>');
        $this->println('<link>'.$this->config->link.'</link>');
        $this->println('<description>'.$this->config->description.'</description>');
        $this->println('<lastBuildDate>'.date(DATE_RSS).'</lastBuildDate>');
    }

    function print_item($title, $link, $date, $description='') {
        $this->println('<item>');
        $this->println('<title>'.$title.'</title>');
        $this->println('<link>'.$link.'</link>');
        $this->println('<pubDate>'.date(DATE_RSS, $date).'</pubDate>');
        if (!empty($description)) {
            $this->println('<description>'.$description.'</description>');
        }
        $this->println('</item>');
    }

    function print_change_item($files) {
        $title = basename(dirname($files[0]['path']));
        if ($title == '.') {
            $title = $this->config->rootnode;
        } else {
            $title = str_replace('_', ' ', $title);
        }
        $link = $this->config->link;
        if (!empty($this->config->link_append)) {
            $link .= $this->config->link_append;
        }
        if ($this->config->urlencode_path) {
            $link .= urlencode(dirname($files[0]['path']));
        } else {
            $link .= dirname($files[0]['path']);
        }
        $date = $files[0]['time'];
        $desc = "\n";
        foreach ($files as $file) {
            $desc .= basename($file['path']).'&lt;br /&gt;';
            $desc .= "\n";
        }
        $this->print_item($title, $link, $date, $desc);
    }

    function print_changes($files_grouped) {
        $max_num_elements = count($files_grouped);
        if ($max_num_elements > $this->config->max_num_changes) {
            $max_num_elements = $this->config->max_num_changes;
        }
        for ($cnt = 0; $cnt < $max_num_elements; $cnt++) {
            $this->print_change_item($files_grouped[$cnt]);
        }
    }

    function print_foot() {
        $this->println('</channel>');
        $this->println('</rss>');
    }

}

/**
 * @author Gernot WALZL
 */
class ChangesHTML {

    function __construct($config) {
        $this->config = $config;
        $this->config->date_format = 'l, Y-m-d H:i T';
    }

    function println($msg) {
        print($msg."\n");
    }

    function print_style() {
        $this->println('html { background-color: #e9e9e9; }');
        $this->println('body { background-color: #ffffff; border: 1px solid #a1a1a1; margin: 2.5em; padding: 2em; font-family: sans-serif; }');
        $this->println('h2, h3 { line-height: 1; }');
        $this->println('span.date { font-size: small; font-weight: normal; }');
        $this->println('td { padding-left: 0.5em; padding-right: 0.5em; }');
        $this->println('td.filedate { font-size: small; }');
    }

    function print_head() {
        $this->println('<!DOCTYPE html>');
        $this->println('<html lang="en">');
        $this->println('<head>');
        $this->println('<meta charset="utf-8">');
        $this->println('<title>'.$this->config->title.'</title>');
        $this->println('<meta name="viewport" content="width=device-width, initial-scale=1.0" />');
        $this->println('<style>');
        $this->print_style();
        $this->println('</style>');
        $this->println('</head>');
        $this->println('<body>');
        $this->println('<header>');
        $this->println('<h1>'.$this->config->title.'</h1>');
        $this->println('<h2>'.$this->config->description.'<br />');
        $this->println('<span class="date">'.date($this->config->date_format).'</span></h2>');
        $this->println('</header>');
    }

    function print_change_item($files) {
        $title = basename(dirname($files[0]['path']));
        if ($title == '.') {
            $title = $this->config->rootnode;
        } else {
            $title = str_replace('_', ' ', $title);
        }
        $link = $this->config->link;
        if (!empty($this->config->link_append)) {
            $link .= $this->config->link_append;
        }
        if ($this->config->urlencode_path) {
            $link .= urlencode(dirname($files[0]['path']));
        } else {
            $link .= dirname($files[0]['path']);
        }
        $date = $files[0]['time'];
        $this->println('<h3><a href="'.$link.'">'.$title.'</a><br />');
        $this->println('<span class="date">'.date($this->config->date_format, $date).'</span></h3>');
        $this->println('<table>');
        foreach ($files as $file) {
            $this->println('<tr>');
            $this->println('<td class="filename">'.basename($file['path']).'</td>');
            $this->println('<td class="filedate">'.date('Y-m-d', $file['time']).'</td>');
            $this->println('</tr>');
        }
        $this->println('</table>');
    }

    function print_changes($files_grouped) {
        $max_num_elements = count($files_grouped);
        if ($max_num_elements > $this->config->max_num_changes) {
            $max_num_elements = $this->config->max_num_changes;
        }
        for ($cnt = 0; $cnt < $max_num_elements; $cnt++) {
            $this->print_change_item($files_grouped[$cnt]);
        }
    }

    function print_foot() {
        $this->println('</body>');
        $this->println('</html>');
    }

}


$format = 'rss';
if (isset($_GET['format'])) {
    if ($_GET['format'] == 'html') {
        $format = 'html';
    }
}

$config = new ChangesConfig();
$fso = new FileSystemObject();
$files = array();
$fso->get_files_rec($files, '.', $config->ignored_dirnames);
$fso->order_by($files, 'time', SORT_DESC);
$files_grouped = $fso->group_by_dirname($files);

if ($format == 'html') {
    $html_changes = new ChangesHTML($config);
    $html_changes->print_head();
    $html_changes->print_changes($files_grouped);
    $html_changes->print_foot();
} else {
    header('Content-Type: application/rss+xml; charset=utf-8');
    $rss_changes = new ChangesRSS($config);
    $rss_changes->print_head();
    $rss_changes->print_changes($files_grouped);
    $rss_changes->print_foot();
}

?>