/******************************************************************************
 *
 * Copyright (c) 2017, the Perspective Authors.
 *
 * This file is part of the Perspective library, distributed under the terms of
 * the Apache License 2.0.  The full license can be found in the LICENSE file.
 *
 */

#pragma once
#include <perspective/first.h>
#include <perspective/exports.h>
#include <perspective/config.h>
#include <perspective/gnode_state.h>
#include <perspective/traversal.h>

namespace perspective {

PERSPECTIVE_EXPORT void notify_sparse_tree_common(
    std::shared_ptr<t_data_table> strands,
    std::shared_ptr<t_data_table> strand_deltas, std::shared_ptr<t_stree> tree,
    std::shared_ptr<t_traversal> traversal, bool process_traversal,
    const std::vector<t_aggspec>& aggregates,
    const std::vector<std::pair<std::string, std::string>>& tree_sortby,
    const std::vector<t_sortspec>& ctx_sortby, const t_gstate& gstate,
    const t_data_table& expression_master_table);

PERSPECTIVE_EXPORT void notify_sparse_tree(std::shared_ptr<t_stree> tree,
    std::shared_ptr<t_traversal> traversal, bool process_traversal,
    const std::vector<t_aggspec>& aggregates,
    const std::vector<std::pair<std::string, std::string>>& tree_sortby,
    const std::vector<t_sortspec>& ctx_sortby, const t_data_table& flattened,
    const t_data_table& delta, const t_data_table& prev,
    const t_data_table& current, const t_data_table& transitions,
    const t_data_table& existed, const t_config& config, const t_gstate& gstate,
    const t_data_table& expression_master_table);

PERSPECTIVE_EXPORT void notify_sparse_tree(std::shared_ptr<t_stree> tree,
    std::shared_ptr<t_traversal> traversal, bool process_traversal,
    const std::vector<t_aggspec>& aggregates,
    const std::vector<std::pair<std::string, std::string>>& tree_sortby,
    const std::vector<t_sortspec>& ctx_sortby, const t_data_table& flattened,
    const t_config& config, const t_gstate& gstate,
    const t_data_table& expression_master_table);

template <typename CONTEXT_T>
void
ctx_expand_path(CONTEXT_T& ctx, t_header header, std::shared_ptr<t_stree> tree,
    std::shared_ptr<t_traversal> traversal,
    const std::vector<t_tscalar>& path) {
    t_index root = 0;
    t_index bidx = 0;

    for (int j = 0, loop_end = path.size(); j < loop_end; j++) {
        const t_tscalar& datum = path[j];
        root = tree->resolve_child(root, datum);

        if (root < 0) {
            break;
        }

        t_index tvidx = traversal->tree_index_lookup(root, bidx);

        bidx = tvidx;
        ctx.open(header, tvidx);
    }
}

template <typename CONTEXT_T>
void
ctx_set_expansion_state(CONTEXT_T& ctx, t_header header,
    std::shared_ptr<t_stree> tree, std::shared_ptr<t_traversal> traversal,
    const std::vector<t_path>& paths) {
    for (int i = 0, loop_end = paths.size(); i < loop_end; i++) {
        const t_path& path = paths[i];
        ctx_expand_path(ctx, header, tree, traversal, path.m_path);
    }
}

PERSPECTIVE_EXPORT std::vector<t_path> ctx_get_expansion_state(
    std::shared_ptr<const t_stree> tree,
    std::shared_ptr<const t_traversal> traversal);

PERSPECTIVE_EXPORT std::vector<t_tscalar> ctx_get_path(
    std::shared_ptr<const t_stree> tree,
    std::shared_ptr<const t_traversal> traversal, t_index idx);

PERSPECTIVE_EXPORT std::vector<t_ftreenode> ctx_get_flattened_tree(t_index idx,
    t_depth stop_depth, t_traversal& trav, const t_config& config,
    const std::vector<t_sortspec>& sortby);

} // end namespace perspective
