using System;
using System.Data;
using System.Data.Common;
using System.Collections;
using System.Xml;
using System.Xml.XPath;

namespace Winson.Framework.Data.XmlClient
{
    public class XmlDataAdapter : DataAdapter
    {
        // Constructors
        public XmlDataAdapter()
        {
        }

        public XmlDataAdapter(XmlCommand selectCommand)
        {
            _selectCommand = selectCommand;
        }

        public XmlDataAdapter(string selectCommandText)
        {
            _selectCommand = new XmlCommand(selectCommandText, new XmlConnection());
        }

        public XmlDataAdapter(string selectCommandText, XmlConnection selectConnection)
        {
            _selectCommand = new XmlCommand(selectCommandText, selectConnection);
        }

        ////////////////////
        // Properties
        ////////////////////

        public XmlCommand SelectCommand
        {
            get { return _selectCommand; }
            set { _selectCommand = value; }
        }

        ////////////////////
        // DataAdapter 
        ////////////////////

        public override int Fill(DataSet dataSet)
        {
            // Empty the DataSet
            ClearDataSet(dataSet);

            // Fill the DataSet 
            dataSet.ReadXml(GetXmlReader());

            // Count the Rows
            int returnVal = 0;
            foreach (DataTable tbl in dataSet.Tables)
            {
                returnVal += tbl.Rows.Count;
            }
            return returnVal;
        }

        public override DataTable[] FillSchema(DataSet dataSet, SchemaType schemaType)
        {
            // Empty the DataSet
            ClearDataSet(dataSet);

            // Fill the DataSet's Schema
            dataSet.ReadXmlSchema(GetXmlReader());

            // Make copy of all the Tables (schema only)
            IEnumerator tableEnum = dataSet.Tables.GetEnumerator();
            DataTable[] aTables = new DataTable[dataSet.Tables.Count];
            for (int x = 0; x < dataSet.Tables.Count; ++x)
            {
                aTables[x] = dataSet.Tables[x];
            }
            return aTables;
        }

        public override IDataParameter[] GetFillParameters()
        {
            throw new InvalidOperationException("XmlClient Provider does not support this function");
        }

        public override int Update(DataSet dataSet)
        {
            throw new InvalidOperationException("XmlClient Provider does not support updating, reading only.");
        }

        public new DataTableMappingCollection TableMappings
        {
            get { throw new InvalidOperationException("XmlClient Provider does not support this property"); }
        }

        ////////////////////
        // Internal Methods
        ////////////////////

        internal XmlReader GetXmlReader()
        {
            // Open the XML Document with an URL (from the XmlCommand)
            XmlDocument doc = _selectCommand._connection._doc;
            XmlNode node = doc.SelectSingleNode(_selectCommand._commandText);
            if (node == null) return null;
            XmlNodeReader rdr = new XmlNodeReader(node);
            return (XmlReader)rdr;
        }

        internal void ClearDataSet(DataSet dataSet)
        {
            dataSet.Reset();
        }

        ////////////////////
        // Internal Data Members
        ////////////////////
        internal XmlCommand _selectCommand = null;
    }
}
