<?php
class Tagebuch_Db
{
    /**
     * @var PDO
     */
    public $db = null;

    protected $config = null;


    public function __construct()
    {
        $this->config = Tagebuch_Config::get();
        $this->prepare();
        $this->loadFiles();
    }



    /**
     * Returns a post object from the given file.
     *
     * @param string $file File name without path
     *
     * @return Tagebuch_Post or boolean false if not found
     */
    public function getPost($file)
    {
        $stmt = $this->db->prepare('SELECT * FROM posts WHERE file = ?');
        $stmt->execute(array($file));
        return $stmt->fetchObject('Tagebuch_Post');
    }



    public function getPosts($tag = null, $limit = null)
    {
        if ($tag === null) {
            $tag = '%';
        } else {
            $tag = '%,' . $tag . ',%';
        }
        $stmt = $this->db->prepare(
            'SELECT * FROM posts'
            . ' WHERE tags LIKE ?'
            . ' ORDER BY modified DESC'
            . ($limit !== null ? ' LIMIT ' . $limit : '')
        );
        $stmt->execute(array($tag));
        return $stmt->fetchAll(PDO::FETCH_CLASS, 'Tagebuch_Post');
    }



    /**
     * Fetches the next and previous posts from the database.
     *
     * @param string $file Filename to fetch
     * @param string $tag  Tag name that determines the file list
     *                     - may be null for no tag
     *
     * @return array Array with prev and next keys, post objects
     *               as value. NULL when empty
     */
    public function getPrevNext($file, $tag = null)
    {
        if ($tag === null) {
            $tag = '%';
        } else {
            $tag = '%,' . $tag . ',%';
        }
        $qfile = $this->db->quote($file);
        $qtag  = $this->db->quote($tag);
        list($date) = $this->db->query(
            'SELECT modified FROM posts WHERE file LIKE '
            . $qfile
            . ' LIMIT 1'
        )->fetch();
        $qdate = $this->db->quote($date);

        $prev = $this->db
            ->query('SELECT * FROM posts'
                    . ' WHERE modified < ' . $qdate
                    . ' AND tags LIKE ' . $qtag
                    . ' ORDER BY modified DESC LIMIT 1'
            )->fetchObject('Tagebuch_Post');
        $next = $this->db
            ->query('SELECT * FROM posts'
                    . ' WHERE modified > ' . $qdate
                    . ' AND tags LIKE ' . $qtag
                    . ' ORDER BY modified ASC LIMIT 1'
            )->fetchObject('Tagebuch_Post');

        return array(
            'prev' => $prev,
            'next' => $next
        );
    }



    /**
     * Returns an array of all tags
     */
    public function getTags()
    {
        $stmt = $this->db->query('SELECT tags FROM posts');
        $tags = array();
        while ($row = $stmt->fetch(PDO::FETCH_OBJ, PDO::FETCH_ORI_NEXT)) {
            $rtags = array_flip(explode(',', substr($row->tags, 1, -1)));
            $tags = array_merge($tags, $rtags);
        }
        unset($tags['']);

        return array_keys($tags);
    }




    /**
     * Prepares the table structure
     *
     * @return void
     */
    protected function prepare()
    {
        $this->db = new PDO('sqlite::memory:');
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->db->exec("CREATE TABLE posts(
title TEXT,
file TEXT,
size INTEGER,
created DATE,
modified DATE,
tags TEXT,
license TEXT
)");
        
    }



    /**
     * Loads raw files into database
     *
     * @return void
     */
    protected function loadFiles()
    {
        $query = $this->db->prepare(
            'insert into posts (title,file,size,created,modified,tags,license)'
            . ' VALUES(:title,:file,:size,:created,:modified,:tags,:license)'
        );
        $query->bindParam(':title', $title);
        $query->bindParam(':file', $filename);
        $query->bindParam(':size', $size);
        $query->bindParam(':created', $crdate);
        $query->bindParam(':modified', $mdate);
        $query->bindParam(':tags', $tags);
        $query->bindParam(':license', $license);

        foreach ($this->getRawFiles() as $file) {
            $hp = new Tagebuch_HtmlPost($file);
            $crdate = $hp->getCreationDate();
            $mdate  = $hp->getModificationDate();
            $tags   = ',' . implode(
                ',',
                $hp->getTags()
            ) . ',';
            $title    = $hp->getTitle();
            $filename = basename($file);
            $size     = filesize($file);
            $license  = $hp->getLicense();
            $query->execute();
        }
    }



    /**
     * Returns an array full of raw filename paths
     *
     * @return array Array of raw file names
     */
    protected function getRawFiles()
    {
        return glob($this->config->raw . '*.htm');
    }
}

?>