//------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel
{
    using System;
    using System.IO;
    using System.Xml;
    /// 
    /// Class wraps a given writer and delegates all XmlDictionaryWriter calls 
    /// to the inner wrapped writer.
    /// 
    public class DelegatingXmlDictionaryWriter : XmlDictionaryWriter
    {
        XmlDictionaryWriter _innerWriter;
        // this writer is used to echo un-canonicalized bytes
        XmlWriter _tracingWriter;
        /// 
        /// Initializes a new instance of 
        /// 
        protected DelegatingXmlDictionaryWriter()
        {
        }
        /// 
        /// Initializes the inner writer that this instance wraps.
        /// 
        /// XmlDictionaryWriter to wrap.
        protected void InitializeInnerWriter(XmlDictionaryWriter innerWriter)
        {
            if (innerWriter == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerWriter");
            }
            _innerWriter = innerWriter;
        }
        /// 
        /// Initializes a writer that will write the un-canonicalize xml.
        /// If this agrument is not null, all calls will be echoed to this writer.
        /// 
        /// XmlTextWriter to echo .
        protected void InitializeTracingWriter(XmlWriter tracingWriter)
        {
            _tracingWriter = tracingWriter;
        }
        /// 
        /// Gets the wrapped writer.
        /// 
        protected XmlDictionaryWriter InnerWriter
        {
            get
            {
                return _innerWriter;
            }
        }
        /// 
        /// Closes the underlying stream.
        /// 
        public override void Close()
        {
            _innerWriter.Close();
            if (_tracingWriter != null)
            {
                _tracingWriter.Close();
            }
        }
        /// 
        /// Flushes the underlying stream.
        /// 
        public override void Flush()
        {
            _innerWriter.Flush();
            if (_tracingWriter != null)
            {
                _tracingWriter.Flush();
            }
        }
        /// 
        /// Encodes the specified binary bytes as Base64 and writes out the resulting text.
        /// 
        /// Byte array to encode.
        /// The position in the buffer indicating the start of the bytes to write.
        /// The number of bytes to write.
        public override void WriteBase64(byte[] buffer, int index, int count)
        {
            _innerWriter.WriteBase64(buffer, index, count);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteBase64(buffer, index, count);
            }
        }
        /// 
        /// Writes out a CDATA block containing the specified text.
        /// 
        /// The text to place inside the CDATA block.
        public override void WriteCData(string text)
        {
            _innerWriter.WriteCData(text);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteCData(text);
            }
        }
        /// 
        /// Forces the generation of a character entity for the specified Unicode character value.
        /// 
        /// The Unicode character for which to generate a character entity.
        public override void WriteCharEntity(char ch)
        {
            _innerWriter.WriteCharEntity(ch);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteCharEntity(ch);
            }
        }
        /// 
        /// When overridden in a derived class, writes text one buffer at a time.
        /// 
        /// Character array containing the text to write.
        /// The position in the buffer indicating the start of the text to write.
        /// The number of characters to write.
        public override void WriteChars(char[] buffer, int index, int count)
        {
            _innerWriter.WriteChars(buffer, index, count);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteChars(buffer, index, count);
            }
        }
        /// 
        /// Writes out a comment containing the specified text.
        /// 
        /// Text to place inside the comment.
        public override void WriteComment(string text)
        {
            _innerWriter.WriteComment(text);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteComment(text);
            }
        }
        /// 
        /// Writes the DOCTYPE declaration with the specified name and optional attributes.
        /// 
        /// The name of the DOCTYPE. This must be non-empty.
        /// If non-null it also writes PUBLIC "pubid" "sysid" where pubid and sysid are
        /// replaced with the value of the given arguments.
        /// If pubid is null and sysid is non-null it writes SYSTEM "sysid" where sysid
        /// is replaced with the value of this argument.
        /// If non-null it writes [subset] where subset is replaced with the value of
        /// this argument.
        public override void WriteDocType(string name, string pubid, string sysid, string subset)
        {
            _innerWriter.WriteDocType(name, pubid, sysid, subset);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteDocType(name, pubid, sysid, subset);
            }
        }
        /// 
        /// Closes the previous System.Xml.XmlWriter.WriteStartAttribute(System.String,System.String) call.
        /// 
        public override void WriteEndAttribute()
        {
            _innerWriter.WriteEndAttribute();
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteEndAttribute();
            }
        }
        /// 
        /// Closes any open elements or attributes and puts the writer back in the Start state.
        /// 
        public override void WriteEndDocument()
        {
            _innerWriter.WriteEndDocument();
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteEndDocument();
            }
        }
        /// 
        /// Closes one element and pops the corresponding namespace scope.
        /// 
        public override void WriteEndElement()
        {
            _innerWriter.WriteEndElement();
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteEndElement();
            }
        }
        /// 
        /// Writes out an entity reference as name.
        /// 
        /// The name of the entity reference.
        public override void WriteEntityRef(string name)
        {
            _innerWriter.WriteEntityRef(name);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteEntityRef(name);
            }
        }
        /// 
        /// Closes one element and pops the corresponding namespace scope.
        /// 
        public override void WriteFullEndElement()
        {
            _innerWriter.WriteFullEndElement();
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteFullEndElement();
            }
        }
        /// 
        /// Writes out a processing instruction with a space between the name and text as follows: <?name text?>.
        /// 
        /// The name of the processing instruction.
        /// The text to include in the processing instruction.
        public override void WriteProcessingInstruction(string name, string text)
        {
            _innerWriter.WriteProcessingInstruction(name, text);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteProcessingInstruction(name, text);
            }
        }
        /// 
        /// When overridden in a derived class, writes raw markup manually from a character buffer.
        /// 
        /// Character array containing the text to write.
        /// The position within the buffer indicating the start of the text to write.
        /// The number of characters to write.
        public override void WriteRaw(char[] buffer, int index, int count)
        {
            _innerWriter.WriteRaw(buffer, index, count);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteRaw(buffer, index, count);
            }
        }
        /// 
        /// Writes raw markup manually from a string.
        /// 
        /// String containing the text to write.
        public override void WriteRaw(string data)
        {
            _innerWriter.WriteRaw(data);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteRaw(data);
            }
        }
        /// 
        /// Writes the start of an attribute with the specified local name and namespace URI.
        /// 
        /// The namespace prefix of the attribute.
        /// The local name of the attribute.
        /// The namespace URI for the attribute.
        public override void WriteStartAttribute(string prefix, string localName, string ns)
        {
            _innerWriter.WriteStartAttribute(prefix, localName, ns);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteStartAttribute(prefix, localName, ns);
            }
        }
        /// 
        /// When overridden in a derived class, writes the XML declaration with the version "1.0".
        /// 
        public override void WriteStartDocument()
        {
            _innerWriter.WriteStartDocument();
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteStartDocument();
            }
        }
        /// 
        /// When overridden in a derived class, writes the XML declaration with the version
        /// "1.0" and the standalone attribute.
        /// 
        /// If true, it writes "standalone=yes"; if false, it writes "standalone=no".
        public override void WriteStartDocument(bool standalone)
        {
            _innerWriter.WriteStartDocument(standalone);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteStartDocument(standalone);
            }
        }
        /// 
        /// When overridden in a derived class, writes the specified start tag and associates
        /// it with the given namespace and prefix.
        /// 
        /// The namespace prefix of the element.
        /// The local name of the element.
        /// The namespace URI to associate with the element.
        public override void WriteStartElement(string prefix, string localName, string ns)
        {
            _innerWriter.WriteStartElement(prefix, localName, ns);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteStartElement(prefix, localName, ns);
            }
        }
        /// 
        /// When overridden in a derived class, gets the state of the writer.
        /// 
        public override WriteState WriteState
        {
            get { return _innerWriter.WriteState; }
        }
        /// 
        /// Writes the given text content.
        /// 
        /// The text to write.
        public override void WriteString(string text)
        {
            _innerWriter.WriteString(text);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteString(text);
            }
        }
        /// 
        /// Generates and writes the surrogate character entity for the surrogate character pair.
        /// 
        /// The low surrogate. This must be a value between 0xDC00 and 0xDFFF.
        /// The high surrogate. This must be a value between 0xD800 and 0xDBFF.
        public override void WriteSurrogateCharEntity(char lowChar, char highChar)
        {
            _innerWriter.WriteSurrogateCharEntity(lowChar, highChar);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteSurrogateCharEntity(lowChar, highChar);
            }
        }
        /// 
        /// Writes out the given white space.
        /// 
        /// The string of white space characters.
        public override void WriteWhitespace(string ws)
        {
            _innerWriter.WriteWhitespace(ws);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteWhitespace(ws);
            }
        }
        /// 
        /// Writes an attribute as a xml attribute with the prefix 'xml:'.
        /// 
        /// Localname of the attribute.
        /// Attribute value.
        public override void WriteXmlAttribute(string localName, string value)
        {
            _innerWriter.WriteXmlAttribute(localName, value);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteAttributeString(localName, value);
            }
        }
        /// 
        /// Writes an xmlns namespace declaration. 
        /// 
        /// The prefix of the namespace declaration.
        /// The namespace Uri itself.
        public override void WriteXmlnsAttribute(string prefix, string namespaceUri)
        {
            _innerWriter.WriteXmlnsAttribute(prefix, namespaceUri);
            if (_tracingWriter != null)
            {
                _tracingWriter.WriteAttributeString(prefix, String.Empty, namespaceUri, String.Empty);
            }
        }
        /// 
        /// Returns the closest prefix defined in the current namespace scope for the namespace URI.
        /// 
        /// The namespace URI whose prefix you want to find.
        /// The matching prefix or null if no matching namespace URI is found in the
        /// current scope.
        public override string LookupPrefix(string ns)
        {
            return _innerWriter.LookupPrefix(ns);
        }
        /// 
        /// Returns a value indicating if the reader is capable of Canonicalization.
        /// 
        public override bool CanCanonicalize
        {
            get
            {
                return _innerWriter.CanCanonicalize;
            }
        }
        /// 
        /// Indicates the start of Canonicalization. Any write operatation following this will canonicalize the data 
        /// and will wirte it to the given stream.
        /// 
        /// Stream to which the canonical stream should be written.
        /// The value indicates if comments written should be canonicalized as well.
        /// Set of prefixes that needs to be included into the canonical stream. The prefixes are defined at 
        /// the first element that is written to the canonical stream.
        public override void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes)
        {
            _innerWriter.StartCanonicalization(stream, includeComments, inclusivePrefixes);
        }
        /// 
        /// Closes a previous Start canonicalization operation. The stream given to the StartCanonicalization is flushed 
        /// and any data written after this call will not be written to the canonical stream.
        /// 
        public override void EndCanonicalization()
        {
            _innerWriter.EndCanonicalization();
        }
    }
}