using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MetaBuilders.Irc.Messages;
using MetaBuilders.Irc.Network;
using MetaBuilders.Irc;
using System.Text.RegularExpressions;

namespace Grovewood
{
    class Irc
    {
        //ALL IRC RELATED MATERIALS WILL BE HERE
        public static Client IrcClient;
        private static string MasterFile = "./xml/Master.xml";
        public static string cmd = "";
        public static string ChannelName = xml.GetXML(MasterFile, "IRC_Channel");
        public static bool ConStatus = false;

        public static void Connect()
        {
            Form1.ChatAppend("Trying to Establish Connection");

            IrcClient = new Client(xml.GetXML(MasterFile, "IRC_Server"), "Grovewood");
            Ident.Service.User = IrcClient.User;

            // Set up event handlers.
            // Event is raised when the welcome message is sent.
            IrcClient.Messages.Welcome += new EventHandler<IrcMessageEventArgs<WelcomeMessage>>(welcomed);
            // Event is raised when data is received.
            IrcClient.DataReceived += new EventHandler<ConnectionDataEventArgs>(dataReceived);
            // Event raised when data is sent.
            IrcClient.MessageSending += new EventHandler<CancelIrcMessageEventArgs<IrcMessage>>(IrcClient_MessageSending);
            // Event raised on disconnect.
            IrcClient.Connection.Disconnected += new EventHandler<ConnectionDataEventArgs>(clientDisconnect);

            //IrcClient.Messages.VersionReply += new EventHandler<IrcMessageEventArgs<VersionReplyMessage>>(Version);
            IrcClient.EnableAutoIdent = false;

            try
            {
                Form1.ChatAppend("Connecting...");
                IrcClient.Connection.Connect();
                Form1.ChatAppend("Client Connected...");

                while (cmd != "quit")
                {
                    if (cmd == "")
                    {
                        //do nothing
                    }
                    else if ((cmd == "/quit") || (cmd == "quit"))
                    {
                        break;
                    }
                    else if (cmd.StartsWith("/me"))
                    {
                        cmd = cmd.TrimStart('/', 'm', 'e', ' ');
                        IrcClient.SendAction(cmd, ChannelName);
                        Form1.ChatAppend(DateTime.Now.ToString("T") + " *Grovewood> " + cmd);
                        cmd = "";
                    }
                    else
                    {
                        IrcClient.SendChat(cmd, ChannelName);
                        Form1.ChatAppend(DateTime.Now.ToString("T") + " <Grovewood> " + cmd);
                        cmd = "";
                    }

                }

                IrcClient.SendQuit();
                Form1.ChatAppend("Disconnected as Requested...");
            }
            catch (Exception ex)
            {
                Form1.ErrorLog("Connection Error: " + ex.Message);
            }
        }

        static private string[] splitMsg(string msg)
        {
            if (msg.Length > 512)
            {
                string[] msg2 = msg.Split(' ');
                int sendL = msg2.Length / 2;

                //assemble the strings
                string send1 = "";
                string send2 = "";
                for (int i = 0; i < sendL; i++)
                {
                    send1 = msg2[i] + " ";
                }
                for (int i = sendL; i < msg2.Length; i++)
                {
                    send2 = msg2[i] + " ";
                }

                string[] sender = new string[3];
                sender[0] = "3";
                sender[1] = send1;
                sender[2] = send2;
                return sender;
            }
            else
            {
                string[] sender = new string[2];
                sender[0] = "1";
                sender[1] = msg;
                return sender;
            }
        }

        static private void welcomed(Object sender, IrcMessageEventArgs<WelcomeMessage> e)
        {
            Form1.ChatAppend("Welcome message received.");
            IrcClient.SendJoin(xml.GetXML("./xml/Master.xml", "IRC_Channel"));
            ConStatus = true;
            // join the channel
            /*
            IrcClient.SendJoin(xml.GetXML("./server.xml", "CHAN"));
            IrcClient.SendJoin(xml.GetXML("./xml/Packs/" + APack + "/settings.xml", "BOT"));
            int CC = Convert.ToInt32(xml.GetXML("./server.xml", "CC"));
            int i = 1;
            for (i = 1; i <= CC; i++)
            {
                IrcClient.SendJoin(xml.GetXML("./server.xml", "C" + i));
            }
             */
            //IrcClient.SendChat("identify " + xml.GetXML("./server.xml", "PASS"), "nickserv");

            //Multipack.PackJoin();
            //connectionstatus = true;
        }

        static private void dataReceived(Object sender, ConnectionDataEventArgs e)
        {
            string[] ircData = e.Data.Split(' ');
            string channel;
            string[] nick;
            string host = RemoveColon(ircData[0]);
            string msg;

            string IrcNumeric;
            IrcNumeric = ircData[1];
            //Console.WriteLine("RAW, IRCDATA: " + e.Data.ToString());
            if (ircData.Length > 2)
            {
                channel = ircData[2];
                channel = RemoveColon(channel);
                ChannelName = channel;
            }
            else
            {
                channel = ChannelName;
            }

            switch (IrcNumeric)
            {
                case "JOIN":
                    nick = ircData[0].Split('!');
                    nick = nick[0].Split(':');
                    Form1.ChatAppend(nick[1] + " has joined.");
                    break;
                case "QUIT":
                    nick = ircData[0].Split('!');
                    nick = nick[0].Split(':');
                    Form1.ChatAppend(nick[1] + " has Quit the Channel.");
                    break;
                case "PART":
                    nick = ircData[0].Split('!');
                    channel = ircData[2].ToLower();
                    nick = nick[0].Split(':');
                    Form1.ChatAppend(nick[1] + " has Parted the channel " + channel);
                    break;
                case "NOTICE":
                    msg = String.Join(" ", ircData, 3, ircData.GetUpperBound(0) + 1 - 3);
                    nick = ircData[0].Split('!');
                    nick = nick[0].Split(':');
                    msg = msg.Substring(1, msg.Length - 1).ToLower();

                    Form1.ChatAppend("==NOTICE FROM " + nick[1] + "== " + msg);
                    break;
                case "NICK":
                    msg = String.Join(" ", ircData, 3, ircData.GetUpperBound(0) + 1 - 3);
                    nick = ircData[0].Split('!');
                    nick = nick[0].Split(':');
                    string[] msg10 = e.Data.Split(':');
                    Form1.ChatAppend("User: " + nick[1] + " is now known as " + msg10[1] + ".");
                    break;
                case "PRIVMSG":
                    channel = ircData[2].ToLower();
                    msg = String.Join(" ", ircData, 3, ircData.GetUpperBound(0) + 1 - 3);
                    nick = ircData[0].Split('!');
                    nick = nick[0].Split(':');
                    string msg3 = msg.Substring(1, msg.Length - 1);
                    msg = msg.Substring(1, msg.Length - 1);

                    msg = msg.Replace('“', '"');
                    msg = msg.Replace('”', '"');
                    msg = msg.Replace("’", "'");
                    string[] msg2 = msg.Split(' ');

                    //----------------------------------------------------------
                    // FROM THIS POINT ON WE WILL NEED TO START WIKI FORMATTING
                    //----------------------------------------------------------
                    //- STRIP CODES
                    msg = Regex.Replace(msg, @"[\x02\x1F\x0F\x16]|\x03(\d\d?(,\d\d?)?)?", String.Empty);
                    //- /Strip Codes
                    msg = msg.Replace('”', '"');

                    if (msg.Contains("ACTION") == false)
                    {

                        //-- NOT AN ACTION -- NOT AN ACTION -- TEXT ONLY
                        Form1.ChatAppend(DateTime.Now.ToString("T") + " <" + nick[1] + "> " + msg);
                        
                        wiki.CallFormatting(xml.GetXML(MasterFile, "LOG_Format"), DateTime.Now.ToString("T") + " <" + nick[1] + "> " + msg);

                        if ((msg2[0].ToLower() == "!log") && (msg2.Length == 2))
                        {
                            if (msg2[1].ToLower() == "off")
                            {
                                xml.UpdateXML(MasterFile, "LOG_Status", "2");
                                Form1.ChatAppend(DateTime.Now.ToString("T") + " <" + nick[1] + "> IRC Logging Off");
                                IrcClient.SendChat("(Logging System is now Offline.)", ChannelName);
                            }
                            else if (msg2[1].ToLower() == "on")
                            {
                                xml.UpdateXML(MasterFile, "LOG_Status", "1");
                                Form1.ChatAppend(DateTime.Now.ToString("T") + " <" + nick[1] + "> IRC Logging On");
                                IrcClient.SendChat("(Logging System is now Online.)", ChannelName);
                            }
                        }

                        //silent on/off for Tolman with his *** trigger
                        if ((msg.ToLower().Contains("***") == true) && (msg.ToLower().Contains("begins") == true))
                        {
                            //we will turn it on or off
                            xml.UpdateXML(MasterFile, "LOG_Status", "1");
                            Form1.ChatAppend(DateTime.Now.ToString("T") + " <" + nick[1] + "> IRC Logging On");
                            IrcClient.SendChat("(GAME START - Logging System is now Online.)", ChannelName);
                        }
                        else if ((msg.ToLower().Contains("***") == true) && (msg.ToLower().Contains("close") == true))
                        {
                            xml.UpdateXML(MasterFile, "LOG_Status", "2");
                            Form1.ChatAppend(DateTime.Now.ToString("T") + " <" + nick[1] + "> IRC Logging Off");
                            IrcClient.SendChat("(GAME END - Logging System is now Offline.)", ChannelName);
                        }

                        //any other commands will have to be nested here.
                    }
                    else
                    {

                        //ACTION - ACTION - ACTION
                        Form1.ChatAppend(DateTime.Now.ToString("T") + " *" + nick[1] + " " + msg);
                        wiki.CallFormatting(xml.GetXML(MasterFile, "LOG_Format"), DateTime.Now.ToString("T") + " *" + nick[1] + " " + msg);
                        //Formatting options
                        
                    }
                    break;
            }
        }

        

        static private void clientDisconnect(Object sender, ConnectionDataEventArgs e)
        {
            String data = "*** Disconnected: " + e.Data;
            //Console.WriteLine(data);
            ConStatus = false;
            Form1.ChatAppend(data);
            
        }

        private static string RemoveColon(string data)
        {
            if (data.StartsWith(":"))
                return data.Substring(1);
            else
                return data;
        }

        private string JoinString(string[] strData, int startIndex, bool removeColon)
        {
            if (startIndex > strData.GetUpperBound(0)) return "";

            string tempString = String.Join(" ", strData, startIndex, strData.GetUpperBound(0) + 1 - startIndex);
            if (removeColon)
            {
                tempString = RemoveColon(tempString);
            }
            return tempString;
        }

        static void IrcClient_MessageSending(object sender, MetaBuilders.Irc.Messages.CancelIrcMessageEventArgs<MetaBuilders.Irc.Messages.IrcMessage> e)
        {
            string data = e.Message.ToString();
            string[] data2 = data.Split(':');

            if (data.Contains("PONG"))
            {

            }
            else
            {

            }
        }


    }

}
