using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using _1_Model;
using Telerik.OpenAccess;
using Telerik.WinControls;
using Telerik.WinControls.UI;

namespace _5B_WCFUseService
{
  public partial class Form1 : RadForm
  {
    public Form1()
    {
      InitializeComponent();
    }

    private ObjectContainer _container = new ObjectContainer();

    private ServiceReference1.Service1Client _client =
       new _5B_WCFUseService.ServiceReference1.Service1Client();

    private void Form1_Load(object sender, EventArgs e)
    {
      cbCategories.DataSource = _client.GetCategories();
      cbCategories.DisplayMember = "CategoryName";
      cbCategories.ValueMember = "CategoryID";

      SetFormBackground();

      gvProducts.MasterGridViewTemplate.AutoSizeColumnsMode =
        GridViewAutoSizeColumnsMode.Fill;
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
      SaveProducts();
    }


    private void cbCategories_SelectedIndexChanged(object sender, EventArgs e)
    {
      RadComboBox combo = sender as RadComboBox;
      if (combo.SelectedValue != null)
      {
        int categoryID = (int)combo.SelectedValue;

        LoadProducts(categoryID);
        CreateGridColumns();
      }
    }

    #region helper methods

    private void SetFormBackground()
    {
      this.FormElement.ClientFillPrimitive.BackColor =
        Color.FromArgb(159, 159, 159);
      this.FormElement.ClientFillPrimitive.BackColor2 =
        Color.FromArgb(120, 120, 120);
      this.FormElement.ClientFillPrimitive.BackColor3 =
        Color.FromArgb(110, 110, 110);
      this.FormElement.ClientFillPrimitive.GradientStyle =
        GradientStyles.OfficeGlassRect;
    }

    private void CreateGridColumns()
    {
      gvProducts.Columns.Clear();
      GridViewTextBoxColumn productColumn =
        new GridViewTextBoxColumn("ProductName");
      productColumn.HeaderText = "Product";
      gvProducts.Columns.Add(productColumn);
      GridViewTextBoxColumn quantityColumn =
        new GridViewTextBoxColumn("QuantityPerUnit");
      quantityColumn.HeaderText = "Quantity Per Unit";
      gvProducts.Columns.Add(quantityColumn);
    }

    #endregion

    #region service handling methods

    private void SaveProducts()
    {
      if (_container.Transaction.IsActive)
        _container.Transaction.Commit();

      // get the deltas 
      ObjectContainer.ChangeSet changeSet =
        _container.GetChanges(ObjectContainer.Verify.Changed);
      // send the deltas to the service
      _client.UpdateProducts(changeSet);

      // start next transaction
      _container.Transaction.Begin();

    }

    private void LoadProducts(int categoryID)
    {
      if (_container.Transaction.IsActive)
        _container.Transaction.Commit();

      // !gotcha: use special constructor that takes an object to 
      // handle difference between the model.myobject and service.myobject types
      ObjectContainer.ChangeSet changeSet =
        new ObjectContainer.ChangeSet(_client.GetProductsByCategory(categoryID));

      FetchGroupCollector collector =
        new FetchGroupCollector(FetchGroupCollector.DefaultFetchGroup);

      // apply service changeset to local container
      _container.Apply(changeSet);

      // use "Named List" to get subset of objects in container
      IList products = _container.NamedList(categoryID.ToString());

      // create BindingSource using named list
      BindingSource bindingSource =
        new BindingSource(products, String.Empty);
      bindingSource.AddingNew +=
        new System.ComponentModel.AddingNewEventHandler(
          bindingSource_AddingNew);
      bindingSource.ListChanged +=
        new System.ComponentModel.ListChangedEventHandler(
          bindingSource_ListChanged);

      // bind
      gvProducts.DataSource = bindingSource;

      // start next transaction
      _container.Transaction.Begin();
    }

    #endregion


    void bindingSource_ListChanged(object sender, 
      System.ComponentModel.ListChangedEventArgs e)
    {
      int category = (int)cbCategories.SelectedValue;
      IList products = _container.NamedList(category.ToString());
      Product product = products[e.NewIndex] as Product;

      switch (e.ListChangedType)
      {
        case ListChangedType.ItemDeleted:
          {
            _container.Remove(product);
            _container.NamedList(category.ToString()).Remove(product); 
            break;
          }
        case ListChangedType.ItemAdded:
          {
            break; 
          }
        case ListChangedType.ItemChanged:
          {
            break;             
          }
      }
    }

    void bindingSource_AddingNew(object sender, 
      System.ComponentModel.AddingNewEventArgs e)
    {
      int category = (int)cbCategories.SelectedValue;
      Product product = new Product();
      product.CategoryID = category;
      product.ProductName = String.Empty;
      product.QuantityPerUnit = String.Empty; 
      e.NewObject = product;
      _container.Add(product);
      //_container.NamedList(category.ToString()).Add(product); 
    }

  }
}
