using System;
using System.IO;
using System.Collections;

namespace IniLib
{
    public class IniFile
    {
        // TODO: Is there another way so we have real consts?
        private static char[] COMMENTCHARS = new char[] { ';' };
        private static char[] EQUALCHARS = new char[] { '=' };

        private bool m_hasChanged = false;

        private int m_linecount = 0;

        private ArrayList m_sections = new ArrayList();

        public IniFile()
        {
            Clear();
        }

        public IniFile( string file )
        {
            Load( file );
        }

        public void Load( string file )
        {
            Clear();

            FileInfo fin = new FileInfo( file );
            StreamReader freader = fin.OpenText();

            Section section = Section( String.Empty );
            string comments = String.Empty;
            string line;

            while ( ( line = freader.ReadLine() ) != null )
            {
                m_linecount++;

                line = line.Trim();

                if ( line == String.Empty )
                    continue;

                // Do we have comments?
                if ( line[0] == ';' )
                {
                    line = line.TrimStart( COMMENTCHARS );
                    line = line.Trim();
                    comments += line + '\n';
                }

                // Do we have a section?
                if ( line.StartsWith( "[" )
                    && line.EndsWith( "]" )
                    && line.Length > 2 )
                {
                    // TODO: Currently anything is accepted as section name.
                    //       Create a section name checker and possible
                    //       retrieve function.
                    section = Section( line.Substring( 1, line.Length - 2 ) );
                    Console.WriteLine( "Section : {0}", section.Name );

                    if ( comments != String.Empty )
                    {
                        section.Comment = comments;
                        comments = String.Empty;
                    }

                    continue;
                }

                // Split in key/value pair
                string[] values = line.Split( EQUALCHARS );
                Console.WriteLine( "values.Count() : {0}", values.Length );
            }

            freader.Close();
        }

        public void Save( string file )
        {
            if ( m_hasChanged )
            {
            }

            m_hasChanged = false;
        }

        public void Clear()
        {
            m_hasChanged = false;
            m_sections.Clear();
            m_linecount = 0;

            // Make sure that there is a default section
            m_sections.Add( new Section( String.Empty ) );
        }

        public Section Section( int i )
        {
            if ( i > m_sections.Count )
                throw new ArgumentOutOfRangeException();

            return (Section)m_sections[i];
        }

        public Section Section( string name )
        {
            // The default section is not deleted
            if ( name == String.Empty )
                ((Section)m_sections[0]).Clear();

            foreach ( Section section in m_sections )
                if ( section.Name == name )
                    return section;

            m_hasChanged = true;
            return new Section( name );
        }

        public void DeleteSection( string name )
        {
            for ( int i = 0; i < m_sections.Count; i++ )
            {
                if ( ((Section)(m_sections[i])).Name == name )
                {
                    m_sections.RemoveAt( i );
                    break;
                }
            }
        }

        public void DeleteSection( int index )
        {
            if ( index > m_sections.Count || index < 0 )
                throw new ArgumentOutOfRangeException();

            m_sections.RemoveAt( index );
        }
    }

    public class Test
    {
        public static void Main()
        {
            IniFile inifile = new IniFile();
            inifile.Load( "/home/niels/tmp/testfile.ini" );
        }
    }
}