context: /*************************************************************************
   *
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
   * 
   * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
   * 
   * Use is subject to license terms.
   * 
   * Licensed 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. You can also
   * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
   * 
   * 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.
   *
   ************************************************************************/
  
  using System;
  using System.Xml;
  using AODL.Document.Styles;
  using AODL.Document.Import.OpenDocument.NodeProcessors;
  using AODL.Document;
  
  namespace AODL.Document.Content.Text
  {
  	/// <summary>
  	/// Header represent a header.
  	/// </summary>
  	public class Header : IContent, IHtml, ITextContainer, ICloneable
  	{
  		/// <summary>
  		/// Gets or sets the out line level.
  		/// e.g
  		/// start header = "1"
  		/// some paragraphs here
  		/// subheader	 = "2"
  		/// some paragraphs here
  		/// start header = "1"
  		/// will result in:
  		/// 1. a header
  		/// some text
  		/// 1.1 a subheader
  		/// some text
  		/// 2. a header
  		/// </summary>
  		/// <value>The out line level.</value>
  		public string OutLineLevel
  		{
  			get 
  			{ 
  				XmlNode xn = this._node.SelectSingleNode("@text:outline-level",
  					this.Document.NamespaceManager);
  				if (xn != null)
  					return xn.InnerText;
  				return null;
  			}
  			set
  			{
  				XmlNode xn = this._node.SelectSingleNode("@text:outline-level",
  					this.Document.NamespaceManager);
  				if (xn == null)
  					this.CreateAttribute("outline-level", value, "text");
  				this._node.SelectSingleNode("@text:outline-level",
  					this.Document.NamespaceManager).InnerText = value;
  			}
  		}
  
  		/// <summary>
  		/// Initializes a new instance of the <see cref="Header"/> class.
  		/// </summary>
  		/// <param name="document">The document.</param>
  		/// <param name="heading">The heading.</param>
  		public Header(IDocument document, Headings heading)
  		{
  			this.Document		= document;
  			this.NewXmlNode();
  			this.StyleName		= this.GetHeading(heading);
  			this.InitStandards();
  		}
  
  		/// <summary>
  		/// Initializes a new instance of the <see cref="Header"/> class.
  		/// </summary>
  		/// <param name="headernode">The headernode.</param>
  		/// <param name="document">The document.</param>
  		public Header(XmlNode headernode, IDocument document)
  		{
  			this.Document				= document;
  			this.Node					= headernode;
  			this.InitStandards();
  		}
  
  		/// <summary>
  		/// Inits the standards.
  		/// </summary>
  		private void InitStandards()
  		{
  			this.TextContent			= new ITextCollection();
  
  			this.TextContent.Inserted	+= TextContent_Inserted;
  			this.TextContent.Removed	+= TextContent_Removed;
  		}
  
  		/// <summary>
  		/// Create a new XmlNode.
  		/// </summary>
  		private void NewXmlNode()
  		{			
  			this.Node		= this.Document.CreateNode("h", "text");
  		}
  
  		/// <summary>
  		/// Create a XmlAttribute for propertie XmlNode.
  		/// </summary>
  		/// <param name="name">The attribute name.</param>
  		/// <param name="text">The attribute value.</param>
  		/// <param name="prefix">The namespace prefix.</param>
  		private void CreateAttribute(string name, string text, string prefix)
  		{
  			XmlAttribute xa = this.Document.CreateAttribute(name, prefix);
  			xa.Value		= text;
  			this.Node.Attributes.Append(xa);
  		}
  
  		/// <summary>
  		/// Gets the heading.
  		/// </summary>
  		/// <param name="heading">The heading.</param>
  		/// <returns>The heading stylename</returns>
  		private string GetHeading(Headings heading)
  		{
  			if (heading == Headings.Heading)
  				return "Heading";
  			else if (heading == Headings.Heading_20_1)
  				return "Heading_20_1";
  			else if (heading == Headings.Heading_20_2)
  				return "Heading_20_2";
  			else if (heading == Headings.Heading_20_3)
  				return "Heading_20_3";
  			else if (heading == Headings.Heading_20_4)
  				return "Heading_20_4";
  			else if (heading == Headings.Heading_20_5)
  				return "Heading_20_5";
  			else if (heading == Headings.Heading_20_6)
  				return "Heading_20_6";
  			else if (heading == Headings.Heading_20_7)
  				return "Heading_20_7";
  			else if (heading == Headings.Heading_20_8)
  				return "Heading_20_8";
  			else if (heading == Headings.Heading_20_9)
  				return "Heading_20_9";
  			else if (heading == Headings.Heading_20_10)
  				return "Heading_20_10";
  			else
  				return "Heading";
  		}
  
  		#region IContent Member
  		/// <summary>
  		/// Gets or sets the name of the style.
  		/// </summary>
  		/// <value>The name of the style.</value>
  		public string StyleName
  		{
  			get 
  			{ 
  				XmlNode xn = this._node.SelectSingleNode("@text:style-name",
  					this.Document.NamespaceManager);
  				if (xn != null)
  					return xn.InnerText;
  				return null;
  			}
  			set
  			{
  				XmlNode xn = this._node.SelectSingleNode("@text:style-name",
  					this.Document.NamespaceManager);
  				if (xn == null)
  					this.CreateAttribute("style-name", value, "text");
  				this._node.SelectSingleNode("@text:style-name",
  					this.Document.NamespaceManager).InnerText = value;
  			}
  		}
  
  		private IDocument _document;
  		/// <summary>
  		/// Every object (typeof(IContent)) have to know his document.
  		/// </summary>
  		/// <value></value>
  		public IDocument Document
  		{
  			get
  			{
  				return this._document;
  			}
  			set
  			{
  				this._document = value;
  			}
  		}
  
  		private IStyle _style;
  		/// <summary>
  		/// A Style class wich is referenced with the content object.
  		/// If no style is available this is null.
  		/// </summary>
  		/// <value></value>
  		public IStyle Style
  		{
  			get
  			{
  				return this._style;
  			}
  			set
  			{
  				this.StyleName	= value.StyleName;
  				this._style = value;
  			}
  		}
  
  		private XmlNode _node;
  		/// <summary>
  		/// Gets or sets the node.
  		/// </summary>
  		/// <value>The node.</value>
  		public XmlNode Node
  		{
  			get { return this._node; }
  			set { this._node = value; }
  		}
  
  		#endregion
  
  		/// <summary>
  		/// Append the xml from added IText object.
  		/// </summary>
  		/// <param name="index"></param>
  		/// <param name="value"></param>
  		private void TextContent_Inserted(int index, object value)
  		{
  			this.Node.AppendChild(((IText)value).Node);
  
  			if (((IText)value).Text != null)
  			{
  				try
  				{
  					if (this.Document is AODL.Document.TextDocuments.TextDocument)
  					{
  						string text		= ((IText)value).Text;
  						this.Document.DocumentMetadata.CharacterCount	+= text.Length;
  						string[] words	= text.Split(' ');
  						this.Document.DocumentMetadata.WordCount		+= words.Length;
  					}
  				}
  				catch(Exception)
  				{
  					//unhandled, only word and character count wouldn' be correct
  				}
  			}
  		}
  
  		/// <summary>
  		/// Texts the content_ removed.
  		/// </summary>
  		/// <param name="index">The index.</param>
  		/// <param name="value">The value.</param>
  		private void TextContent_Removed(int index, object value)
  		{
  			this.Node.RemoveChild(((IText)value).Node);
  		}
  
  
  		#region IHtml Member
  
  		/// <summary>
  		/// Return the content as Html string
  		/// </summary>
  		/// <returns>The html string</returns>
  		public string GetHtml()
  		{
  			try
  			{
  				string html		= this.GetAnchor()+"<p ";
  				string style	= this.GetHtmlStyle(this.StyleName);
  				
  				if (style.Length > 0)
  					html		+= style;
  				html			+= ">\n";
  
  				//Check numbering
  				string number	= this.GetHeadingNumber();
  
gt: 				if (number.Length > 0)