using System;
using System.Collections.Generic;
using System.Xml;
using System.Text;

using DataWarehouse;
using AstronomyDB.AstronomyDataSetTableAdapters;
using System.Data.SqlClient;
using System.Data.Common;

namespace AstronomyDB
{
    public class AstronomyWarehouse : IDatabaseInterface
    {
        static private AstronomyWarehouse aw;
        private string treeString;
        private XmlDocument doc;
        private Dictionary<Guid, XmlElement> dic = new Dictionary<Guid, XmlElement>();
        QueriesTableAdapter ad;
        SelectBinaryTableAdapter bt;
        InsertBinaryTableAdapter idt;
        InsertBinaryNodeTableAdapter addn;
        private string server;
        private string cs;

        private AstronomyWarehouse(string server)
        {
            load(System.Environment.MachineName);
        }

        static public AstronomyWarehouse GetInterface(string server)
        {
            if (aw != null)
            {
                return aw;
            }
            return new AstronomyWarehouse(server);
        }

         

        private void load(string server)
        {
            DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
            builder["Data Source"] = server;
            builder["Initial Catalog"] = "AstronomyDB";
            builder["Integrated Security"] = "SSPI";
            builder["Timeout"] = 10000;
            cs = builder.ConnectionString;
            AstronomyDB.Properties.Settings.Default["AstronomyDBConnectionString"] = cs;
            SqlConnection connection = new SqlConnection(cs);
            ad = new QueriesTableAdapter();
            bt = new SelectBinaryTableAdapter();
           // bt.Connection = connection;
            idt = new InsertBinaryTableAdapter();
           // idt.Connection = connection;
            addn = new InsertBinaryNodeTableAdapter();
           // addn.Connection = connection;
            doc = new XmlDocument();
            doc.LoadXml("<?xml version=\"1.0\"?><Root><BinaryRoot></BinaryRoot></Root>");
            SelectBinaryTreeTableAdapter btr = new SelectBinaryTreeTableAdapter();
            AstronomyDataSet.SelectBinaryTreeDataTable tree =
                btr.GetData();
            XmlElement sel;
            List<object[]> l = new List<object[]>();
            foreach (AstronomyDataSet.SelectBinaryTreeRow row in tree.Rows)
            {
                XmlElement e = doc.CreateElement("BinaryNode");
                dic[row.Id] = e;
                if (row.Id.Equals(row.ParentId))
                {
                    sel = e;
                    doc.DocumentElement.AppendChild(sel);
                }
                else
                {
                    l.Add(new object[] { row.ParentId, e });
                }
                XmlAttribute aid = doc.CreateAttribute("BinaryNodeId");
                aid.Value = row.Id + "";
                e.Attributes.Append(aid);
                XmlAttribute an = doc.CreateAttribute("BinaryNodeName");
                an.Value = row.Name;
                e.Attributes.Append(an);
                XmlAttribute ae = doc.CreateAttribute("BinaryNodeExtention");
                ae.Value = row.ext;
                e.Attributes.Append(ae);
                XmlElement d = doc.CreateElement("Description");
                d.InnerText = row.Description;
                e.AppendChild(d);
            }
            foreach (object[] o in l)
            {
                Guid g = (Guid)o[0];
                XmlElement e = o[1] as XmlElement;
                dic[g].AppendChild(e);
            }
            SelectBinaryTableTableAdapter at =
                new SelectBinaryTableTableAdapter();
            AstronomyDataSet.SelectBinaryTableDataTable table =
                at.GetData();
            foreach (AstronomyDataSet.SelectBinaryTableRow row in table)
            {
                Guid pid = row.ParentId;
                XmlElement e = doc.CreateElement("Binary");
                dic[pid].AppendChild(e);
                dic[row.Id] = e;
                XmlAttribute aid = doc.CreateAttribute("BinaryId");
                aid.Value = row.Id + "";
                e.Attributes.Append(aid);
                XmlAttribute an = doc.CreateAttribute("BinaryName");
                an.Value = row.Name;
                e.Attributes.Append(an);
                XmlAttribute aExt = doc.CreateAttribute("Ext");
                aExt.Value = row.Ext;
                e.Attributes.Append(aExt);
                XmlElement d = doc.CreateElement("Description");
                d.InnerText = row.Description;
                e.AppendChild(d);
            }

        }

 
        #region IDatabaseInterface Members

        void IDatabaseInterface.Login(string login, string password)
        {
        }

        System.Xml.XmlDocument IDatabaseInterface.GetTree(string login, string password, string[] ext)
        {
            return doc;
        }

        string IDatabaseInterface.GetTreeString(string login, string password, string[] ext)
        {
            return doc.OuterXml;
        }

        byte[] IDatabaseInterface.GetData(string login, string password, string id, ref string ext)
        {
            Guid guid = new Guid(id);
            AstronomyDataSet.SelectBinaryDataTable t = bt.GetData(guid);
            AstronomyDataSet.SelectBinaryRow row = t.Rows[0] as AstronomyDataSet.SelectBinaryRow;
            ext = row.Ext;
            return row.Data;
        }

        string IDatabaseInterface.AddData(string login, string password, string parentId, string name, string description, byte[] data, string ext)
        {
            Guid guid = new Guid(parentId);
            AstronomyDataSet.InsertBinaryDataTable t =
               idt.GetData(guid, name, description, data, data.Length, ext);
            AstronomyDataSet.InsertBinaryRow row = t.Rows[0] as AstronomyDataSet.InsertBinaryRow;
            string id = row.Id + "";
            XmlElement p = dic[guid] as XmlElement;
            XmlElement e = doc.CreateElement("Binary");
            p.AppendChild(e);
            XmlAttribute aid = doc.CreateAttribute("BinaryId");
            aid.Value = id;
            e.Attributes.Append(aid);
            XmlAttribute aName = doc.CreateAttribute("BinaryName");
            aName.Value = name;
            e.Attributes.Append(aName);
            XmlElement d = doc.CreateElement("Description");
            d.InnerText = description;
            e.AppendChild(d);
            XmlAttribute aExt = doc.CreateAttribute("Ext");
            aExt.Value = ext;
            e.Attributes.Append(aExt);
            dic[row.Id] = e;
            return id;

        }

        void IDatabaseInterface.UpdateData(string login, string password, string id, byte[] data)
        {
            Guid guid = new Guid(id);
            ad.UpdateBinaryData(guid, data);
        }

        string IDatabaseInterface.AddDirectory(string login, string password, string parentId, string name, string description, string ext)
        {
            Guid guid = new Guid(parentId);
            AstronomyDataSet.InsertBinaryNodeDataTable t = addn.GetData(guid, name, description, ext);
            AstronomyDataSet.InsertBinaryNodeRow row = t.Rows[0]
            as AstronomyDataSet.InsertBinaryNodeRow;
            XmlElement p = dic[guid];
            XmlElement e = doc.CreateElement("BinaryNode");
            dic[row.Id] = e;
            string id = row.Id + "";
            XmlAttribute aid = doc.CreateAttribute("BinaryNodeId");
            aid.Value = id;
            e.Attributes.Append(aid);
            XmlAttribute aName = doc.CreateAttribute("BinaryNodeName");
            aName.Value = name;
            e.Attributes.Append(aName);
            XmlElement d = doc.CreateElement("Description");
            d.InnerText = description;
            e.AppendChild(d);
            p.AppendChild(e);
            return id;
        }

        void IDatabaseInterface.UpdateData(string login, string password, string Id, string name, string description)
        {
            Guid guid = new Guid(Id);
            ad.UpdateBinaryDataName(guid, name, description);
        }

        void IDatabaseInterface.UpdateDirectory(string login, string password, string id, string name, string description)
        {
            Guid guid = new Guid(id);
            ad.UpdateBinaryTreeName(guid, name, description);
        }

        void IDatabaseInterface.RemoveData(string login, string password, string id)
        {
            Guid guid = new Guid(id);
            ad.DeleteBinary(guid);
            XmlElement e = dic[guid];
            XmlElement p = e.ParentNode as XmlElement;
            p.RemoveChild(e);
            dic.Remove(guid);
        }

        void IDatabaseInterface.RemoveDirectory(string login, string password, string id)
        {
            Guid guid = new Guid(id);
            ad.DeleteBinaryTree(guid);
            XmlElement e = dic[guid];
            XmlElement p = e.ParentNode as XmlElement;
            p.RemoveChild(e);
            dic.Remove(guid);
        }

        #endregion
    }
}
