<?php

class Album implements JsonSerializable {
    private $id = 0;
    private $foldername = "";
    private $title = "";
    private $thumbnail = "";
    private $description = "";
    private $createtime = "";

    public function getID() {
        return intval($this->id);
    }

    public function getFolderName($flag = 0) {
        switch ($flag) {
            case HTMLSAFE:
                return htmlspecialchars($this->foldername);
                break;
            case HTMLFORMSAFE:
                return htmlspecialchars($this->foldername, ENT_QUOTES);
                break;
            case CSVSAFE:
                return str_replace('"', '""', $this->foldername);
                break;
            default:
                return $this->foldername;
                break;
        }
    }

    public function getTitle($flag = 0) {
        switch ($flag) {
            case HTMLSAFE:
                return htmlspecialchars($this->title);
                break;
            case HTMLFORMSAFE:
                return htmlspecialchars($this->title, ENT_QUOTES);
                break;
            case CSVSAFE:
                return str_replace('"', '""', $this->title);
                break;
            default:
                return $this->title;
                break;
        }
    }

    public function getThumbnail($flag = 0) {
        switch ($flag) {
            case HTMLSAFE:
                return htmlspecialchars($this->thumbnail);
                break;
            case HTMLFORMSAFE:
                return htmlspecialchars($this->thumbnail, ENT_QUOTES);
                break;
            case CSVSAFE:
                return str_replace('"', '""', $this->thumbnail);
                break;
            case URLSAFE:
                if ( $this->thumbnail == "" ) {
                    return "graphics/no-image-available_thm.gif";
                } else {
                    return htmlspecialchars(basename(THUMBNAILFOLDER) . "/" . $this->foldername . $this->thumbnail, ENT_QUOTES);
                }
                break;
            default:
                return $this->thumbnail;
                break;
        }
    }

    public function getDescription($flag = 0) {
        switch ($flag) {
            case HTMLSAFE:
                return htmlspecialchars($this->description);
                break;
            case HTMLFORMSAFE:
                return htmlspecialchars($this->description, ENT_QUOTES);
                break;
            case CSVSAFE:
                return str_replace('"', '""', $this->description);
                break;
            default:
                return $this->description;
                break;
        }
    }

    public function getCreateTime($flag = 0) {
        switch ($flag) {
            case TIMESTAMP:
                return strtotime($this->createtime);
                break;
            case PRETTY:
                return date("F j Y H:i:s", strtotime($this->createtime));
                break;
            default:
                return $this->createtime;
                break;
        }
    }

    public function setID($id = null) {
        if (is_null($id)) return false;
        $id = abs(intval($id));
        if ($id == 0) return false;
        $this->id = $id;
        return true;
    }

    public function setFolderName($foldername = null) {
        if (is_null($foldername) || ($foldername == "")) return false;
        settype($foldername, "string");
        $this->foldername = $foldername;
        return true;
    }

    public function setTitle($title = null) {
        if (is_null($title) || ($title == "")) return false;
        settype($title, "string");
        $this->title = $title;
        return true;
    }

    public function setThumbnail($thumbnail = null) {
        if (is_null($thumbnail) || ($thumbnail == "")) return false;
        settype($thumbnail, "string");
        $this->thumbnail = $thumbnail;
        return true;
    }

    public function setDescription($description = null) {
        if (is_null($description) || ($description == "")) return false;
        settype($description, "string");
        $this->description = $description;
        return true;
    }

    public function refreshImages() {
        global $globaldbh;

        // Get the images from this album's folder
        $imagefiles = glob(ALBUMFOLDER . $this->getFolderName() . "*.[jJpPgG][pPeEiI][gGeEfF]*");
        // Remove existing images from the DB if file no longer exists
        $images = Image::getImagesForAlbum($this->getID());
        foreach ( $images as $index => $image ) {
            $albumfile = ALBUMFOLDER . $this->getFolderName() . $image->getFileName();
            if ( !in_array($albumfile, $imagefiles) ) {
                if ( $image->getFileName() == $this->getThumbnail ) {
                    $this->setThumbnail("");
                    $this->save();
                }
                $image->delete();
            } else {
                // If this image already exists,
                // delete it from the imagefiles list so we only
                // create newly identified images in the next step
                array_splice($imagefiles, array_search($albumfile, $imagefiles), 1);
            }
        }
        // Add new images
        foreach ( $imagefiles as $imagefile ) {
            $imagefile = basename($imagefile);
            $image = new Image();
            $image->setAlbumID($this->getID());
            $image->setAlbumFolder($this->getFolderName());
            $image->setFileName($imagefile);
            $image->setTitle(substr($imagefile, 0, strrpos($imagefile, ".")));
            $image->save();
        }
    }

    public static function refreshAlbums() {
        global $globaldbh;

        // Get the folders inside ALBUMFOLDER
        $folders = glob(ALBUMFOLDER . "*", GLOB_ONLYDIR|GLOB_MARK);
        // Remove existing albums from DB if folder doesn't exist
        $albums = Album::getList();
        foreach ( $albums as $index => $album ) {
            $albumfolder = ALBUMFOLDER . $album->getFolderName();
            if ( !in_array($albumfolder, $folders) ) {
                $album->delete();
            } else {
                // If this album has a folder that exists,
                // delete it from the folder list so we only
                // create newly identified folders in the next step
                array_splice($folders, array_search(ALBUMFOLDER . $album->getFolderName(), $folders), 1);
            }
        }
        // Add albums for new folders
        foreach ( $folders as $folder ) {
            $folder = substr($folder, strlen(ALBUMFOLDER));
            $album = new Album();
            $album->setFolderName($folder);
            $album->setTitle(substr($folder, 0, -1));
            $album->save();
        }
        // Refresh images for all albums
        $albums = Album::getList();
        foreach ( $albums as $album ) {
            $album->refreshImages();
        }
    }

    public static function getList() {
        global $globaldbh;

        $query = "SELECT id FROM " . AppDB::TABLE_ALBUMS . " ORDER BY title";
        $sth = $globaldbh->prepare($query);
        $sth->execute();
        $thelist = array();
        while ( $row = $sth->fetch(PDO::FETCH_ASSOC) ) {
            $thelist[] = new Album($row['id']);
        }
        return $thelist;
    }

    public function jsonSerialize() {
        return [
            'id' => $this->getID(),
            'foldername' => $this->getFolderName(),
            'thumbnail' => $this->getThumbnail(),
            'thumburl' => ($this->getThumbnail() == "") ? "graphics/no-image-available_thm.gif" : THUMBNAILFOLDER . $this->getFolderName() . $this->getThumbnail(),
            'title' => $this->getTitle(),
            'description' => $this->getDescription(),
            'createtime' => $this->getCreateTime(),
            'images' => Image::getImagesForAlbum($this->getID())
        ];
    }

    public function delete() {
        global $globaldbh;

        $query = "DELETE FROM " . AppDB::TABLE_ALBUMS . " WHERE id=:id";
        $sth = $globaldbh->prepare($query);
        $sth->bindValue(":id", (int) $this->getID(), PDO::PARAM_INT);
        $sth->execute();
        $this->setID(0);
        $thumbnailfolder = THUMBNAILFOLDER . $this->getFolderName();
        if ( is_dir($thumbnailfolder) ) {
            unlink($thumbnailfolder . "*");
            rmdir($thumbnailfolder);
        }
    }

    public function save() {
        global $globaldbh;

        $query = "INSERT INTO " . AppDB::TABLE_ALBUMS . " ";
        $query .= "(id, foldername, title, thumbnail, description, createtime) ";
        $query .= "VALUES(NULL, :foldername, :title, :thumbnail, :description, NOW()) ";
        $query .= "ON DUPLICATE KEY UPDATE ";
        $query .= "foldername=:foldername, title=:title, thumbnail=:thumbnail, description=:description";
        $sth = $globaldbh->prepare($query);
        $sth->bindValue(":id", (int) $this->getID(), PDO::PARAM_INT);
        $sth->bindValue(":foldername", $this->getFolderName(), PDO::PARAM_STR);
        $sth->bindValue(":title", $this->getTitle(), PDO::PARAM_STR);
        $sth->bindValue(":thumbnail", $this->getThumbnail(), PDO::PARAM_STR);
        $sth->bindValue(":description", $this->getDescription(), PDO::PARAM_STR);
        $sth->execute();
        if ( $this->getID() == 0 ) {
            $this->setID($globaldbh->lastInsertId());
            mkdir(THUMBNAILFOLDER . $this->getFolderName());
        }
    }

    function __construct($reqid = 0) {
        global $globaldbh;
        
        $reqid = intval($reqid);
        $query = "SELECT id, foldername, title, thumbnail, description, createtime " .
                 "FROM " . AppDB::TABLE_ALBUMS . " WHERE id=:id";
        $sth = $globaldbh->prepare($query);
        $sth->bindValue(":id", $reqid, PDO::PARAM_INT);
        $sth->execute();
        if ( $row = $sth->fetch(PDO::FETCH_ASSOC) ) {
            $this->setID($row['id']);
            $this->setFolderName($row['foldername']);
            $this->setTitle($row['title']);
            $this->setThumbnail($row['thumbnail']);
            $this->setDescription($row['description']);
            $this->createtime = $row['createtime'];
        }
    }
}

// vim: set ts=4:sw=4
