//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Data;
using System.Reflection;

namespace CommunityServer.Components
{
	/// <summary>
	/// Summary description for CADataConverter.
	/// </summary>
	public class CADataConverter
	{

		private static Hashtable types = new Hashtable();

		private CADataConverter()
		{
		}

		/// <summary>
		/// Converts an IList into a datatable.
		/// </summary>
		/// <param name="list">List of objects. First item can not be null</param>
		/// <returns></returns>
		public static DataTable ToDataTable(IList list)
		{
			if(list == null)
				throw new ArgumentNullException("list", "List can not be null");

			if(list.Count == 0)
				throw new ArgumentOutOfRangeException("list", "List can not be empty without supplying a type. Please use the other overload");

			object obj = list[0];
			if(obj == null)
				throw new ArgumentOutOfRangeException("list", "First item in collection can not equal null");


			return ToDataTable(list,obj.GetType());
		}

		/// <summary>
		/// Converts an IList into a datatable.
		/// </summary>
		/// <param name="list"></param>
		/// <param name="t">Since a type is supplied, the list can be null or empty</param>
		/// <returns></returns>
		public static DataTable ToDataTable(IList list, Type t)
		{
			DataTable dt = types[t] as DataTable;
			if(dt == null)
				dt = CreateShell(t);
			else
				dt = dt.Clone();

			if(list == null || list.Count == 0)
				return dt;

			foreach(object item in list)
			{
				if(item != null)
				{
					DataRow dr = dt.NewRow();
					foreach(DataColumn dc in dt.Columns)
					{
						try
						{
							dr[dc.ColumnName] = t.GetProperty(dc.ColumnName).GetValue(item,null);
						}
						catch{}
					}
					dt.Rows.Add(dr);
				}
			}

			return dt;
		}

		/// <summary>
		/// Creates a datatable with datacolumns
		/// </summary>
		/// <param name="t"></param>
		/// <returns></returns>
		protected static DataTable CreateShell(Type t)
		{
			DataTable dt = new DataTable(t.Name);
			PropertyInfo[] pia = t.GetProperties();
			foreach (PropertyInfo pi in pia)
			{
				if(pi.CanRead)
				{
					string st = pi.PropertyType.ToString();
					switch(st)
					{
						case "System.String":
						case "System.Int32":
						case "System.Boolean":
						case "System.Double":
						case "System.Guid":
							dt.Columns.Add(pi.Name,pi.PropertyType);
							break;
					}
				}
			}

			types[t] = dt;

			return dt;
		}
	}
}
