public void Serialize(object obj, Altaxo.Serialization.Xml.IXmlSerializationInfo info)
            {
                PlotItemCollection s = (PlotItemCollection)obj;

                info.CreateArray("PlotItems", s.Count);
                for (int i = 0; i < s.Count; i++)
                {
                    info.AddValue("PlotItem", s[i]);
                }
                info.CommitArray();

                info.AddValue("GroupStyles", s._styles);
            }
        /// <summary>
        /// Copy constructor. Clones (!) all the items in the list.
        /// </summary>
        /// <param name="owner">The new owner of the cloned list.</param>
        /// <param name="from">The list to clone all items from.</param>
        public PlotItemCollection(XYPlotLayer owner, PlotItemCollection from)
        {
            _parent    = owner;
            _styles    = new PlotGroupStyleCollection();
            _plotItems = new List <IGPlotItem>();


            // Clone all the items in the list.
            for (int i = 0; i < from.Count; i++)
            {
                Add((IGPlotItem)from[i].Clone()); // clone the items
            }
            // special way neccessary to handle plot groups
            this._styles = null == from._styles ? null : from._styles.Clone();
        }
        /// <summary>
        /// Prepare styles forward, but only up in the hierarchy.
        /// </summary>
        /// <param name="parentstyles">The parent group style collection.</param>
        /// <param name="layer">The plot layer.</param>
        protected void PrepareStylesForward_HierarchyUpOnly(PlotGroupStyleCollection parentstyles, IPlotArea layer)
        {
            bool transferFromParentStyles =
                parentstyles != null &&
                parentstyles.Count != 0 &&
                parentstyles.DistributeToChildGroups &&
                this._styles.InheritFromParentGroups;

            _styles.BeginPrepare();

            string thisname = Main.DocumentPath.GetPathString(this, int.MaxValue);

            System.Diagnostics.Debug.WriteLine(string.Format("{0}:Begin:PrepareFWHUO", thisname));
            if (transferFromParentStyles)
            {
                PlotGroupStyleCollection.TransferFromTo(parentstyles, _styles);
                System.Diagnostics.Debug.WriteLine(string.Format("{0}:Begin:PrepareFWHUO (transfer from parent style", thisname));
            }


            // now distibute the styles from the first item down to the last item
            int last = _plotItems.Count - 1;

            for (int i = 0; i <= last; i++)
            {
                IGPlotItem pi = _plotItems[i];
                if (pi is PlotItemCollection)
                {
                    PlotItemCollection pic = (PlotItemCollection)pi;
                    pic.PrepareStylesForward_HierarchyUpOnly(_styles, layer);
                    _styles.PrepareStepIfForeignSteppingFalse(((PlotItemCollection)pi)._styles);
                }
                else
                {
                    pi.PrepareStyles(_styles, layer);
                    _styles.PrepareStep();
                }
            }

            if (transferFromParentStyles)
            {
                PlotGroupStyleCollection.TransferFromTo(_styles, parentstyles);
                System.Diagnostics.Debug.WriteLine(string.Format("{0}:End:PrepareFWHUO (transfer back to parent style", thisname));
            }

            _styles.EndPrepare();
            System.Diagnostics.Debug.WriteLine(string.Format("{0}:End:PrepareFWHUO", thisname));
        }
        /// <summary>
        /// Apply styles, beginning at item 'pivotidx' in this collection, iterative backwards up and down the hierarchy.
        /// It stops at the first item of a collection here or down the hierarchy that do not inherit from it's parent collection.
        /// </summary>
        /// <param name="pivotidx">The index of the item where the application process starts.</param>
        /// <returns>The plot item collection where the process stops.</returns>
        protected PlotItemCollection ApplyStylesIterativeBackward(int pivotidx)
        {
            // if the pivot is lower than 0, we first distibute all changes to the first item and
            // then from the first item again down the line
            if (pivotidx > 0)
            {
                _styles.BeginApply();
                for (int i = pivotidx; i >= 0; i--)
                {
                    IGPlotItem pi = _plotItems[i];
                    if (pi is PlotItemCollection)
                    {
                        _styles.Step(-1);
                        PlotItemCollection pic = (PlotItemCollection)pi;
                        pic.ApplyStylesBackward_HierarchyUpOnly(_styles);
                    }
                    else
                    {
                        pi.ApplyStyles(_styles);
                        if (i > 0)
                        {
                            _styles.Step(-1);
                        }
                    }
                }
                _styles.EndApply();
            }


            // now use this styles to copy to the parent
            bool transferToParentStyles =
                ParentCollection != null &&
                ParentCollection._styles.Count != 0 &&
                ParentCollection._styles.DistributeToChildGroups &&
                this._styles.InheritFromParentGroups;

            PlotItemCollection rootCollection = this;

            if (transferToParentStyles)
            {
                PlotGroupStyleCollection.TransferFromTo(_styles, ParentCollection._styles);
                rootCollection = ParentCollection.ApplyStylesIterativeBackward(ParentCollection._styles.Count - 1);
            }

            return(rootCollection);
        }
            public object Deserialize(object o, Altaxo.Serialization.Xml.IXmlDeserializationInfo info, object parent)
            {
                PlotItemCollection s = null != o ? (PlotItemCollection)o : new PlotItemCollection();

                int count = info.OpenArray();

                IGPlotItem[] plotItems = new IGPlotItem[count];
                for (int i = 0; i < count; i++)
                {
                    s.Add((IGPlotItem)info.GetValue("PlotItem", s));
                }
                info.CloseArray(count);

                s._styles = (PlotGroupStyleCollection)info.GetValue("GroupStyles", s);

                return(s);
            }
        /// <summary>
        /// Distribute the changes made to the plotitem 'pivotitem' to all other items in the collection and if neccessary, also up and down the plot item tree.
        /// </summary>
        /// <param name="pivotitem">The plot item where changes to the plot item's styles were made.</param>
        public void DistributeChanges(IGPlotItem pivotitem)
        {
            int pivotidx = _plotItems.IndexOf(pivotitem);

            if (pivotidx < 0)
            {
                return;
            }

            // Distribute the changes backward to the first item
            PrepareStylesIterativeBackward(pivotidx, this.ParentLayer);
            PlotItemCollection rootCollection = ApplyStylesIterativeBackward(pivotidx);

            // now prepare and apply the styles forward normally beginning from the root collection
            // we can set the parent styles to null since rootCollection is the lowest collection that don't inherit from a lower group.
            rootCollection.PrepareStylesForward_HierarchyUpOnly(null, this.ParentLayer);
            rootCollection.ApplyStylesForward_HierarchyUpOnly(null);
        }
        /// <summary>
        /// Apply styles forward, but only up in the hierarchy.
        /// </summary>
        /// <param name="parentstyles">The parent group style collection.</param>
        protected void ApplyStylesForward_HierarchyUpOnly(PlotGroupStyleCollection parentstyles)
        {
            bool transferFromParentStyles =
                parentstyles != null &&
                parentstyles.Count != 0 &&
                parentstyles.DistributeToChildGroups &&
                this._styles.InheritFromParentGroups;

            if (transferFromParentStyles)
            {
                PlotGroupStyleCollection.TransferFromTo(parentstyles, _styles);
            }

            _styles.BeginApply();

            // now distibute the styles from the first item down to the last item
            int last = _plotItems.Count - 1;

            for (int i = 0; i <= last; i++)
            {
                IGPlotItem pi = _plotItems[i];
                if (pi is PlotItemCollection)
                {
                    PlotItemCollection pic = (PlotItemCollection)pi;
                    pic.ApplyStylesForward_HierarchyUpOnly(_styles);
                    _styles.StepIfForeignSteppingFalse(1, ((PlotItemCollection)pi)._styles);
                }
                else
                {
                    pi.ApplyStyles(_styles);
                    _styles.Step(1);
                }
            }
            _styles.EndApply();

            if (transferFromParentStyles)
            {
                PlotGroupStyleCollection.TransferFromToIfBothSteppingEnabled(_styles, parentstyles);
                parentstyles.SetAllToApplied(); // to indicate that we have applied this styles and so to enable stepping
            }
        }
            public object Deserialize(object o, Altaxo.Serialization.Xml.IXmlDeserializationInfo info, object parent)
            {
                PlotItemCollection s = null != o ? (PlotItemCollection)o : new PlotItemCollection();

                int count = info.OpenArray();

                IGPlotItem[] plotItems = new IGPlotItem[count];
                for (int i = 0; i < count; i++)
                {
                    plotItems[i] = (IGPlotItem)info.GetValue("PlotItem", s);
                }
                info.CloseArray(count);


                count = info.OpenArray(); // PlotGroups
                PGTrans[] plotGroups = new PGTrans[count];
                for (int i = 0; i < count; i++)
                {
                    plotGroups[i].PlotGroup = (PlotGroupMemento)info.GetValue(s);
                }
                info.CloseArray(count);

                // now assemble the new tree based collection based on the both fields

                for (int pix = 0; pix < plotItems.Length; pix++)
                {
                    // look if this plotItem is member of some group
                    int foundidx = -1;
                    for (int grx = 0; grx < plotGroups.Length; grx++)
                    {
                        if (Array.IndexOf <int>(plotGroups[grx].PlotGroup._plotItemIndices, pix) >= 0)
                        {
                            foundidx = grx;
                            break;
                        }
                    }
                    if (foundidx < 0) // if not found in some group, add the item directly
                    {
                        s.Add(plotItems[pix]);
                    }
                    else
                    {
                        if (plotGroups[foundidx].PlotItemCollection == null)
                        {
                            PlotItemCollection newColl = new PlotItemCollection();
                            plotGroups[foundidx].PlotItemCollection = newColl;
                            s.Add(plotGroups[foundidx].PlotItemCollection);
                            // now set the properties of this new collection
                            bool            serial = !plotGroups[foundidx].PlotGroup._concurrently;
                            IPlotGroupStyle curr   = null;
                            IPlotGroupStyle prev   = null;
                            if (0 != (plotGroups[foundidx].PlotGroup._plotGroupStyle & Version0PlotGroupStyle.Color))
                            {
                                curr = new ColorGroupStyle();
                                newColl.GroupStyles.Add(curr);
                            }
                            if (0 != (plotGroups[foundidx].PlotGroup._plotGroupStyle & Version0PlotGroupStyle.Line))
                            {
                                prev = curr;
                                curr = new LineStyleGroupStyle();
                                newColl.GroupStyles.Add(curr, serial ? (prev == null?null:prev.GetType()) : null);
                            }
                            if (0 != (plotGroups[foundidx].PlotGroup._plotGroupStyle & Version0PlotGroupStyle.Symbol))
                            {
                                prev = curr;
                                curr = new SymbolShapeStyleGroupStyle();
                                newColl.GroupStyles.Add(curr, serial ? (prev == null ? null : prev.GetType()) : null);
                            }
                        }
                        // now add the item to this collection
                        plotGroups[foundidx].PlotItemCollection.Add(plotItems[pix]);
                    }
                }

                return(s);
            }
 /// <summary>
 /// Copy constructor. Clones (!) all items. The parent owner is set to null and has to be set afterwards.
 /// </summary>
 /// <param name="from">The PlotItemCollection to clone this list from.</param>
 public PlotItemCollection(PlotItemCollection from)
     :
     this(null, from)
 {
 }