/*
 * [The "BSD licence"]
 * Copyright (c) 2005-2008 Terence Parr
 * All rights reserved.
 *
 * Conversion to C#:
 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

namespace Antlr.Runtime
{
    using System.Collections.Generic;

    using Array = System.Array;
    using CLSCompliant = System.CLSCompliantAttribute;
    using ICloneable = System.ICloneable;
    using Math = System.Math;
    using StringBuilder = System.Text.StringBuilder;

    /** <summary>
     *  A stripped-down version of org.antlr.misc.BitSet that is just
     *  good enough to handle runtime requirements such as FOLLOW sets
     *  for automatic error recovery.
     *  </summary>
     */
    [System.Serializable]
    public sealed class BitSet : ICloneable
    {
        private const int BITS = 64;    // number of bits / long
        private const int LOG_BITS = 6; // 2^6 == 64

        /** <summary>
         *  We will often need to do a mod operator (i mod nbits).  Its
         *  turns out that, for powers of two, this mod operation is
         *  same as (i & (nbits-1)).  Since mod is slow, we use a
         *  precomputed mod mask to do the mod instead.
         *  </summary>
         */
        private const int MOD_MASK = BITS - 1;

        /** <summary>The actual data bits</summary> */
        ulong[] _bits;

        /** <summary>Construct a bitset of size one word (64 bits)</summary> */
        public BitSet()
            : this( BITS )
        {
        }

        /** <summary>Construction from a static array of longs</summary> */
        [CLSCompliant( false )]
        public BitSet( ulong[] bits )
        {
            _bits = bits;
        }

        /** <summary>Construction from a list of integers</summary> */
        public BitSet( IEnumerable<int> items )
            : this()
        {
            foreach ( int i in items )
                Add( i );
        }

        /** <summary>Construct a bitset given the size</summary>
         *  <param name="nbits">The size of the bitset in bits</param>
         */
        public BitSet( int nbits )
        {
            _bits = new ulong[( ( nbits - 1 ) >> LOG_BITS ) + 1];
        }

        public static BitSet Of( int el )
        {
            BitSet s = new BitSet( el + 1 );
            s.Add( el );
            return s;
        }

        public static BitSet Of( int a, int b )
        {
            BitSet s = new BitSet( Math.Max( a, b ) + 1 );
            s.Add( a );
            s.Add( b );
            return s;
        }

        public static BitSet Of( int a, int b, int c )
        {
            BitSet s = new BitSet();
            s.Add( a );
            s.Add( b );
            s.Add( c );
            return s;
        }

        public static BitSet Of( int a, int b, int c, int d )
        {
            BitSet s = new BitSet();
            s.Add( a );
            s.Add( b );
            s.Add( c );
            s.Add( d );
            return s;
        }

        /** <summary>return this | a in a new set</summary> */
        public BitSet Or( BitSet a )
        {
            if ( a == null )
            {
                return this;
            }
            BitSet s = (BitSet)this.Clone();
            s.OrInPlace( a );
            return s;
        }

        /** <summary>or this element into this set (grow as necessary to accommodate)</summary> */
        public void Add( int el )
        {
            int n = WordNumber( el );
            if ( n >= _bits.Length )
            {
                GrowToInclude( el );
            }
            _bits[n] |= BitMask( el );
        }

        /** <summary>Grows the set to a larger number of bits.</summary>
         *  <param name="bit">element that must fit in set</param>
         */
        public void GrowToInclude( int bit )
        {
            int newSize = Math.Max( _bits.Length << 1, NumWordsToHold( bit ) );
            SetSize(newSize);
        }

        public void OrInPlace( BitSet a )
        {
            if ( a == null )
            {
                return;
            }
            // If this is smaller than a, grow this first
            if ( a._bits.Length > _bits.Length )
            {
                SetSize( a._bits.Length );
            }
            int min = Math.Min( _bits.Length, a._bits.Length );
            for ( int i = min - 1; i >= 0; i-- )
            {
                _bits[i] |= a._bits[i];
            }
        }

        /** <summary>Sets the size of a set.</summary>
         *  <param name="nwords">how many words the new set should be</param>
         */
        private void SetSize( int nwords )
        {
            Array.Resize(ref _bits, nwords);
        }

        private static ulong BitMask( int bitNumber )
        {
            int bitPosition = bitNumber & MOD_MASK; // bitNumber mod BITS
            return 1UL << bitPosition;
        }

        public object Clone()
        {
            return new BitSet( (ulong[])_bits.Clone() );
        }

        public int Size()
        {
            int deg = 0;
            for ( int i = _bits.Length - 1; i >= 0; i-- )
            {
                ulong word = _bits[i];
                if ( word != 0L )
                {
                    for ( int bit = BITS - 1; bit >= 0; bit-- )
                    {
                        if ( ( word & ( 1UL << bit ) ) != 0 )
                        {
                            deg++;
                        }
                    }
                }
            }
            return deg;
        }

        public override int GetHashCode()
        {
            throw new System.NotImplementedException();
        }

        public override bool Equals( object other )
        {
            if ( other == null || !( other is BitSet ) )
            {
                return false;
            }

            BitSet otherSet = (BitSet)other;

            int n = Math.Min( this._bits.Length, otherSet._bits.Length );

            // for any bits in common, compare
            for ( int i = 0; i < n; i++ )
            {
                if ( this._bits[i] != otherSet._bits[i] )
                {
                    return false;
                }
            }

            // make sure any extra bits are off

            if ( this._bits.Length > n )
            {
                for ( int i = n + 1; i < this._bits.Length; i++ )
                {
                    if ( this._bits[i] != 0 )
                    {
                        return false;
                    }
                }
            }
            else if ( otherSet._bits.Length > n )
            {
                for ( int i = n + 1; i < otherSet._bits.Length; i++ )
                {
                    if ( otherSet._bits[i] != 0 )
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        public bool Member( int el )
        {
            if ( el < 0 )
            {
                return false;
            }
            int n = WordNumber( el );
            if ( n >= _bits.Length )
                return false;
            return ( _bits[n] & BitMask( el ) ) != 0;
        }

        // remove this element from this set
        public void Remove( int el )
        {
            int n = WordNumber( el );
            if ( n < _bits.Length )
            {
                _bits[n] &= ~BitMask( el );
            }
        }

        public bool IsNil()
        {
            for ( int i = _bits.Length - 1; i >= 0; i-- )
            {
                if ( _bits[i] != 0 )
                    return false;
            }
            return true;
        }

        private static int NumWordsToHold( int el )
        {
            return ( el >> LOG_BITS ) + 1;
        }

        public int NumBits()
        {
            return _bits.Length << LOG_BITS; // num words * bits per word
        }

        /** <summary>return how much space is being used by the bits array not how many actually have member bits on.</summary> */
        public int LengthInLongWords()
        {
            return _bits.Length;
        }

        /**Is this contained within a? */
        /*
        public boolean subset(BitSet a) {
            if (a == null || !(a instanceof BitSet)) return false;
            return this.and(a).equals(this);
        }
        */

        public int[] ToArray()
        {
            int[] elems = new int[Size()];
            int en = 0;
            for ( int i = 0; i < ( _bits.Length << LOG_BITS ); i++ )
            {
                if ( Member( i ) )
                {
                    elems[en++] = i;
                }
            }
            return elems;
        }

        private static int WordNumber( int bit )
        {
            return bit >> LOG_BITS; // bit / BITS
        }

        public override string ToString()
        {
            return ToString( null );
        }

        public string ToString( string[] tokenNames )
        {
            StringBuilder buf = new StringBuilder();
            string separator = ",";
            bool havePrintedAnElement = false;
            buf.Append( '{' );

            for ( int i = 0; i < ( _bits.Length << LOG_BITS ); i++ )
            {
                if ( Member( i ) )
                {
                    if ( i > 0 && havePrintedAnElement )
                    {
                        buf.Append( separator );
                    }
                    if ( tokenNames != null )
                    {
                        buf.Append( tokenNames[i] );
                    }
                    else
                    {
                        buf.Append( i );
                    }
                    havePrintedAnElement = true;
                }
            }
            buf.Append( '}' );
            return buf.ToString();
        }
    }
}
