using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Linq;
using C1.Silverlight.DataGrid;
using C1DataGrid_WCF_DS.AdventureWorksDataService;

namespace C1DataGrid_WCF_DS
{
    public class MyAstoriaDataSource : AstoriaDataSourceView<Product>
    {
        private AdventureWorksEntities _dataContext;
        private KeyValuePair<int, object>[] _editedElements;
        private C1DataGrid _owner;

        public MyAstoriaDataSource( AdventureWorksEntities dataContext, IEnumerable<Product> source, C1DataGrid owner)
            : base(source)
        {
            _dataContext = dataContext;
            _owner = owner;
            _owner.SelectionChanged += _owner_SelectionChanged;
            _owner.CommittingEdit += _owner_CommittingEdit;
        }

        public override void Refresh()
        {
            IQueryable<Product> initialQuery = from p in _dataContext.Product
                                               select p;
            IQueryable<Product> query = Sort(Filter(initialQuery));
            InvokeService(query);
        }

        public override void AddDataItems(KeyValuePair<int, object>[] newItems)
        {
            _editedElements = null;
            Product[] newProducts = newItems.Select(p => p.Value as Product).ToArray();
            foreach (Product product in newProducts)
            {
                _dataContext.AddToProduct(product);
            }
            SaveChanges();
        }

        public override void EditDataItems(KeyValuePair<int, object>[] editedItems)
        {
            Product[] editedProducts = editedItems.Select(p => p.Value as Product).ToArray();
            foreach (Product product in editedProducts)
            {
                _dataContext.UpdateObject(product);
            }
            SaveChanges();
        }

        public override void RemoveDataItems(KeyValuePair<int, object>[] removedItems)
        {
            Product[] removedProducts = removedItems.Select(p => p.Value as Product).ToArray();
            foreach (Product product in removedProducts)
            {
                _dataContext.DeleteObject(product);
            }
            SaveChanges();
        }

        private void _owner_CommittingEdit(object sender, DataGridEndingEditEventArgs e)
        {
            KeyValuePair<int, object> editedElement = new KeyValuePair<int, object>(e.Row.Index, e.Row.DataItem);
            _editedElements = new KeyValuePair<int, object>[] { editedElement };
        }

        private void _owner_SelectionChanged(object sender, EventArgs e)
        {
            if (_editedElements != null)
            {
                EditDataItems(_editedElements);
                _editedElements = null;
            }
        }

        private void SaveChanges()
        {
            _dataContext.SaveChangesDefaultOptions = SaveChangesOptions.Batch;
            _dataContext.BeginSaveChanges(
                result =>
                {
                    _dataContext.EndSaveChanges(result);
                    Refresh();
                }, null);
        }
    }
}
