//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// UserRTX.NET satellite library | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;

#if !WASM
namespace user_rtx { using u = user_rtx;
#else
namespace user_rtx.wasm { using u = user_rtx.wasm;
#endif

/// <summary>
/// XML-configuration (instance class)
/// </summary>
public abstract partial class XmlConfigurationBase {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class RC: user_rtx.rc.XmlConfigurationBase {}
//==================================================================================================

protected bool IsDocumentLoaded =>
   _document != null;

/// <exception cref="InvalidOperationException" />
protected string FilePath {
   get {
      VerifyDocumentLoaded();
      return u.prop_check.Initialized( _filePath, GetType() ); }}

protected string? FilePathN =>
   _filePath;

/// <exception cref="InvalidOperationException" />
protected string FileFullPath {
   get {
      VerifyDocumentLoaded();
      return u.prop_check.Initialized( _fileFullPath, GetType() ); }}

protected string? FileFullPathN =>
   _fileFullPath;

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

protected string? TargetNamespace =>
   Schema.TargetNamespace;

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

protected XmlSchema Schema { get; private set; }

/// <exception cref="InvalidOperationException" />
protected XmlNamespaceManager NamespaceManager {
   get {
      VerifyDocumentLoaded();
      return _namespaceManager.NN(); }}

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

/// <exception cref="InvalidOperationException" />
protected XmlElement CurrentElement {
   get {
      VerifyCurrentElementSelected();
      return _currentElement.NN(); }
   private set {
      VerifyDocumentLoaded();
      _currentElement = value; }}

protected XmlElement? CurrentElementN =>
   _currentElement;

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

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

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

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

protected XmlDocument? DocumentN =>
   _document;

/// <exception cref="InvalidOperationException" />
protected XmlElement DocumentElement =>
   Document.DocumentElement.NN();

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

/// <exception cref="InvalidOperationException" />
protected XmlAttributeCollection Attributes =>
   CurrentElement.Attributes;

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

protected XmlConfigurationBase( string schemaText )
{
   using ( var stringReader = new StringReader( schemaText ) )
      Schema = XmlSchema.Read( stringReader, null ) ??
         throw new EUnexpected( "Successfully read XML-schema is unexpectedly null." );
}

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

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

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

XmlDocument? _document;
XmlNamespaceManager? _namespaceManager;
XmlElement? _currentElement;
string? _filePath, _fileFullPath;

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // XmlConfigurationBase

} // user_rtx (.wasm)
