private void Initialize(IEnumerable <Layer> layers, string undoChangeLocation, bool saveOnStartup, bool useDocumentSize = false)
        {
            var layersArray = layers as Layer[] ?? layers.ToArray();

            LayerChunk[] layerChunks = new LayerChunk[layersArray.Length];
            for (var i = 0; i < layersArray.Length; i++)
            {
                var layer   = layersArray[i];
                int width   = layer.Width;
                int height  = layer.Height;
                int offsetX = layer.OffsetX;
                int offsetY = layer.OffsetY;

                if (useDocumentSize)
                {
                    width   = layer.MaxWidth;
                    height  = layer.MaxHeight;
                    offsetX = 0;
                    offsetY = 0;
                }

                layerChunks[i] = new LayerChunk(layer, SKRectI.Create(offsetX, offsetY, width, height));
                layersToStore.Add(layer.GuidValue);
            }

            UndoChangeLocation = undoChangeLocation;
            GenerateUndoLayers(layerChunks);
            if (saveOnStartup)
            {
                SaveLayersOnDevice();
            }
        }
        public StorageBasedChange(Document doc, IEnumerable <LayerChunk> chunks, bool saveOnStartup = true)
        {
            Document = doc;
            var chunkData = chunks as LayerChunk[] ?? chunks.ToArray();

            LayerChunk[] layerChunks = new LayerChunk[chunkData.Length];
            for (var i = 0; i < chunkData.Length; i++)
            {
                var chunk = chunkData[i];
                layerChunks[i] = chunk;
                layersToStore.Add(chunk.Layer.GuidValue);
            }

            UndoChangeLocation = DefaultUndoChangeLocation;
            GenerateUndoLayers(layerChunks);
            if (saveOnStartup)
            {
                SaveLayersOnDevice();
            }
        }
        /// <summary>
        ///     Creates UndoManager ready Change instance, where undo and redo is the same, before process images are loaded from disk and current ones are saved.
        /// </summary>
        /// <param name="undoRedoProcess">Process that is invoked on redo and undo.</param>
        /// <param name="processArgs">Custom parameters for undo and redo process.</param>
        /// <param name="description">Undo change description.</param>
        /// <returns>UndoManager ready 'Change' instance.</returns>
        public Change ToChange(Action <Layer[], UndoLayer[], object[]> undoRedoProcess, object[] processArgs, string description = "")
        {
            Action <object[]> finalProcess = processParameters =>
            {
                Layer[]      layers = LoadLayersFromDevice();
                LayerChunk[] chunks = new LayerChunk[layers.Length];
                for (int i = 0; i < layers.Length; i++)
                {
                    chunks[i] = new LayerChunk(layers[i], StoredLayers[i].SerializedRect);
                }

                GenerateUndoLayers(chunks);

                SaveLayersOnDevice();

                undoRedoProcess(layers, StoredLayers, processParameters);
            };

            var change = new Change(finalProcess, processArgs, finalProcess, processArgs, description);

            change.DisposeProcess = (_, _) => Dispose();
            return(change);
        }