public SimpleTokenNode(IMathBookFieldNode node) : base(node.direction == MathBookField.Direction.Output ? CreatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Multi, typeof(float)) : null
                                                               , node.direction == MathBookField.Direction.Input ? CreatePort(Orientation.Horizontal, Direction.Output, Port.Capacity.Multi, typeof(float)) : null)
        {
            modelNode = node;
            userData  = node;
            if (input != null)
            {
                input.userData = node;
            }
            if (output != null)
            {
                output.userData = node;
            }

            UpdateData();
            node.changed += e => UpdateData();

            RegisterCallback <AttachToPanelEvent>(e => UpdateData());
        }
        public GraphElement CreateNode(MathNode mathNode)
        {
            if (mathNode is MathOperator)
            {
                MathOperator add = mathNode as MathOperator;

                return(CreateMathNode(mathNode, mathNode.name, add.m_Position, 2, 1));
            }
            else if (mathNode is MathStackNode)
            {
                MathStackNode mathStackNode = mathNode as MathStackNode;

                return(CreateStackNode(mathStackNode, mathStackNode.m_Position));
            }
            else if (mathNode is MathFunction)
            {
                MathFunction fn = mathNode as MathFunction;

                Debug.Assert(fn.parameterCount == fn.parameterNames.Length);

                Node nodeUI = CreateMathNode(mathNode, mathNode.name, mathNode.m_Position, fn.parameterNames.Length, 1);

                for (int i = 0; i < fn.parameterNames.Length; ++i)
                {
                    (nodeUI.inputContainer.ElementAt(i) as Port).portName = fn.parameterNames[i];
                }

                return(nodeUI);
            }
            else if (mathNode is IMathBookFieldNode)
            {
                IMathBookFieldNode mathBookFieldNode = mathNode as IMathBookFieldNode;
                SimpleTokenNode    tokenNode         = new SimpleTokenNode(mathBookFieldNode);

                tokenNode.SetPosition(new Rect(mathNode.m_Position, Vector2.zero));
                tokenNode.RefreshPorts();
                tokenNode.visible = true;

                return(tokenNode);
            }
            else if (mathNode is MathConstant)
            {
                MathConstant mathConstant = mathNode as MathConstant;

                Node nodeUI = CreateMathNode(
                    mathNode,
                    mathConstant.name,
                    mathConstant.m_Position, 0, 1);

                var field = new DoubleField()
                {
                    value = mathConstant.m_Value
                };
                field.SetEnabled(!(mathConstant is PIConstant));
                field.RegisterValueChangedCallback(evt => mathConstant.m_Value = (float)evt.newValue);
                nodeUI.inputContainer.Add(field);
                nodeUI.RefreshExpandedState();
                return(nodeUI);
            }
            else if (mathNode is MathResult)
            {
                MathResult mathResult = mathNode as MathResult;

                Node nodeUI = CreateMathNode(
                    mathNode,
                    "Result",
                    mathResult.m_Position, 1, 0);

                nodeUI.inputContainer.Add(new Button(() => Debug.Log(mathResult.Evaluate()))
                {
                    text = "Print result"
                });

                return(nodeUI);
            }
            else if (mathNode is MathGroupNode)
            {
                MathGroupNode mathGroupNode = mathNode as MathGroupNode;

                if (mathGroupNode.m_IsScope)
                {
                    return(CreateScope(mathGroupNode,
                                       mathGroupNode.m_Position));
                }
                else
                {
                    return(CreateGroupNode(mathGroupNode,
                                           mathGroupNode.m_Title,
                                           mathGroupNode.m_Position));
                }
            }

            return(null);
        }