using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using agsXMPP;
using agsXMPP.protocol.client;

namespace ISIM
{
    public enum CallStatus { callUnsupported, none, ringingContact, incommingCall, isLive };

    public interface ISIMContact
    {
        string id { get; }
        string name { get; set; }
        Global.Availability availability { get; set; }
        string protocol { get; }
        string client { get; set; }
        bool isComposingMessage { get; set; }
        bool unreadedMessage { get; set; }
        object contactObject { get; }
        bool elisActive { get; set; }
    }

    public class XmppContact : ISIMContact
    {
        string _identificator;
        ContactObject _contactObject;
        string _protocolName;

        public XmppContact(string jid, string name, ContactObject contactObject, string protocolName, string client, PresenceType presence = PresenceType.error)
        {
            _identificator = jid;
            this.name = name;
            availability = Global.Converter.GetContactAvailability(presence);
            _contactObject = contactObject;

            _protocolName = protocolName;
            this.client = client;
        }

        public string id
        {
            get { return _identificator; }
        }

        public string name
        {
            get;
            set;
        }

        public Global.Availability availability
        {
            get;
            set;
        }

        public object contactObject
        {
            get { return _contactObject; }
        }


        public string protocol
        {
            get { return _protocolName; }
        }

        public string client
        {
            get;
            set;
        }

        public bool isComposingMessage { get; set; }

        public bool unreadedMessage { get; set; }

        public class ContactObject
        {
            private XmppClientConnection _xmppClient;
            private string protocolName;

            public ContactObject(string protocolName)
            {
                this.protocolName = protocolName;
            }

            public XmppClientConnection xmppClient
            {
                get
                {
                    Global.OpenForms.mainForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                    {
                        XmppClass xmpp = null;
                        if (protocolName == "jabber")
                            xmpp = Global.OpenForms.mainForm.jabber;
                        if (protocolName == "facebook")
                            xmpp = Global.OpenForms.mainForm.fb;
                        if (protocolName == "gtalk")
                            xmpp = Global.OpenForms.mainForm.gt;

                        if (xmpp != null)
                            _xmppClient = xmpp.xmppClient;
                    }));

                    return _xmppClient;
                }
            }
        }


        public bool elisActive
        {
            get;
            set;
        }
    }


    public class IcqContact : ISIMContact
    {
        ContactObject contactObj;

        public IcqContact(IcqSharp.Base.Contact contact)
        {
            contactObj = new ContactObject(contact);
            availability = Global.Converter.GetContactAvailability(contact.Status);
        }

        public string id
        {
            get { return contactObj.contact.Uin; }
        }

        public string name
        {
            get
            {
                if (contactObj.contact.Nickname != null)
                    return contactObj.contact.Nickname;
                else
                    return contactObj.contact.Uin;
            }
            set { }
        }

        public Global.Availability availability
        {
            get;
            set;
        }

        public object contactObject
        {
            get { return contactObj; }
        }

        public string protocol
        {
            get { return "ICQ"; }
        }

        public string client
        {
            get { return "ICQ"; }
            set { }
        }

        public bool isComposingMessage { get; set; }

        public bool unreadedMessage { get; set; }


        public class ContactObject
        {
            private IcqSharp.Session _session;
            private IcqSharp.Base.Contact _contact;

            public ContactObject(IcqSharp.Base.Contact contact)
            {
                if (contact.Nickname == null)
                    contact.Nickname = contact.Uin;

                _contact = contact;
            }

            public IcqSharp.Session session
            {
                get
                {
                    Global.OpenForms.mainForm.Invoke(new System.Windows.Forms.MethodInvoker(() =>
                    {
                        _session = Global.OpenForms.mainForm.icq.session;
                    }));

                    return _session;
                }
            }

            public IcqSharp.Base.Contact contact
            {
                get { return _contact; }
            }
        }


        public bool elisActive
        {
            get;
            set;
        }
    }

    
    /// <summary>
    /// Porovnává nejdřív podle dostupnosti a pak podle jména. Jednoduše přičte ke jménu dostupnost a porovná -> 1David. Je to do 6tky takže neřešim :P
    /// </summary>
    public class ISIMcontactComparer : IComparer
    {
        public int Compare(object x, object y)
        {
            int result = -1;
            try
            {
                string c1 = (int)(x as ContactListViewItem).contact.availability + Global.Converter.GetRenamedContactName((x as ContactListViewItem).contact);
                string c2 = (int)(y as ContactListViewItem).contact.availability + Global.Converter.GetRenamedContactName((y as ContactListViewItem).contact);

                result = string.Compare(c1, c2);
            }
            catch (NullReferenceException)
            {
                result = -1;
            }
            return result;
        }
    }
}
