private static IPanelGroupElement Deserialize(DynamicPanelsCanvas canvas, ISerializedElement element)
        {
            if (element == null)
            {
                return(null);
            }

            if (element is SerializedDummyPanel)
            {
                return(canvas.Internal.DummyPanel);
            }

            if (element is SerializedPanel)
            {
                SerializedPanel serializedPanel = (SerializedPanel)element;
                Panel           panel           = null;

                SerializedPanelTab[] tabs = serializedPanel.tabs;
                for (int i = 0; i < tabs.Length; i++)
                {
                    PanelTab tab;
                    if (!PanelNotificationCenter.TryGetTab(tabs[i].id, out tab))
                    {
                        continue;
                    }

                    if (panel == null)
                    {
                        panel = tab.Detach();
                        canvas.UnanchoredPanelGroup.AddElement(panel);
                    }
                    else
                    {
                        panel.AddTab(tab);
                    }

                    //if( tab != null )
                    //{
                    //	tab.MinSize = tabs[i].minSize;
                    //	tab.Label = tabs[i].label;
                    //}
                }

                if (panel != null)
                {
                    if (serializedPanel.activeTab < tabs.Length)
                    {
                        int activeTabIndex = panel.GetTabIndex(tabs[serializedPanel.activeTab].id);
                        if (activeTabIndex >= 0)
                        {
                            panel.ActiveTab = activeTabIndex;
                        }
                    }

                    if (serializedPanel is SerializedUnanchoredPanel)
                    {
                        SerializedUnanchoredPanel unanchoredPanel = (SerializedUnanchoredPanel)serializedPanel;
                        panel.RectTransform.anchoredPosition = unanchoredPanel.position;
                        panel.gameObject.SetActive(unanchoredPanel.active);
                    }

                    panel.FloatingSize = serializedPanel.floatingSize;
                }

                return(panel);
            }

            if (element is SerializedPanelGroup)
            {
                SerializedPanelGroup serializedPanelGroup = (SerializedPanelGroup)element;
                ISerializedElement[] children             = serializedPanelGroup.children;
                if (children == null || children.Length == 0)
                {
                    return(null);
                }

                PanelGroup panelGroup = new PanelGroup(canvas, serializedPanelGroup.horizontal ? Direction.Right : Direction.Top);
                for (int i = 0; i < children.Length; i++)
                {
                    if (children[i] == null)
                    {
                        continue;
                    }

                    IPanelGroupElement childElement = Deserialize(canvas, children[i]);
                    if (childElement != null)
                    {
                        panelGroup.AddElement(childElement);
                        sizesHolder.Add(new GroupElementSizeHolder(childElement, children[i].size));
                    }
                }

                if (panelGroup.Count > 0)
                {
                    return(panelGroup);
                }
            }

            return(null);
        }
        public static void DeserializeCanvasFromArray(DynamicPanelsCanvas canvas, byte[] data)
        {
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                Debug.LogError("Can deserialize in Play mode only!");
                return;
            }
#endif

            if (data == null || data.Length == 0)
            {
                Debug.LogError("Data is null!");
                return;
            }

            SerializedCanvas serializedCanvas;
            BinaryFormatter  formatter = new BinaryFormatter();
            using (MemoryStream stream = new MemoryStream(data))
            {
                serializedCanvas = formatter.Deserialize(stream) as SerializedCanvas;
            }

            if (serializedCanvas == null)
            {
                return;
            }

            sizesHolder.Clear();
            canvas.LeaveFreeSpace = serializedCanvas.useFreeSpace;

            if (serializedCanvas.rootPanelGroup != null)
            {
                PanelGroup           rootPanelGroup = canvas.RootPanelGroup;
                ISerializedElement[] children       = serializedCanvas.rootPanelGroup.children;
                for (int i = children.Length - 1; i >= 0; i--)
                {
                    IPanelGroupElement element = Deserialize(canvas, children[i]);
                    if (element != null)
                    {
                        if (rootPanelGroup.Count == 0)
                        {
                            rootPanelGroup.AddElement(element);
                        }
                        else
                        {
                            rootPanelGroup.AddElementBefore(rootPanelGroup[0], element);
                        }

                        sizesHolder.Insert(0, new GroupElementSizeHolder(element, children[i].size));
                    }
                }
            }

            if (sizesHolder.Count > 0)
            {
                canvas.ForceRebuildLayoutImmediate();

                for (int i = 0; i < sizesHolder.Count; i++)
                {
                    sizesHolder[i].element.ResizeTo(sizesHolder[i].size, Direction.Right, Direction.Top);
                }
            }

            if (serializedCanvas.unanchoredPanelGroup != null)
            {
                ISerializedElement[] children = serializedCanvas.unanchoredPanelGroup.children;
                for (int i = 0; i < children.Length; i++)
                {
                    SerializedUnanchoredPanel unanchoredPanel = children[i] as SerializedUnanchoredPanel;
                    if (unanchoredPanel != null)
                    {
                        Panel panel = Deserialize(canvas, unanchoredPanel) as Panel;
                        if (panel != null)
                        {
                            panel.Detach();
                            canvas.UnanchoredPanelGroup.RestrictPanelToBounds(panel);
                        }
                    }
                }
            }

            for (int i = 0; i < canvas.UnanchoredPanelGroup.Count; i++)
            {
                Panel panel = canvas.UnanchoredPanelGroup[i] as Panel;
                if (panel != null)
                {
                    panel.RectTransform.SetAsLastSibling();
                }
            }

            canvas.gameObject.SetActive(serializedCanvas.active);
        }