using System;
using System.Collections;
using System.Web.UI;
using System.Web.UI.Design;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Reflection;
using System.Data;
namespace Csla.Web.Design
{
  /// 
  /// Object responsible for providing details about
  /// data binding to a specific CSLA .NET object.
  /// 
  public class CslaDesignerDataSourceView : DesignerDataSourceView
  {
    private CslaDataSourceDesigner _owner = null;
    /// 
    /// Creates an instance of the object.
    /// 
    public CslaDesignerDataSourceView(CslaDataSourceDesigner owner, string viewName)
      : base(owner, viewName)
    {
      _owner = owner;
    }
    /// 
    /// Returns a set of sample data used to populate
    /// controls at design time.
    /// 
    /// Minimum number of sample rows
    /// to create.
    /// Returns True if the data
    /// is sample data.
    public override IEnumerable GetDesignTimeData(int minimumRows, out bool isSampleData)
    {
      IDataSourceViewSchema schema = this.Schema;
      DataTable result = new DataTable();
      // create the columns
      foreach (IDataSourceFieldSchema item in schema.GetFields())
      {
        result.Columns.Add(item.Name, item.DataType);
      }
      // create sample data
      for (int index = 1; index <= minimumRows; index++)
      {
        object[] values = new object[result.Columns.Count];
        int colIndex = 0;
        foreach (DataColumn col in result.Columns)
        {
          if (col.DataType.Equals(typeof(string)))
            values[colIndex] = "abc";
          else if (col.DataType.Equals(typeof(System.DateTime)))
            values[colIndex] = System.DateTime.Today.ToShortDateString();
          else if (col.DataType.Equals(typeof(bool)))
            values[colIndex] = false;
          else if (col.DataType.IsPrimitive)
            values[colIndex] = index;
          else if (col.DataType.Equals(typeof(Guid)))
            values[colIndex] = Guid.Empty;
          else if (col.DataType.IsValueType)
            values[colIndex] = Activator.CreateInstance(col.DataType);
          else
            values[colIndex] = null;
          colIndex += 1;
        }
        result.LoadDataRow(values, LoadOption.OverwriteChanges);
      }
      isSampleData = true;
      return (IEnumerable)result.DefaultView;
    }
    /// 
    /// Returns schema information corresponding to the properties
    /// of the CSLA .NET business object.
    /// 
    /// 
    /// All public properties are returned except for those marked
    /// with the Browsable attribute
    /// as False.
    /// 
    public override IDataSourceViewSchema Schema
    {
      get
      {
        return new ObjectSchema(
          _owner, 
          _owner.DataSourceControl.TypeName).GetViews()[0];
      }
    }
    /// 
    /// Get a value indicating whether data binding can retrieve
    /// the total number of rows of data.
    /// 
    public override bool CanRetrieveTotalRowCount
    {
      get
      {
        return true;
      }
    }
    private Type GetObjectType()
    {
      Type result;
      try
      {
        ITypeResolutionService typeService = null;
        typeService = (ITypeResolutionService)(_owner.Site.GetService(typeof(ITypeResolutionService)));
        result = typeService.GetType(this._owner.DataSourceControl.TypeName, true, false);
      }
      catch
      {
        result = typeof(object);
      }
      return result;
    }
    /// 
    /// Get a value indicating whether data binding can directly
    /// delete the object.
    /// 
    /// 
    /// If this returns true, the web page must handle the
    /// DeleteObject
    /// event.
    /// 
    public override bool CanDelete
    {
      get
      {
        Type objectType = GetObjectType();
        if (typeof(Csla.Core.IUndoableObject).IsAssignableFrom(objectType))
        {
          return true;
        }
        else if (objectType.GetMethod("Remove") != null)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }
    /// 
    /// Get a value indicating whether data binding can directly
    /// insert an instance of the object.
    /// 
    /// 
    /// If this returns true, the web page must handle the
    /// InsertObject
    /// event.
    /// 
    public override bool CanInsert
    {
      get
      {
        Type objectType = GetObjectType();
        if (typeof(Csla.Core.IUndoableObject).IsAssignableFrom(objectType))
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }
    /// 
    /// Get a value indicating whether data binding can directly
    /// update or edit the object.
    /// 
    /// 
    /// If this returns true, the web page must handle the
    /// UpdateObject
    /// event.
    /// 
    public override bool CanUpdate
    {
      get
      {
        Type objectType = GetObjectType();
        if (typeof(Csla.Core.IUndoableObject).IsAssignableFrom(objectType))
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }
    /// 
    /// Gets a value indicating whether the data source supports
    /// paging.
    /// 
    public override bool CanPage
    {
      get
      {
        return _owner.DataSourceControl.TypeSupportsPaging;
      }
    }
    /// 
    /// Gets a value indicating whether the data source supports
    /// sorting.
    /// 
    public override bool CanSort
    {
      get
      {
        return _owner.DataSourceControl.TypeSupportsSorting;
      }
    }
  }
}