using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc.Html;

namespace System.Web.Mvc {
	public static class HtmlHelperExtensions {
		/// <summary>
		/// Serializes an object to Javascript Object Notation.
		/// </summary>
		/// <param name="item">The item to serialize.</param>
		/// <returns>
		/// The item serialized as Json.
		/// </returns>
		public static string ToJson ( this object item ) {
            return Newtonsoft.Json.JsonConvert.SerializeObject(item);
			// return new System.Web.Script.Serialization.JavaScriptSerializer( ).Serialize( item );
		}

		/// <summary>
		/// Renders the specified partial view as an HTML-encoded string. The output may be different based on authentication status.
		/// </summary>
		/// <param name="helper">
		/// The HTML helper instance that this method extends.
		/// </param>
		/// <param name="authenticated">
		/// The name of the partial view to render if the current user is authenticated.
		/// </param>
		/// <param name="unauthenticated">
		/// The name of the partial view to render if the current user is not authenticated.
		/// </param>
		/// <returns>
		/// The partial view that is rendered as an HTML-encoded string.
		/// </returns>
		public static MvcHtmlString Partial ( this HtmlHelper helper, string authenticated, string unauthenticated ) {
			if (HttpContext.Current.Request.IsAuthenticated)
				return helper.Partial( authenticated );
			else
				return helper.Partial( unauthenticated );
		}

		/// <summary>
		/// Invokes the specified child action method using the specified parameters and returns the result as an HTML string.
		/// </summary>
		/// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
		/// <param name="actionName">The name of the action method to invoke.</param>
		/// <param name="routeValues">
		/// A dictionary that contains the parameters for a route. You can use routeValues 
		/// to provide the parameters that are bound to the action method parameters.
		/// The routeValues parameter is merged with the original route values and overrides
		/// them.
		/// </param>
		/// <returns>The child action result as an HTML string.</returns>
		public static MvcHtmlString AuthenticatedAction ( this HtmlHelper htmlHelper, string actionName, object routeValues ) {
			if (HttpContext.Current.Request.IsAuthenticated)
				return htmlHelper.Action( actionName, routeValues );
			else
				return null;
		}

		public static HtmlSelectTag<TModel, TEnum> EnumTagFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) {
			ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
			IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum)).Cast<TEnum>();

			IEnumerable<SelectListItem> items = new[] { 
		        new SelectListItem { Text = "", Value = "", Selected = true }
		    }
				.Concat(values.Select(value => new SelectListItem {
					Text = System.Text.RegularExpressions.Regex.Replace(value.ToString(), "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 "),
					Value = value.ToString(),
					Selected = false
				}));

			// create a new select tag
			return new HtmlSelectTag<TModel, TEnum>(htmlHelper, expression).Options(items);
		}
	}
}