using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using IdeaBlade.Core;
using IdeaBlade.EntityModel;
using System.Collections.Specialized;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using IdeaBladeMVC.Data;

namespace IdeaBladeSilverlight {
  public class MainPageViewModel : INotifyPropertyChanged {
    public ObservableCollection<Employee> Employees { get; private set; }
    public ObservableCollection<string> Log { get; private set; }
    public Employee CurrentEmployee { get; set; }
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public MainPageViewModel() {
      Log = new ObservableCollection<string>();
      WriteToLog("Initializing View Model");
      Employees = new ObservableCollection<Employee>();
      Employees.CollectionChanged += Employees_CollectionChanged;
      _mgr = new NorthwindIBEntities();
      //_mgr.Fetching += (s, e) => WriteToLog("Fetching " + e.Query.ElementType);  //lambda syntax
      _mgr.Fetching += new EventHandler<EntityFetchingEventArgs>(_mgr_Fetching);
      _mgr.Fetching += delegate { IsBusy = true; };
      _mgr.Queried += delegate { IsBusy = false; };
      //var query = _mgr.Employees;
      var query = _mgr.Employees.Include("Orders");
      query.ExecuteAsync(op => op.Results.ForEach(Employees.Add));
    }

    void _mgr_Fetching(object sender, EntityFetchingEventArgs e) {
      WriteToLog("Fetching " + e.Query.ElementType);
    }

    public void Save() {
      _mgr.SaveChangesAsync();
    }

    private void Employees_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
      switch (e.Action) {
        case NotifyCollectionChangedAction.Add:
          Add(e.NewItems.Cast<Employee>());
          break;
        case NotifyCollectionChangedAction.Remove:
          Delete(e.OldItems.Cast<Employee>());
          break;
      }
    }

    private void Add(IEnumerable<Employee> employees) {
      employees.ForEach(_mgr.AddEntity);
    }

    private void Delete(IEnumerable<Employee> employees) {
      employees.ForEach(employee => employee.EntityAspect.Delete());
      Save();
    }

    private void WriteToLog(string message) {
      Log.Insert(0, message);
    }

    private void WriteToLog(IEntityQuery query) {
      var returnType = query.ElementType;
      var message = (returnType == typeof(Order))
          ? "Fetching Orders from Employee " + CurrentEmployee.FullName
          : "Fetching " + returnType;
      WriteToLog(message);
    }

    private void RaisePropertyChanged(string property) {
      PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    public bool IsBusy {
      get {
        return _isBusy;
      }
      set {
        _isBusy = value;
        RaisePropertyChanged("IsBusy");
      }
    }

    private readonly NorthwindIBEntities _mgr;
    private bool _isBusy;

  }
}
