//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// CommonHelpers satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Collections.Generic;

namespace CommonHelpers {

//**************************************************************************************************
/// <summary>
/// </summary>
public abstract partial class HXmlConfigurationBase {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

protected bool IsDocumentLoaded
{
   get { return _Document_ != null; }
}

protected string FilePath
{
   get { VerifyDocumentLoaded(); return _FilePath_; }
}

protected string FileFullPath
{
   get { VerifyDocumentLoaded(); return _FileFullPath_; }
}

//--------------------------------------------------------------------------------------------------

protected string TargetNamespace
{
   get { return Schema.TargetNamespace; }
}

//--------------------------------------------------------------------------------------------------

protected XmlSchema Schema
{
   get { return _Schema_; }
}

protected XmlNamespaceManager NamespaceManager
{
   get { VerifyDocumentLoaded(); return _NamespaceManager_; }
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="InvalidOperationException" />
/// <exception cref="HNullValueException" />
[HNotNull]
protected XmlElement CurrentElement
{
   get
   {
      VerifyCurrentElementSelected();
      return _CurrentElement_;
   }
   set
   {
      if ( value == null )
         throw new HNullValueException();
      VerifyDocumentLoaded();
      SetCurentElementPrepareValueCollection( value );
   }
}

/// <exception cref="InvalidOperationException" />
protected string CurrentElementPath
{
   get { return GetElementPath( CurrentElement ); }
}

/// <exception cref="InvalidOperationException" />
protected bool IsCurrentElementSelected
{
   get { return GetCurrentElement() != null; }
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="InvalidOperationException" />
protected XmlDocument Document
{
   get { VerifyDocumentLoaded(); return _Document_; }
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="InvalidOperationException" />
protected XmlAttributeCollection Attributes
{
   get { return CurrentElement.Attributes; }
}

/// <exception cref="InvalidOperationException" />
protected HSimpleDictionary<string,string> AttributeValues
{
   get
   {
      VerifyCurrentElementSelected();
      return _CurrentAttributeValues_;
   }
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
protected HXmlConfigurationBase(string schemaText)
{
   HArgChecking.VerifyNotNull( schemaText );
   using ( var stringReader = new StringReader( schemaText ) )
      _Schema_ = XmlSchema.Read( stringReader, null );
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="HXmlConfigurationException" />
protected virtual HXmlConfigurationBase Duplicate(bool cloneDocument=true)
{
   var instance = (HXmlConfigurationBase)MemberwiseClone();
   if ( cloneDocument && IsDocumentLoaded )
      instance.LoadDocumentFromText( Document.InnerXml );
   return instance;
}

//==================================================================================================

XmlElement SetCurentElementPrepareValueCollection([HOptional] XmlElement element)
{
   _CurrentAttributeValues_ = null;
   _CurrentElement_ = null;
   if ( element != null )
   {
      _CurrentAttributeValues_ = GetAttributeValues( element );
      _CurrentElement_ = element;
   }
   return element;
}

void UpdateAttributeValueCollection()
{
   _CurrentAttributeValues_ = _CurrentElement_ != null ?
      GetAttributeValues( _CurrentElement_ ) : null;
}

//==================================================================================================

static HXmlConfigurationBase()
{
   CommonHelpers_Plus.Access();
}

//==================================================================================================

readonly XmlSchema
   _Schema_;
XmlDocument
   _Document_;
XmlNamespaceManager
   _NamespaceManager_;
XmlElement
   _CurrentElement_;
HXmlAttributeValueCollection
   _CurrentAttributeValues_;
string
   _FilePath_,
   _FileFullPath_;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HXmlConfigurationBase
//**************************************************************************************************

} // CommonHelpers
