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

namespace Rokojori
{  
  public class Inkscape
  {
    public static readonly XMLAttributeName label = XMLAttributeName.Create( "label", "inkscape" );

    public static void StripEditorData( XMLDocument doc )
    {
      var walker = new XMLWalker();

      var  it = doc.documentElement;

      var removals = new List<XMLNode>();
      var inkspaceNamespaceRegex = "^(sodipodi|inkscape)$";

      walker.Iterate( it, 
        ( n )=>
        {
          if ( XMLNode.NodeType.Element != n.nodeType )
          {
            if ( XMLNode.NodeType.Text == n.nodeType && ! HasTextParent( n) )
            {              
              removals.Add( n );
            }

            return;
          }

          var element = (XMLElementNode) n;

          if ( RegexUtility.MatchingIgnoreCase( element.nameSpace, inkspaceNamespaceRegex ) )
          {
            removals.Add( element );
            return;
          }

          var attRemovals = new List<int>();
          
          for ( int i = 0; i < element.numAttributes; i++ )
          {
            var att = element.GetAttributeAt( i );

            if ( ! RegexUtility.MatchingIgnoreCase( att.nameSpace, inkspaceNamespaceRegex ) )
            {
              continue;
            }

            attRemovals.Add( i );
          }
          

          for ( int i = attRemovals.Count - 1; i >= 0; i -- )
          {
            var index = attRemovals[ i ];
            element.RemoveAttributeAt( index );
          }


        }
      );


      removals.ForEach( n => n.parentElement.RemoveChild( n ) );
    }

    public static bool HasTextParent( XMLNode node )
    {
      var parent = node.parentElement;
      
      if ( parent == null )
      {
        return false;
      }

      var parentName = parent.nodeName;

      var textElementRegex = "^(text|tspan)$";

      return RegexUtility.MatchingIgnoreCase( parentName, textElementRegex );
    }

    public static List<XMLElementNode> GetLayers( XMLDocument doc, bool onlyTopLayers = false )
    {     

      if ( onlyTopLayers )
      {
        var svg = doc.querySelector( SVGElementName.svg );

        var list = new List<XMLElementNode>();

        for ( int i = 0; i < svg.numChildren; i++ )
        {
          var child = svg.GetChildAt( i );
          var elementChild = child as XMLElementNode;

          if ( elementChild != null && label.Selects( elementChild ) )
          { 
            list.Add( elementChild );
          }
        }

        return list;
      }

      return doc.querySelectorAll( Inkscape.label );
    }

    public static string GetLayerName( XMLElementNode node )
    {
      return label.Get( node );
    }
  }
}