using System;
using System.Collections.Generic;
using System.Web.UI;
using C1.Web.Wijmo.Controls.C1TreeView;

namespace TreeView_Sample
{
    public partial class _Default : Page
    {
        // Dictionary persisted in ViewState so it survives postbacks
        private Dictionary<string, int> NodeIndexMap
        {
            get
            {
                if (ViewState["NodeIndexMap"] == null)
                    ViewState["NodeIndexMap"] = new Dictionary<string, int>();
                return (Dictionary<string, int>)ViewState["NodeIndexMap"];
            }
            set { ViewState["NodeIndexMap"] = value; }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                BuildNodeIndexMap();
            }
        }

        /// <summary>
        /// Walks the tree once and maps every node's Value -> index (BFS order)
        /// BFS order:
        /// Index 0: Node1
        /// Index 1: Node2
        /// Index 2: Node3
        /// Index 3: Node3.1
        /// Index 4: Node3.2  ← this is what we got
        /// Index 5: Node3.3
        /// Index 6: Node3.2.1
        /// 
        /// </summary>
        private void BuildNodeIndexMap()
        {
            var map = new Dictionary<string, int>();
            int index = 0;

            var queue = new Queue<C1TreeViewNode>();

            // seed the queue with root nodes, matching Enrique's BFS pattern
            foreach (C1TreeViewNode node in C1TreeView1.Nodes)
                queue.Enqueue(node);

            while (queue.Count != 0)
            {
                C1TreeViewNode node = queue.Dequeue();
                map[node.Value] = index++;

                foreach (C1TreeViewNode child in node.Nodes)
                    queue.Enqueue(child);
            }

            NodeIndexMap = map;
        }

        // O(1) lookup — replaces Enrique's FindNodeBreadthFirstSearch
        private C1TreeViewNode FindNodeByIndex(C1TreeView tree, int targetIndex)
        {
            var queue = new Queue<C1TreeViewNode>();

            foreach (C1TreeViewNode node in tree.Nodes)
                queue.Enqueue(node);

            while (queue.Count != 0)
            {
                C1TreeViewNode node = queue.Dequeue();

                if (NodeIndexMap.TryGetValue(node.Value, out int idx) && idx == targetIndex)
                    return node;

                foreach (C1TreeViewNode child in node.Nodes)
                    queue.Enqueue(child);
            }

            return null;
        }

        protected void btnFind_Click(object sender, EventArgs e)
        {
            // Example: find the node that was assigned index 4 at build time
            int targetIndex = 4;
            C1TreeViewNode found = FindNodeByIndex(C1TreeView1, targetIndex);

            lblResult.Text = found != null
                ? $"Found: Text='{found.Text}', Value='{found.Value}', Index={NodeIndexMap[found.Value]}"
                : "Node not found.";
        }
    }
}