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

namespace OsaGateway
{
    public enum TrafficType
    {
        Incomming,
        Outgoing,
        Undetected
    }

    public class Message
    {
        public delegate void MessageHandler();
        static public event MessageHandler MessageAdded;
        static public event MessageHandler MessageDeleted;

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

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

        public Message()
        {

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

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

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

            try
            {
                XDocument xdoc;
                xdoc = XDocument.Load(xmlFile);
                messages = (from a in xdoc.Descendants("Message")
                            orderby a.Element("Date").Value descending
                            select new Message
                            {
                                GUID = new Guid(a.Element("GUID").Value),
                                Phone = a.Element("Phone").Value,
                                Text = a.Element("Text").Value,
                                Date = new DateTime(long.Parse(a.Element("Date").Value)),
                                TrafficType = ConvertTrafficType(a.Element("TrafficType").Value)
                            }).ToList();
            }
            catch (Exception)
            {
                return null;
            }
            return messages;
        }
        static public bool Add(string phone, string text, TrafficType trafficType)
        {
            XDocument xdoc;

            try
            {
                if (!File.Exists(xmlFile))
                    new XElement("Messages").Save(xmlFile);
            }
            catch (Exception)
            {
                return false;
            }
            finally
            {
                xdoc = XDocument.Load(xmlFile);
                xdoc.Element("Messages").Add(new XElement("Message",
                    new XElement("GUID", Guid.NewGuid().ToString()),
                    new XElement("Date", DateTime.Now.Ticks),
                    new XElement("Phone", phone),
                    new XElement("Text", text),
                    new XElement("TrafficType", ConvertTrafficType(trafficType))
                    ));
                xdoc.Save(xmlFile);
                if (MessageAdded != null)
                    MessageAdded();
            }
            return true;
        }
        public bool Add(Message message)
        {
            XDocument xdoc;
            try
            {
                if (!File.Exists(xmlFile))
                    new XElement("Messages").Save(xmlFile);
            }
            catch (Exception)
            {
                return false;
            }
            finally
            {
                xdoc = XDocument.Load(xmlFile);
                xdoc.Element("Messages").Add(new XElement("Message",
                    new XElement("GUID", message.guid),
                    new XElement("Date", message.date.Ticks),
                    new XElement("Phone", message.phone),
                    new XElement("Text", message.text),
                    new XElement("TrafficType", ConvertTrafficType(message.trafficType))
                    ));
                xdoc.Save(xmlFile);
                if (trafficType == OsaGateway.TrafficType.Outgoing)
                {
                    if (MessageAdded != null)
                        MessageAdded();
                }
            }
            return true;
        }
        static public bool Delete(Guid guid)
        {
            try
            {
                XDocument xdoc = XDocument.Load(xmlFile);
                (from a in xdoc.Descendants("Message")
                 where a.Element("GUID").Value == guid.ToString()
                 select a).FirstOrDefault().Remove();
                xdoc.Save(xmlFile);
                if (MessageDeleted != null)
                    MessageDeleted();
                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;
        }
    }
}
