//------------------------------------------------------------------------------
// <copyright file=”*.cs” company=”EhLib Team”>
//     Copyright (c) 2017 Dmitry V. Bolshakov   
// </copyright>
//------------------------------------------------------------------------------

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms.Design;
using System.Drawing;
using System.Collections;
using System.Diagnostics;
using System.Windows.Forms;
using System.Windows.Forms.Design.Behavior;
using System.Collections.Generic;

namespace EhLib.Design
{
  [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
  public class DataAxisGridDesigner : ControlDesigner
  {

    internal DataAxisGrid Grid
    {
      get { return this.Component as DataAxisGrid; }
    }

    public virtual string PropAxisBarName
    {
      get { return "PropAxisBar"; }
    }

    public virtual string PropAxisBarsName
    {
      get { return "PropAxisBars"; }
    }

    public virtual Type StaticPropBarCollectionType
    {
      get { return null; }
      //typeof(DataGridStaticColumnCollection)
    }

    public virtual DataAxisGridPropertyBarsEditor CreatePropertyBarsEditor()
    {
      return null;
    }

    protected override bool GetHitTest(Point point)
    {
      Point tpPoint = this.Control.PointToClient(point);

      Control childControl = Grid.GetChildAtPoint(tpPoint, GetChildAtPointSkip.None);

      if (childControl is BaseGridScrollBarPanelControl)
        return true;
      else
        return false;
    }

  }

  [ComplexBindingProperties("DataSource", "DataMember")]
  public class DataAxisGridChooseDataSourceActionList : DesignerActionList
  {
    readonly DataAxisGridDesigner owner;

    public DataAxisGridChooseDataSourceActionList(DataAxisGridDesigner owner) : base(owner.Component)
    {
      this.owner = owner;
    }

    public override DesignerActionItemCollection GetSortedActionItems()
    {
      DesignerActionItemCollection items = new DesignerActionItemCollection();
      DesignerActionPropertyItem item = new DesignerActionPropertyItem("DataSource", "Choose Data Source");
      item.RelatedComponent = this.owner.Component;
      items.Add(item);
      return items;
    }

    [AttributeProvider(typeof(IListSource))]
    public object DataSource
    {
      get
      {
        return this.owner.Grid.DataSource;
      }
      set
      {
        DataAxisGrid grid = this.owner.Grid;
        IDesignerHost host = grid.Site.GetService(typeof(IDesignerHost)) as IDesignerHost;
        PropertyDescriptor member = TypeDescriptor.GetProperties(grid)["DataSource"];
        IComponentChangeService service = grid.Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService;
        DesignerTransaction transaction = host.CreateTransaction("Choose DataSource");
        try
        {
          service.OnComponentChanging(grid, member);
          this.owner.Grid.DataSource = value;
          service.OnComponentChanged(grid, member, null, null);
          transaction.Commit();
          transaction = null;
        }
        finally
        {
          if (transaction != null)
          {
            transaction.Cancel();
          }
        }
      }
    }
  }

  public class DataAxisGridActionList : DesignerActionList
  {
    readonly DataAxisGridDesigner owner;

    public DataAxisGridActionList(DataAxisGridDesigner owner) : base(owner.Component)
    {
      this.owner = owner;
    }

    public override DesignerActionItemCollection GetSortedActionItems()
    {
      DesignerActionItemCollection items = new DesignerActionItemCollection();
      items.Add(new DesignerActionMethodItem(this, "EditAxisBands", "Edit " + owner.PropAxisBarsName + " ...", true));
      items.Add(new DesignerActionMethodItem(this, "EditAxisBand", "Add " + owner.PropAxisBarName + " ...", true));  // promoteToDesignerVerb 
      items.Add(new DesignerActionMethodItem(this, "AddAxisBands", "Add " + owner.PropAxisBarsName + " ...", true)); // promoteToDesignerVerb 
      return items;
    }

    public void EditAxisBands()
    {
      DataAxisGridPropertyBarsEditor ce = owner.CreatePropertyBarsEditor();

      PropertyDescriptor propDesc = TypeDescriptor.GetProperties(owner.Grid)["StaticPropBars"];
      DialogWindowsFormsEditorService internalSrv = new DialogWindowsFormsEditorService(owner.Grid, propDesc);

      ce.EditValue(internalSrv, internalSrv, owner.Grid.StaticPropBars);
    }

    public void EditAxisBand()
    {
      //     Show Collection Dialog for grid.Collumns Collection
    }

    public void AddAxisBands()
    {
      DataAxisGridAddBoundBandsDialog.AddBoundAxisBats(owner.Grid);
    }

  }

  public class DataAxisGridPropertiesActionList : DesignerActionList
  {
    readonly DataAxisGridDesigner owner;

    public DataAxisGridPropertiesActionList(DataAxisGridDesigner owner) : base(owner.Component)
    {
      this.owner = owner;
    }

    public override DesignerActionItemCollection GetSortedActionItems()
    {
      DesignerActionItemCollection items = new DesignerActionItemCollection();
      items.Add(new DesignerActionPropertyItem("Dock", "Dock"));
      return items;
    }

    public DockStyle Dock
    {
      get { return this.owner.Grid.Dock; }
      set { GetPropertyByName("Dock").SetValue(owner.Grid, value); }
    }

    private PropertyDescriptor GetPropertyByName(String propName)
    {
      PropertyDescriptor prop = TypeDescriptor.GetProperties(owner.Grid)[propName];
      if (prop == null)
      {
        throw new ArgumentException("Propery {0} does not exist", propName);
      }
      return prop;
    }
  }

  internal class DialogWindowsFormsEditorService : IServiceProvider, IWindowsFormsEditorService, ITypeDescriptorContext
  {
    readonly IServiceProvider baseServiceProvider;

    readonly PropertyDescriptor propDesc;
    readonly Component component;

    public DialogWindowsFormsEditorService(Component component, PropertyDescriptor propDesc)
    {
      this.baseServiceProvider = component.Site;
      this.component = component;
      this.propDesc = propDesc;
    }

    //IServiceProvider
    public object GetService(Type serviceType)
    {
      if (serviceType == typeof(IWindowsFormsEditorService))
        return this;
      else
        return baseServiceProvider.GetService(serviceType);
    }

    //IWindowsFormsEditorService
    public void CloseDropDown()
    {
      //throw new NotImplementedException();
    }

    public void DropDownControl(Control control)
    {
      //throw new NotImplementedException();
    }

    public DialogResult ShowDialog(Form dialog)
    {
      return dialog.ShowDialog();
    }

    //ITypeDescriptorContext
    public IContainer Container
    {
      get { return component.Site.Container; }
    }

    public object Instance
    {
      get { return component; }
    }

    public PropertyDescriptor PropertyDescriptor
    {
      get { return propDesc; }
    }

    public bool OnComponentChanging()
    {
      return true;
    }

    public void OnComponentChanged()
    {
    }
  }

}
