using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace Rokojori
{  
  public class XMLDocument:XMLNode
  {
    XMLElementNode _documentElement;
    List<XMLNode> _roots = new List<XMLNode>();
   // public List<XMLNode> roots => _roots;

    public static XMLDocument From( string text )
    {
      var reader = new XMLReader();
      return reader.Read( text );
    }

    public static XMLDocument HTML()
    {
      var text = "<!DOCTYPE html><html><head></head><body></body></html>";
      return From( text );
    }

    public void AppendChild( XMLNode node  )
    {
      _roots.Add( node );

      if ( XMLNode.NodeType.Element == node.nodeType )
      {
        _documentElement = (XMLElementNode) node;
      }

      node._SetParent( this );
    }

    public int numRoots => _roots.Count;

    public XMLNode GetChild( int index )
    {
      return _roots[ index ];
    }

    public XMLDocument():base( null, XMLNode.NodeType.Document )
    {
      _document = this;
    }

    public XMLElementNode documentElement 
    {
      get => _documentElement;
      set 
      {
        _documentElement = value;
      }
    }

    public string Serialize()
    {
      var serializer = new XMLSerializer();

      return serializer.SerializeXMLNode( document );
    }


    public static XMLDocument CreateHtmlDocument( bool addHeadAndBody = true )
    {
      var htmlDocument = new XMLDocument();

      htmlDocument._documentElement = HTMLElementName.html.Create( htmlDocument );
      htmlDocument._roots.Add( htmlDocument._documentElement );

      if ( addHeadAndBody )
      {
        htmlDocument._documentElement.AppendChild( HTMLElementName.head.Create( htmlDocument ) );
        htmlDocument._documentElement.AppendChild( HTMLElementName.body.Create( htmlDocument ) );
      }

      return htmlDocument;
    } 

    public XMLElementNode Create( XMLElementNodeName nodeName, string text = null )
    {
      var element = nodeName.Create( this );

      if ( text != null )
      {
        element.AddText( text );
      }

      return element;
    }

    public XMLTextNode CreateText( string text )
    {
      return new XMLTextNode( this, text ); 
    }

    public XMLElementNode querySelector( XMLElementSelector selector )
    { 
      return XMLQuery.SelectElement( this, selector );
    }

    public XMLElementNode querySelector( string selector )
    {
      return querySelector( XMLElementSelectors.From( selector ) );
    }

    public List<XMLElementNode> querySelectorAll( XMLElementSelector selector )
    { 
      return XMLQuery.SelectAllElements( this, selector );
    }

    public List<XMLElementNode> querySelectorAll( string selector )
    {
      return querySelectorAll( XMLElementSelectors.From( selector ) );
    }
  }
}