using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using VisimBox;
using VisimBox.Scene;

namespace VisimBuilder
{

    public partial class SceneBrowser : UserControl
    {
        SceneRoot sceneroot;

        public delegate void SelectNodeCallback(Node node);
        public event SelectNodeCallback NodeSelected;

        protected MainBuilderForm MainForm;

        public SceneBrowser()
        {
            InitializeComponent();
        }

        public void Init(MainBuilderForm mainform)
        {
            MainForm = mainform;
            MainForm.SelectedNodeChanged += new MainBuilderForm.NodeChangedCallback(MainForm_SelectedNodeChanged);
        }

        void MainForm_SelectedNodeChanged()
        {
            if (MainForm.SelectedNode == null)
                return;

            SelectSceneNode(MainForm.SelectedNode, true);
        }

        public void UpdateScene()
        {
            sceneroot = VisimEngine.Instance.MainScene;

            TreeNode main = new VSTreeNode("Scene root", sceneroot);

            treeScene.Nodes.Clear();

            treeScene.Nodes.Add(main);
            GetNodes(main, sceneroot);
        }

        protected void GetNodes(TreeNode main, Node scene)
        {
            foreach (var nodes in scene)
            {
                TreeNode tn = new VSTreeNode(nodes.Name, nodes);
                main.Nodes.Add(tn);
                GetNodes(tn, nodes);
            }

        }

        protected void SelectNode()
        {
            VSTreeNode tn = (VSTreeNode)treeScene.SelectedNode;
            if (tn == null)
                return;

            MainForm.SelectNode(tn.myNode, true);
            if (NodeSelected != null)
                NodeSelected(tn.myNode);
        }

        private void buttonSelect_Click(object sender, EventArgs e)
        {
            SelectNode();
        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            UpdateScene();
        }

        private void buttonDelete_Click(object sender, EventArgs e)
        {
            VSTreeNode tn = (VSTreeNode)treeScene.SelectedNode;
            if (tn == null)
                return;
            if (tn.myNode == MainForm.Scene)
            {
                MessageBox.Show("Can't delete whole scene, use new scene function!");
                return;
            }
            if (MessageBox.Show("Delete node " + tn.myNode.FullName + "and all it's children?", "Node deleting", MessageBoxButtons.YesNo) != DialogResult.Yes)
                return;

            if (MainForm.SelectedNode == tn.myNode)
                MainForm.SelectNode(null, false);

            treeScene.SelectedNode = treeScene.SelectedNode.Parent;

            if (tn.myNode.Parent != null)
            {
                tn.myNode.Parent.RemoveNode(tn.myNode);                
            }

            tn.myNode.Dispose();
            UpdateScene();
        }

        private void buttonCopy_Click(object sender, EventArgs e)
        {
            VSTreeNode tn = (VSTreeNode)treeScene.SelectedNode;
            if (tn == null)
                return;
            MainForm.CreateNodeCopy(tn.myNode);
            UpdateScene();
        }

        private void buttonLink_Click(object sender, EventArgs e)
        {
            VSTreeNode tn = (VSTreeNode)treeScene.SelectedNode;
            if (tn == null)
                return;
            MainForm.LinkNode(tn.myNode);
        }

        private void searchButton_Click(object sender, EventArgs e)
        {            
            SearchNode();
        }

        private void SearchBoxKeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
                SearchNode();
        }

        private void SearchNode()
        {        
            string searchtext = textBoxSearch.Text;

            Node node = MainForm.Scene.SearchChild(searchtext);

            if (node == null)
            {
                UpdateScene();

                node = MainForm.Scene.SearchChild(searchtext);

                if (node == null)
                {
                    MessageBox.Show("Not found!");
                    return;
                }
            }

            SelectSceneNode(node);
        }

        private void SelectSceneNode(Node node, bool dorefreshonnotfound = false)
        {
            VSTreeNode vst = SearchForNode(treeScene.SelectedNode, node);

            if (vst == null)
            {
                vst = SearchForNode(treeScene.TopNode, node);
            }

            if (vst == null)
            {
                if (dorefreshonnotfound)
                {
                    UpdateScene();
                    SelectSceneNode(node, false);
                }
                else return;
            }
            
            treeScene.SelectedNode = vst;
        }

        private VSTreeNode SearchForNode(TreeNode node, Node scenenode)
        {
            if (node == null)
                return null;
            VSTreeNode vst = node as VSTreeNode;
            if (vst != null)
            {
                if (vst.myNode == scenenode)
                    return vst;
            }
            foreach (TreeNode tn in node.Nodes)
            {
                VSTreeNode rval = SearchForNode(tn, scenenode);
                if (rval != null)
                    return rval;
            }
            return null;
        }

        private void buttonlookat_Click(object sender, EventArgs e)
        {
            VSTreeNode tn = (VSTreeNode)treeScene.SelectedNode;
            if (tn == null)
                return;

            MainForm.LookAtObject(tn.myNode);

        }

        private void buttonteleport_Click(object sender, EventArgs e)
        {
            VSTreeNode tn = (VSTreeNode)treeScene.SelectedNode;
            if (tn == null)
                return;

            MainForm.TeleportToObject(tn.myNode);
        }
    }

    public class VSTreeNode : TreeNode
    {
        public Node myNode;

        public VSTreeNode(string name, Node val)
            : base(name)
        {
            myNode = val;
        }
    }

}
