﻿#region Apache License
//
// Licensed to the Apache Software Foundation (ASF) under one or more 
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership. 
// The ASF licenses this file to you under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with 
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion


using System;
using System.Collections;
using System.IO;

using log4net.Core;
using log4net.Layout.Pattern;
using log4net.Util;

namespace log4net.Layout
{
	/// <summary>
	/// A flexible layout configurable with pattern string that re-evaluates on each call.
	/// </summary>
	/// <remarks>
	/// <para>This class is built on <see cref="PatternLayout"></see> and provides all the
	/// features and capabilities of PatternLayout.  PatternLayout is a 'static' class
	/// in that its layout is done once at configuration time.  This class will recreate
	/// the layout on each reference.</para>
	/// <para>One important difference between PatternLayout and DynamicPatternLayout is the
	/// treatment of the Header and Footer parameters in the configuration.  The Header and Footer
	/// parameters for DynamicPatternLayout must be syntactically in the form of a PatternString,
	/// but should not be marked as type log4net.Util.PatternString.  Doing so causes the
	/// pattern to be statically converted at configuration time and causes DynamicPatternLayout
	/// to perform the same as PatternLayout.</para>
	/// <para>Please see <see cref="PatternLayout"/> for complete documentation.</para>
	/// <example>
	///	&lt;layout type="log4net.Layout.DynamicPatternLayout"&gt;
	///   &lt;param name="Header" value="%newline**** Trace Opened     Local: %date{yyyy-MM-dd HH:mm:ss.fff}     UTC: %utcdate{yyyy-MM-dd HH:mm:ss.fff} ****%newline" /&gt;
	///   &lt;param name="Footer" value="**** Trace Closed %date{yyyy-MM-dd HH:mm:ss.fff} ****%newline" /&gt;
	/// &lt;/layout&gt;
	/// </example>
	/// </remarks>
	public class DynamicPatternLayout: PatternLayout
	{
		#region Member Variables
		/// <summary>
		/// The header PatternString
		/// </summary>
		private PatternString m_headerPatternString = new PatternString("");

		/// <summary>
		/// The footer PatternString
		/// </summary>
		private PatternString m_footerPatternString  = new PatternString("");
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a DynamicPatternLayout using the DefaultConversionPattern
		/// </summary>
		/// <remarks>
		/// <para>
		/// The default pattern just produces the application supplied message.
		/// </para>
		/// </remarks>
		public DynamicPatternLayout()
			: base()
		{
		}

		/// <summary>
		/// Constructs a DynamicPatternLayout using the supplied conversion pattern
		/// </summary>
		/// <param name="pattern">the pattern to use</param>
		/// <remarks>
		/// </remarks>
		public DynamicPatternLayout (string pattern) 
			: base(pattern)
		{
		}
		#endregion

		#region Override implementation of LayoutSkeleton
		/// <summary>
		/// The header for the layout format.
		/// </summary>
		/// <value>the layout header</value>
		/// <remarks>
		/// <para>
		/// The Header text will be appended before any logging events
		/// are formatted and appended.
		/// </para>
		/// The pattern will be formatted on each get operation.
		/// </remarks>
		public override string Header
		{
			get
			{
				return m_headerPatternString.Format();
			}
			set
			{
				base.Header = value;
				m_headerPatternString = new PatternString(value);
			}
		}		/* property DynamicPatternLayout Header */

		/// <summary>
		/// The footer for the layout format.
		/// </summary>
		/// <value>the layout footer</value>
		/// <remarks>
		/// <para>
		/// The Footer text will be appended after all the logging events
		/// have been formatted and appended.
		/// </para>
		/// The pattern will be formatted on each get operation.
		/// </remarks>
		public override string Footer
		{
			get
			{
				return m_footerPatternString.Format();
			}
			set
			{
				base.Footer = value;
				m_footerPatternString = new PatternString(value);
			}
		}		/* property DynamicPatternLayout Footer */
		#endregion
	}			/* class DynamicPatternLayout */
}				/* namespace log4net.Layout */
