<?php
namespace Grav\Plugin\Breadcrumbs;

use Grav\Common\Grav;

class Breadcrumbs
{
    /**
     * @var array
     */
    protected $breadcrumbs;
    /**
     * @var array
     */
    protected $config;

    /**
     * @param $config
     */
    public function __construct($config)
    {
        $this->config = $config;
    }

    /**
     * Return an array of breadcrumbs for the current page.
     *
     * @return array An array of breadcrumbs.
     */
    public function get()
    {
        // If the breadcrumbs have not yet been generated...
        if (!$this->breadcrumbs) {
            // Generate them now.
            $this->build();
        }

        return $this->breadcrumbs;
    }

    /**
     * Build the array of breadcrumbs.
     *
     * The array is generated by starting at the current page and then climbing
     * the hierarchy until the root is reached. The resulting crumbs are then
     * stored in the $breadcrumbs instance variable.
     *
     * @internal
     */
    protected function build()
    {
        // Used to hold the breadcrumbs as they are being generated.
        $hierarchy = array();

        $grav = Grav::instance();
        $current = $grav['page'];

        // If the page is not routable...
        if (!$current) {
            // Set up an empty array of crumbs.
            $this->breadcrumbs = array();
            return;
        }

        // If we are not at the root page...
        if (!$current->root()) {

            // If we are configured to include the current page...
            if ($this->config['include_current']) {
                // Place the current page in the hierarchy.
                $hierarchy[$current->url()] = $current;
            }

            $current = $current->parent();

            // As long as $current does not contain the root page...
            while ($current && !$current->root()) {
                // Get the frontmatter of the page.
                $header = $current->header();

                // Assume we may descend unless otherwise told.
                $may_descend = true;

                // If the frontmatter contains a value for $may_descend...
                if(isset(
                    $header->breadcrumbs,
                    $header->breadcrumbs['may_descend']
                )) {
                    // Get that value.
                    $may_descend = $header->breadcrumbs['may_descend'];
                }

                // Then, if breadcrumbs should stop at this page...
                if ($may_descend === false) {
                    // Empty the $hierarchy.
                    $hierarchy = [];
                }

                // Place the current page in the hierarchy.
                $hierarchy[$current->url()] = $current;

                // Get the parent of the current page.
                $current = $current->parent();
            }
        }

        // If we are configured to include the home page...
        if ($this->config['include_home']) {
            // Get the home page.
            $home = $grav['pages']->dispatch('/');

            // If the home page isn't already in the hierarchy...
            if ($home && !array_key_exists($home->url(), $hierarchy)) {
                // Place the home page in the hierarchy.
                $hierarchy[] = $home;
            }
        }

        // Reverse the array of breadcrumbs, so that they are in descending
        // order.
        $this->breadcrumbs = array_reverse($hierarchy);
    }
}
