<#@ template language="C#" HostSpecific="true" #>
<#@ import namespace="ICSharpCode.AspNet.Mvc" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Reflection" #>
<# if (MvcHost.IsPartialView) { #>
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<#= GetViewPageType() #>" %>

<# } else if (MvcHost.IsContentPage) { #>
<%@ Page Language="C#" MasterPageFile="<#= MvcHost.MasterPageFile #>" Inherits="System.Web.Mvc.ViewPage<#= GetViewPageType() #>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="Title" runat="server">
<#= MvcHost.ViewName #>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="<#= MvcHost.PrimaryContentPlaceHolderID #>" runat="server">
<#
		PushIndent("\t");
	} else {
#>
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<#= GetViewPageType() #>" %>

<!DOCTYPE html>
<html>
	<head runat="server">
		<title><#= MvcHost.ViewName #></title>
	</head>
	<body>
<# 
		PushIndent("\t\t");
	} 
#>
<% using (Html.BeginForm()) { %>
	<%: Html.ValidationSummary(true) %>
	<fieldset>
		<legend><#= MvcHost.ViewDataType.Name #></legend>
<# if (ModelHasPrimaryKey) { #>
		
		<%: Html.HiddenFor(model => model.Id) %>
<# } #>
<#
	foreach (ModelProperty modelProperty in ModelProperties) {
		if (!modelProperty.IsPrimaryKey) {
#>
		
		<div class="editor-label">
			<%: Html.LabelFor(model => model.<#= modelProperty.Name #>) %>
		</div>
		<div class="editor-field">
			<%: Html.EditorFor(model => model.<#= modelProperty.Name #>) %>
			<%: Html.ValidationMessageFor(model => model.<#= modelProperty.Name #>) %>
		</div>
<#
		}
	}
#>
		
		<p>
			<input type="submit" value="Save"/>
		</p>
	</fieldset>
<% } %>
<div>
	<%: Html.ActionLink("Back", "Index") %>
</div>
<#
	if (MvcHost.IsPartialView) {
		// Do nothing.
	} else if (MvcHost.IsContentPage) {
		PopIndent();
#>
</asp:Content>
<#
	} else { 
		PopIndent();
#>
	</body>
</html>
<# } #>
<#+
	MvcTextTemplateHost MvcHost {
		get { return (MvcTextTemplateHost)Host; }
	}
	
	public class ModelProperty
	{
		public string Name { get; set; }
		public bool IsPrimaryKey { get; set; }
		
		public ModelProperty(PropertyInfo propertyInfo)
		{
			this.Name = propertyInfo.Name;
			this.IsPrimaryKey = IsPrimaryKeyProperty(propertyInfo);
		}
		
		bool IsPrimaryKeyProperty(PropertyInfo propertyInfo)
		{
			return
				IsIdProperty(propertyInfo) ||
				IsIdPropertyPrefixedWithClassName(propertyInfo);
		}
		
		bool IsIdProperty(PropertyInfo propertyInfo)
		{
			return IsMatchIgnoringCase(propertyInfo.Name, "id");
		}
		
		bool IsIdPropertyPrefixedWithClassName(PropertyInfo propertyInfo)
		{
			string prefixedIdPropertyName = propertyInfo.DeclaringType.Name + "id";
			return IsMatchIgnoringCase(propertyInfo.Name, prefixedIdPropertyName);
		}
		
		static bool IsMatchIgnoringCase(string a, string b)
		{
			return String.Equals(a, b, StringComparison.OrdinalIgnoreCase);
		}
	}
	
	public string GetViewPageType()
	{
		string viewDataTypeName = MvcHost.ViewDataTypeName;
		if (!String.IsNullOrEmpty(viewDataTypeName)) {
			return String.Format("<{0}>", viewDataTypeName);
		}
		return String.Empty;
	}
	
	List<ModelProperty> modelProperties;
	
	List<ModelProperty> ModelProperties {
		get {
			if (modelProperties == null) {
				modelProperties = new List<ModelProperty>(GetModelProperties());
			}
			return modelProperties;
		}
	}
	
	public IEnumerable<ModelProperty> GetModelProperties()
	{
		var properties = new List<ModelProperty>();
		foreach (PropertyInfo propertyInfo in MvcHost.GetViewDataTypeProperties()) {
			properties.Add(new ModelProperty(propertyInfo));
		}
		return properties;
	}
	
	bool ModelHasPrimaryKey {
		get { return ModelPrimaryKeyName.Length > 0; }
	}
	
	string modelPrimaryKeyName;
	
	string ModelPrimaryKeyName {
		get {
			if (modelPrimaryKeyName == null) {
				modelPrimaryKeyName = GetModelPrimaryKeyName();
			}
			return modelPrimaryKeyName;
		}
	}
	
	public string GetModelPrimaryKeyName()
	{
		foreach (ModelProperty modelProperty in ModelProperties) {
			if (modelProperty.IsPrimaryKey) {
				return modelProperty.Name;
			}
		}
		return "";
	}
#>