using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.IO;

namespace OsaGateway
{
    public class Calls
    {
        public delegate void CallDelegate();
        static public event CallDelegate CallAdded;
        static public event CallDelegate CallDeleted;

        private Guid guid;
        private string phone;
        private DateTime date;
        private TrafficType trafficType;
        static public string xmlFile = Application.StartupPath + @"\" + @"calls.xml";

        public Guid GUID
        {
            get
            {
                return this.guid;
            }
            set
            {
                this.guid = value;
            }
        }
        public string Phone
        {
            get
            {
                return this.phone;
            }
            set
            {
                this.phone = value;
            }
        }
        public DateTime Date
        {
            get
            {
                return this.date;
            }
            set
            {
                this.date = value;
            }
        }
        public TrafficType TrafficType
        {
            get
            {
                return this.trafficType;
            }
            set
            {
                this.trafficType = value;
            }
        }

        public Calls()
        {

        }
        public Calls(string phone, TrafficType trafficType)
        {
            this.guid = Guid.NewGuid();
            this.date = DateTime.Now;
            this.phone = phone;
            this.trafficType = trafficType;
        }

        static public Calls Get(Guid guid)
        {
            Calls call = new Calls();
            try
            {
                XDocument xdoc;
                xdoc = XDocument.Load(xmlFile);
                call = (from a in xdoc.Descendants("Call")
                        where a.Element("GUID").Value == guid.ToString()
                        select new Calls
                        {
                            GUID = new Guid(a.Element("GUID").Value),
                            Phone = a.Element("Phone").Value,
                            Date = new DateTime(long.Parse(a.Element("Date").Value)),
                            TrafficType = ConvertTrafficType(a.Element("TrafficType").Value)
                        }
                         ).FirstOrDefault();
            }
            catch (Exception)
            {
                return null;
            }
            return call;
        }
        static public List<Calls> GetAll(TrafficType trafficType)
        {
            List<Calls> calls = new List<Calls>();

            try
            {
                XDocument xdoc;
                xdoc = XDocument.Load(xmlFile);
                calls = (from a in xdoc.Descendants("Call")
                         where a.Element("TrafficType").Value == ConvertTrafficType(trafficType)
                         orderby a.Element("Date").Value descending
                         select new Calls
                         {
                             GUID = new Guid(a.Element("GUID").Value),
                             Phone = a.Element("Phone").Value,
                             Date = new DateTime(long.Parse(a.Element("Date").Value)),
                             TrafficType = ConvertTrafficType(a.Element("TrafficType").Value)
                         }
                         ).ToList();
            }
            catch (Exception)
            {
                return null;
            }
            return calls;
        }
        static public List<Calls> GetAll()
        {
            List<Calls> calls = new List<Calls>();

            try
            {
                XDocument xdoc;
                xdoc = XDocument.Load(xmlFile);
                calls = (from a in xdoc.Descendants("Call")
                         orderby a.Element("Date").Value descending
                         select new Calls
                         {
                             GUID = new Guid(a.Element("GUID").Value),
                             Phone = a.Element("Phone").Value,
                             Date = new DateTime(long.Parse(a.Element("Date").Value)),
                             TrafficType = ConvertTrafficType(a.Element("TrafficType").Value)
                         }
                         ).ToList();
            }
            catch (Exception)
            {
                return null;
            }
            return calls;
        }
        static public bool Add(string phone, TrafficType trafficType)
        {
            XDocument xdoc;
            try
            {
                if (!File.Exists(xmlFile))
                    new XElement("Calls").Save(xmlFile);
            }
            catch (Exception)
            {
                return false;
            }
            finally
            {
                xdoc = XDocument.Load(xmlFile);
                xdoc.Element("Calls").Add(new XElement("Call",
                    new XElement("GUID", Guid.NewGuid().ToString()),
                    new XElement("Date", DateTime.Now.Ticks),
                    new XElement("Phone", phone),
                    new XElement("TrafficType", ConvertTrafficType(trafficType))
                    ));
                xdoc.Save(xmlFile);
                if (CallAdded != null)
                    CallAdded();
            }
            return true;
        }
        public bool Add(Calls call)
        {
            XDocument xdoc;
            try
            {
                if (!File.Exists(xmlFile))
                    new XElement("Calls").Save(xmlFile);
            }
            catch (Exception)
            {
                return false;
            }
            finally
            {
                xdoc = XDocument.Load(xmlFile);
                xdoc.Element("Calls").Add(new XElement("Call",
                    new XElement("GUID", call.guid),
                    new XElement("Date", call.date.Ticks),
                    new XElement("Phone", call.phone),
                    new XElement("TrafficType", ConvertTrafficType(call.trafficType))
                    ));
                xdoc.Save(xmlFile);
                if (trafficType == OsaGateway.TrafficType.Outgoing)
                {
                    if (CallAdded != null)
                        CallAdded();
                }
            }
            return true;
        }
        static public bool Delete(Guid guid)
        {
            try
            {
                XDocument xdoc = XDocument.Load(xmlFile);
                (from a in xdoc.Descendants("Call")
                 where a.Element("GUID").Value == guid.ToString()
                 select a).FirstOrDefault().Remove();
                xdoc.Save(xmlFile);
                if (CallDeleted != null)
                    CallDeleted();
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        static private TrafficType ConvertTrafficType(string trafficTypeString)
        {
            switch (trafficTypeString)
            {
                case "Incomming":
                    return TrafficType.Incomming;
                case "Outgoing":
                    return TrafficType.Outgoing;
            }
            return TrafficType.Undetected;
        }
        static private string ConvertTrafficType(TrafficType trafficType)
        {
            switch (trafficType)
            {
                case TrafficType.Incomming:
                    return "Incomming";
                case TrafficType.Outgoing:
                    return "Outgoing";
            }
            return string.Empty;
        }
    }
}
