// static method for serialization from the AdminQuestion to the byte array
        public static byte[] Serialize(AdminQuestion quest)
        {
            IFormatter formatter = new BinaryFormatter();
            Stream stream = new MemoryStream();

            formatter.Serialize(stream, quest);

            byte[] buffer = ((MemoryStream)stream).ToArray();

            return buffer;
        }
        // static method for the deserialization from byte array to a AdminQuestion
        public static AdminQuestion Deserialize(byte[] buffer)
        {
            AdminQuestion que = new AdminQuestion();

            Stream strm = new MemoryStream(buffer);

            IFormatter frr = new BinaryFormatter();

            que = (AdminQuestion)frr.Deserialize(strm);

            return que;
        }
        public List<AdminQuestion> GetAdminStats()
        {
            List<AdminQuestion> list = new List<AdminQuestion>();
            List<int> toFill = new List<int>();

            string query = "SELECT useranswer.QuestionID as id, QuestionContext, avg(Time),"
                + " COUNT(*) / ((SELECT COUNT(*) FROM useranswer WHERE Time = 0 AND useranswer.QuestionID = id) + COUNT(*)) as Answered"
                + " FROM useranswer INNER JOIN Question on Question.QuestionID = Useranswer.QuestionID"
                + " WHERE Time > 0"
                + " GROUP BY useranswer.QuestionID;";

            this.command.CommandText = query;
            this.connection.Open();
            this.reader = this.command.ExecuteReader();

            int counter = 0;

            while (this.reader.Read())
            {
                counter++;

                AdminQuestion q = new AdminQuestion();

                q.number = Convert.ToInt32(this.reader["id"]);
                q.content = this.reader["QuestionContext"].ToString();
                q.avgTime = Convert.ToDouble(this.reader["avg(Time)"]);
                q.answered = Convert.ToDouble(this.reader["Answered"]);
                list.Add(q);

                while (q.number != counter)
                {
                    toFill.Add(counter);
                    counter++;
                }
            }

            if (this.connection.State == System.Data.ConnectionState.Open)
            {
                this.connection.Close();
            }

            if (toFill.Count > 0)
            {
                for (int i = 0; i < toFill.Count; i++)
                {
                    AdminQuestion q = new AdminQuestion();
                    q.number = toFill[i];
                    q.content = this.GetQuestion(toFill[i]).content;
                    q.avgTime = 0;
                    q.answered = 0;

                    list.Add(q);
                }

                list.Sort(
                       delegate (AdminQuestion q1, AdminQuestion q2)
                       {
                           return q1.number.CompareTo(q2.number);
                       }
                   );
            }

            return list;
        }
        private void AdminInteraction(User admin)
        {
            string message = "";

            while (true)
            {
                try
                {
                    message = this.connector.Read(admin.socket);
                }
                catch (Exception e)
                {
                    Logging.LogEvent("AdminInteraction", e.Message);
                    break;
                }

                Logging.LogEvent("AdminInteraction", "User #" + admin.id + " said -> " + message);

                if (message == "")
                {
                    int count = 1;
                    while (true)
                    {
                        string nMessage = connector.Read(admin.socket);
                        if (nMessage == "")
                        {
                            count++;
                        }
                        else
                        {
                            break;
                        }
                        if (count > 20)
                        {
                            message = TCPIPconnector.kClientLeft;
                            break;
                        }
                    }
                }

                if (message == "!leaderboard")
                {
                    List<TriviaLib.User> list = null;

                    try
                    {
                        list = this.DBConnector.GetLeaderBoard();
                    }
                    catch (Exception e)
                    {
                        Logging.LogEvent("AdminInteraction", e.Message);
                        break;
                    }

                    try
                    {
                        for (int counter = 0; counter < list.Count; counter++)
                        {
                            this.connector.Send(TriviaLib.User.Serialize(list[counter]), admin.socket);
                            this.connector.Read(admin.socket);
                        }
                        this.connector.Send(TriviaLib.User.Serialize(new TriviaLib.User()), admin.socket);
                    }
                    catch (Exception e)
                    {
                        Logging.LogEvent("AdminInteraction", e.Message);
                        break;
                    }
                }

                if (message == "!data")
                {
                    List<AdminQuestion> list;

                    if (TriviaServer.answerID > 1)
                    {
                        try
                        {
                            list = this.DBConnector.GetAdminStats();

                            if (list.Count < 10)
                            {
                                for (int i = list[(list.Count - 1)].number; i < 10; i++)
                                {
                                    AdminQuestion q = new AdminQuestion();
                                    q.number = i + 1;
                                    q.content = this.DBConnector.GetQuestion(i + 1).content;
                                    q.avgTime = 0;
                                    q.answered = 0;

                                    list.Add(q);
                                }
                            }
                        }
                        catch(Exception e)
                        {
                            Logging.LogEvent("AdminInteraction", e.Message);
                            break;
                        }
                    }
                    else
                    {
                        list = new List<AdminQuestion>();
                    }

                    try
                    {
                        for (int counter = 0; counter < list.Count; counter++)
                        {
                            list[counter].answered = list[counter].answered * 100;
                            this.connector.Send(AdminQuestion.Serialize(list[counter]), admin.socket);
                            this.connector.Read(admin.socket);
                        }
                        this.connector.Send(AdminQuestion.Serialize(new AdminQuestion()), admin.socket);
                    }
                    catch (Exception e)
                    {
                        Logging.LogEvent("AdminInteraction", e.Message);
                        break;
                    }
                }

                if (message.Length > 5)
                {
                    if ((message.Substring(0, 5) == "!edit") && (message.Length > 5))
                    {
                        int qId = Convert.ToInt32(message.Substring(5));

                        if (qId < 11)
                        {
                            Question q = new Question();
                            try
                            {
                                q = this.DBConnector.GetQuestion(qId);
                            }
                            catch (Exception e)
                            {
                                Logging.LogEvent("AdminInteraction", e.Message);
                                break;
                            }

                            byte[] buffer = Question.Serialize(q);
                            Question newQuestion = new Question();

                            try
                            {
                                this.connector.Send(buffer, admin.socket);

                                newQuestion = Question.Deserialize(this.connector.ReadObject(admin.socket));
                            }
                            catch (Exception e)
                            {
                                Logging.LogEvent("AdminInteraction", e.Message);
                                break;
                            }

                            if ((q.content != newQuestion.content)
                                    || (q.answer != newQuestion.answer)
                                    || (q.a != newQuestion.a)
                                    || (q.b != newQuestion.b)
                                    || (q.c != newQuestion.c)
                                    || (q.d != newQuestion.d))
                            {
                                newQuestion.number = q.number;
                                try
                                {
                                    this.DBConnector.ChangeQuestion(newQuestion);
                                }
                                catch (Exception e)
                                {
                                    Logging.LogEvent("AdminInteraction", e.Message);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            Question q = new Question();

                            byte[] buffer = Question.Serialize(q);

                            try
                            {
                                this.connector.Send(buffer, admin.socket);
                            }
                            catch (Exception e)
                            {
                                Logging.LogEvent("AdminInteraction", e.Message);
                                break;
                            }
                        }
                    }
                }

                if (message == "!live")
                {
                    try
                    {
                        for (int counter = 0; counter < this.userList.Count; counter++)
                        {
                            TriviaLib.User u = new TriviaLib.User();
                            u.name = this.userList[counter].name;
                            u.currentQuestion = this.userList[counter].currentQuestion;
                            u.totalPoints = this.userList[counter].totalScore;

                            this.connector.Send(TriviaLib.User.Serialize(u), admin.socket);
                            this.connector.Read(admin.socket);
                        }
                        this.connector.Send(TriviaLib.User.Serialize(new TriviaLib.User()), admin.socket);
                    }
                    catch (Exception e)
                    {
                        Logging.LogEvent("AdminInteraction", e.Message);
                        break;
                    }
                }

                if (message == TCPIPconnector.kClientLeft)
                {
                    Logging.LogEvent("AdminInteraction", "Client #" + admin.id + " left");
                    break;
                }
            }
        }