<?php
/**
 * View for edit photos page
 *
 * This file is part of Zoph.
 *
 * Zoph is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Zoph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with Zoph; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @package Zoph
 * @author Jeroen Roos
 */

namespace photos\view;

use album;
use category;
use conf\conf;
use organizerException;
use person;
use photo;
use photo\collection as photoCollection;
use photo\people as photoPeople;
use place;
use rating;
use search;
use template\block;
use template\fieldset;
use template\form;
use template\template;
use user;
use web\request;

/**
 * This view displays the "photos" page in edit mode
 */
class edit extends view {
    /**
     * Output view
     */
    public function view() : block {
        $clean = array(
            '/_crumb=\d+&?/',
            '/_action=\w+&?/'
        );
        $qs = $this->request->cleanQueryString($clean);
        if (empty($qs)) {
             $search = new search();
             $search->setSearchURL($this->request);
             $qs = urldecode($search->getSearchQS());
        }

        $actionlinks=array(
            translate("return") => "photos.php?" .  $qs
        );

        $tpl = new block("editPhotos", array(
            "title"         => $this->getTitle(bar: true),
            "actionlinks"   => $actionlinks,
            "pager"         => $this->params->getPager()
        ));

        if (!empty($this->display)) {
            $tpl->addBlock($this->buildForm());
        } else {
            $tpl->addBlock(new block("message", array(
                "class" => "error",
                "title" => translate("No photos found"),
                "text"  => translate("No photos were found matching your search criteria.")
            )));
        }
        return $tpl;
    }

    /**
     * Build form
     * @return template\form form for edit photos
     */
    private function buildForm() : form {
        $form = new form("editPhotosForm");
        $form->addHiddenFields($this->request->getRequestVars(), $this->getIgnoredFields());
        $form->addBlock($this->buildAllPhotosFieldset());

        foreach ($this->display as $photo) {
            $form->addBlock($this->buildPhotoFieldset($photo));

        }

        return $form;
    }

    /**
     * Get array of ignored fields
     * Returns an array of fields to ignore when building the hidden fields of the form
     * the hidden fields are used to pass information about the original request to the next
     * page, but not all fields are necessary, this function creates a list of all fields
     * that can be ignored.
     * @return array ignored fields
     */
    private function getIgnoredFields() : array {
        $ignore = array(
            '_action',
            '_overwrite',
            '__location_id__all',
            '_rating__all',
            '_album__all',
            '_category__all',
            'PHPSESSID',
            '_crumb'
        );
        foreach ($this->display as $photo) {
            $photo_id = $photo->getId();
            $ignore[] = "__photo_id__$photo_id";
            $ignore[] = "__location_id__$photo_id";
            $ignore[] = "__photographer_id__$photo_id";
            $ignore[] = "__title__$photo_id";
            $ignore[] = "__description__$photo_id";
            $ignore[] = "_rating__$photo_id";
            $ignore[] = "_album__$photo_id";
            $ignore[] = "_remove_album__$photo_id";
            $ignore[] = "_category__$photo_id";
            $ignore[] = "_remove_category__$photo_id";
            $ignore[] = "_remove_person__$photo_id";
            $ignore[] = "_person__" . $photo_id;
            $ignore[] = "_deg__$photo_id";
            $ignore[] = "_action__$photo_id";
        }
        return $ignore;
    }

    /**
     * Create fieldset for the "all photos" part of the form
     * @return template\fieldset template containing subform
     */
    private function buildAllPhotosFieldset() : fieldset {
        $fs = new fieldset("formFieldset", array(
            "class"  => "editphotos",
            "legend" => translate("All photos")
        ));

        $fsAlbum = new fieldset("formFieldset", array(
            "class" =>  "multiple"
        ));
        $fsAlbum->addBlock(album::createDropdown("_album__all[0]"));

        $fsCategory = new fieldset("formFieldset", array(
            "class" =>  "multiple"
        ));
        $fsCategory->addBlock(category::createDropdown("_category__all[0]"));

        $fsPerson = new fieldset("formFieldset", array(
            "class" =>  "multiple"
        ));
        $fsPerson->addBlock(person::createDropdown("_person__all[0]"));

        $fs->addInputCheckBox("_overwrite", false, translate("overwrite values below", 0));
        $fs->addBreak();
        $fs->addBlocks(array(
            template::createInputDate("__date__all", "", translate("date")),
            template::createInputTime("__time__all", "", translate("time")),
            form::createLabel("location_id__all", translate("location")),
            place::createDropdown("__location_id__all"),
            form::createLabel("photographer__all", translate("photographer")),
            person::createDropdown("__photographer_id__all"),
            form::createLabel("rating__all", translate("rating")),
            rating::createDropdown("_rating__all"),
            form::createLabel("album__all", translate("album")),
            $fsAlbum,
            form::createLabel("category__all", translate("category")),
            $fsCategory,
            form::createLabel("person__all", translate("person")),
            $fsPerson
        ));

        return $fs;
    }

    /**
     * Create fieldset for a specific photo in the form
     * @param photo photo to build fieldset for
     * @return template\fieldset template containing subform
     */
    private function buildPhotoFieldset(photo $photo) : block {
        $user = user::getCurrent();
        $photo->lookup();
        $id = $photo->getId();

        $fs= new block("editPhotosFieldset", array(
            "name"      => $photo->getName(),
            "photoId"   => $photo->getId(),
            "thumb"     => $photo->getThumbnailLink()
        ));

        $fsAlbum = new fieldset("formFieldset", array(
            "class" =>  "multiple"
        ));
        $fsAlbum->addBlock(album::createDropdown("_album__" . $id . "[0]"));
        $fsCategory = new fieldset("formFieldset", array(
            "class" =>  "multiple"
        ));
        $fsCategory->addBlock(category::createDropdown("_category__" . $id . "[0]"));

        $id = (int) $photo->getId();
        $fsPhoto = new fieldset("formFieldset", array(
            "class" => "editphotos-fields",
        ));
        $fsPhoto->addBlocks(array(
            template::createInput("__title__" . $id, $photo->get("title"), 64, translate("title"), 30),
            template::createInputDate("__date__" . $id, $photo->get("date"), translate("date")),
            template::createInputTime("__time__" . $id, $photo->get("time"), translate("time")),
            form::createLabel("location_id__" . $id, translate("location")),
            place::createDropdown("__location_id__". $id, $photo->get("location_id")),
            form::createLabel("photographer__" . $id, translate("photographer")),
            person::createDropdown("__photographer_id__" . $id, $photo->get("photographer_id")),
        ));

        if (conf::get("feature.rating")) {
            $rating = $photo->getRatingForUser($user);
            $fsPhoto->addBlocks(array(
                form::createLabel("rating__" . $id, translate("rating")),
                rating::createDropdown("_rating__" . $id, $rating)
            ));
        }

        $people = new photoPeople($photo);
        $fsPhoto->addBlocks(array(
            $this->createOrganizerList("album", $photo->getAlbums($user), $photo),
            $this->createOrganizerList("category", $photo->getCategories($user), $photo),
            $this->createOrganizerList("person", $people->getAll(), $photo),
        ));
        $fs->addBlock($fsPhoto);
        return $fs;
    }

    /**
     * Create fieldset for an organizer
     * @param string album|category|person
     * @param array array of albums/categories/persons
     * @param photo photo
     * @return block fieldset
     */
    private function createOrganizerList(string $type, array $organizers, photo $photo) : block {
        switch ($type) {
            case "album":
                $label = "albums";
                $dropdown = album::createDropdown("_album__" . $photo->getId() . "[0]");
                break;
            case "category":
                $label = "categories";
                $dropdown = category::createDropdown("_category__" . $photo->getId() . "[0]");
                break;
            case "person":
                $label = "people";
                $dropdown = person::createDropdown("_person__" . $photo->getId() . "[0]");
                break;
            default:
                throw new organizerException("Unknown organizer: " . e($type));
                break;
        }
        return new block("organizerListFieldset", array(
            "type"          => $type,
            "label"         => translate($label),
            "photo"         => $photo,
            "organizers"    => $organizers,
            "msg_not"       => "",
            "dropdown"      => $dropdown
        ));
    }

    /**
     * Create title for this page
     * title for the window and title bar can differ slightly
     * @param bool bar false: (default) build for window (HTML <title> tag)| true: build for title bar
     * @return string title text
     */
    public function getTitle($bar=false) : string {
        $cells = $this->params->rows * $this->params->cols;
        $offset = $this->params->offset;

        if (!empty($this->display)) {
            $photoCount=sizeof($this->photos);
            $pageCount = ceil($photoCount / $cells);
            $currentPage = floor($offset / $cells) + 1;

            $num = min($cells, sizeof($this->display));
            $title = sprintf(translate("Edit Photos (Page %s/%s)", 0), $currentPage, $pageCount);
            $titleBar = sprintf(translate("edit photos %s to %s of %s"),
                ($offset + 1), ($offset + $num), $photoCount);
        } else {
            $title = translate("No Photos Found");
            $titleBar = translate("edit photos");
        }
        if ($bar) {
            return $titleBar;
        } else {
            return $title;
        }
    }
}
