#ifndef PASTELSYS_REDBLACKTREE_QUANTILE_HPP
#define PASTELSYS_REDBLACKTREE_QUANTILE_HPP
#include "pastel/sys/redblacktree/redblacktree_quantile.h"
namespace Pastel
{
    template <typename Settings, template <typename> class Customization>
    typename RedBlackTree<Settings, Customization>::ConstIterator
    quantile(
        const RedBlackTree<Settings, Customization>& tree,
        dreal alpha)
    {
        /*
       Let n = tree.size(), and
       f : ZZ --> RR: f(i) = (i + 0.5) / n.
       Then
       f(i) = alpha
       <=>
       f(i) n = alpha n
       <=>
       i + 0.5 = alpha n
       <=>
       i = alpha n - 0.5
       Since i is an integer, this equation may not have
       a solution. Therefore, we use the closest integer
       instead:
       i = round(alpha n - 0.5) = floor(alpha n)
       */
        integer searchIndex = std::floor(alpha * tree.size());
        if (searchIndex <= 0)
        {
            return tree.cbegin();
        }
        if (searchIndex >= tree.size() - 1)
        {
            return tree.clast();
        }
        using ConstIterator = 
            typename RedBlackTree<Settings, Customization>::ConstIterator;
        ConstIterator node = tree.croot();
        integer i = node.left().size();
        while (i != searchIndex)
        {
            ASSERT(!node.isSentinel());
            bool right = i < searchIndex;
            node = node.child(right);
            if (right)
            {
                i += node.left().size() + 1;
            }
            else
            {
                i -= node.right().size() + 1;
            }
        }
        return node;
    }
}
#endif