using System;
using System.Linq;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Criterion.Lambda;

namespace Common
{
	/// <summary>
	/// 扩展 IQueryOver
	/// </summary>
    public static class IQueryOverExtension
    {
		/// <summary>
		/// 扩展 IQueryOver.OrderBy
		/// </summary>
		/// <typeparam name="TRoot"></typeparam>
		/// <typeparam name="TSubType"></typeparam>
		/// <param name="source"></param>
		/// <param name="sort"></param>
		/// <param name="order"></param>
		/// <returns></returns>
        public static IQueryOver<TRoot, TSubType> OrderBy<TRoot, TSubType>(this IQueryOver<TRoot, TSubType> source, string sort, string order)
        {
            if (String.IsNullOrEmpty(sort)) {
				throw new ArgumentNullException("sort");
            }

            Type type = typeof(TRoot);
            if (type.GetProperties().Count(r => r.Name == sort) == 0) {
				throw new ArgumentException(String.Format("无效的参数值，{0}不是{1}的属性。", sort, type.Name), "sort");
            }

            if (String.IsNullOrEmpty(order)) {
				throw new ArgumentNullException("order");
            }

            bool ascending = true;

            if (String.Equals(order, "asc", StringComparison.OrdinalIgnoreCase)) {
                ascending = true;
            } else if (String.Equals(order, "desc", StringComparison.OrdinalIgnoreCase)) {
                ascending = false;
            } else {
				throw new ArgumentException("无效的参数值，取值范围 asc 或 desc 。", "order");
            }

            IQueryOverOrderBuilder<TRoot, TSubType> orderBuilder = source.OrderBy(Projections.Property(sort));

            return ascending ? orderBuilder.Asc : orderBuilder.Desc;
        }
    }
}
