using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace TCPServer
{
    public partial class Users : Form
    {
        private ServerData data;
        private bool Refreshing = false;

        public Users(ServerData Data)
        {
            InitializeComponent();
            data = Data;
        }

        private void Users_Shown(object sender, EventArgs e)
        {
            RefreshUserGrid();
            RefreshIngoingGrid();
            RefreshOutgoingGrid();
        }

        public void RefreshUserRow(int index)
        {
            UsersDataGridView.Rows[index].Cells["UserID"].Value = data.Users[index].ID;
            UsersDataGridView.Rows[index].Cells["Email"].Value = data.Users[index].Email;
            UsersDataGridView.Rows[index].Cells["Credits"].Value = data.Users[index].Credits;
            UsersDataGridView.Rows[index].Cells["Status"].Value = (data.Users[index].Connection == null)
                                                                ? ""
                                                                : "connected";
        }

        public void AddUserRow(User iUser)
        {
            var index = UsersDataGridView.Rows.Add();
            data.Users.Add(iUser);
            RefreshUserRow(index);
        }

        public void DeleteUserRow(int index)
        {
            RemoveUser(index);
            UsersDataGridView.Rows.RemoveAt(index);
        }

        public void RefreshUserGrid()
        {
            UsersDataGridView.Rows.Clear();
            Monitor.Enter(data.Users);
            if (data.Users.Count > 0)
                UsersDataGridView.Rows.Add(data.Users.Count);
            for (int i = 0; i < data.Users.Count; i++)
            {
                RefreshUserRow(i);
            }
            Monitor.Exit(data.Users);
        }

        public int GetUserIndex()
        {
            var row = UsersDataGridView.CurrentRow;
            return (row == null) ? -1 : row.Index;
        }

        public void RefreshIngoingRow(int index)
        {
            var userindex = GetUserIndex();
            if(userindex>=0){
               MailData inmail = data.Users[userindex].IncomingMail[index];
               IngoingDataGridView.Rows[index].Cells["InID"].Value = inmail.ID;
               IngoingDataGridView.Rows[index].Cells["InFrom"].Value = inmail.From;
               IngoingDataGridView.Rows[index].Cells["InStamp"].Value = inmail.Stamp;
               IngoingDataGridView.Rows[index].Cells["InTime"].Value = inmail.TimeStamp;
            }
        }

        public void DeleteIngoingRow(int index)
        {
            var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                data.Users[userindex].IncomingMail.RemoveAt(index);
            }
        }

        public void RefreshIngoingGrid()
        {
            IngoingDataGridView.Rows.Clear();
            var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                data.Users[userindex].IncomingMail = data.database.GetIncomingMail(data.Users[userindex].ID);
                if (data.Users[userindex].IncomingMail.Count > 0)
                    IngoingDataGridView.Rows.Add(data.Users[userindex].IncomingMail.Count);
                for (int i = 0; i < data.Users[userindex].IncomingMail.Count; i++)
                {
                    RefreshIngoingRow(i);
                }
            }
        }

        public void RefreshOutgoingRow(int index)
        {
            var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                MailData outmail = data.Users[userindex].OutgoingMail[index];
                OutgoingDataGridView.Rows[index].Cells["OutID"].Value = outmail.ID;
                OutgoingDataGridView.Rows[index].Cells["OutTo"].Value = outmail.To;
                OutgoingDataGridView.Rows[index].Cells["OutStamp"].Value = outmail.Stamp;
                OutgoingDataGridView.Rows[index].Cells["OutTime"].Value = outmail.TimeStamp;
            }
        }

        public void DeleteOutgoingRow(int index)
        {
            var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                data.Users[userindex].OutgoingMail.RemoveAt(index);
            }
        }

        public void RefreshOutgoingGrid()
        {
            OutgoingDataGridView.Rows.Clear();
            var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                data.Users[userindex].OutgoingMail = data.database.GetOutgoingMail(data.Users[userindex].ID);
                if (data.Users[userindex].OutgoingMail.Count > 0)
                    OutgoingDataGridView.Rows.Add(data.Users[userindex].OutgoingMail.Count);
                for (int i = 0; i < data.Users[userindex].OutgoingMail.Count; i++)
                {
                    RefreshOutgoingRow(i);
                }
            }
        }

        private void UsersDataGridView_SelectionChanged(object sender, EventArgs e)
        {
            if (Refreshing)
                return;
            RefreshIngoingGrid();
            RefreshOutgoingGrid();
        }

        private void UsersDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            var cell = UsersDataGridView[e.ColumnIndex, e.RowIndex];
            switch (UsersDataGridView.Columns[e.ColumnIndex].Name)
            {
                case "Email":
                    data.Users[e.RowIndex].Email = cell.Value.ToString();
                    break;
                case "Credits":
                    int res = 0;
                    if (Int32.TryParse(cell.Value.ToString(), out res))
                        data.Users[e.RowIndex].Credits = res;
                    break;

            }
            data.database.ChangeUser(data.Users[e.RowIndex].ID, data.Users[e.RowIndex].Email, data.Users[e.RowIndex].Credits);
            RefreshUserRow(e.RowIndex);
        }

        private void IngoingDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            /*var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                MailData maildata = data.Users[userindex].IncomingMail[e.RowIndex];
                var cell = IngoingDataGridView[e.ColumnIndex, e.RowIndex];
                switch (IngoingDataGridView.Columns[e.ColumnIndex].Name)
                {
                    case "InFrom":
                        maildata.From = cell.Value.ToString();
                        break;
                    case "InStamp":
                        maildata.Stamp = cell.Value.ToString();
                        break;
                }
                RefreshIngoingRow(e.RowIndex);
            }*/
        }

        private void OutgoingDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            /*var userindex = GetUserIndex();
            if (userindex >= 0)
            {
                MailData maildata = data.Users[userindex].OutgoingMail[e.RowIndex];
                var cell = OutgoingDataGridView[e.ColumnIndex, e.RowIndex];
                switch (OutgoingDataGridView.Columns[e.ColumnIndex].Name)
                {
                    case "OutTo":
                        maildata.To = cell.Value.ToString();
                        break;
                    case "OutStamp":
                        maildata.Stamp = cell.Value.ToString();
                        break;
                }
                RefreshOutgoingRow(e.RowIndex);
            }*/
        }

        public void RemoveUser(int index)
        {
            var con = data.Users[index].Connection;
            if (con != null)
            {
                Monitor.Enter(con);
                con.User = null;
                Monitor.Exit(con);
            }
            data.Users.RemoveAt(index);
        }
        
        private void UsersDataGridView_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
        {
            Refreshing = true;
            Monitor.Enter(data.Users);
            RemoveUser(e.Row.Index);
            Monitor.Exit(data.Users);
            Refreshing = false;
        }

        private void AddButton_Click(object sender, EventArgs e)
        {
            Refreshing = true;
            Monitor.Enter(data.Users);            
            int id = data.database.InsertUser("", 0);
            var user = new User(id, "", 0);
            AddUserRow(user);
            Monitor.Exit(data.Users);
            Refreshing = false;
        }

        private void RemoveButton_Click(object sender, EventArgs e)
        {
            Refreshing = true;
            if (UsersDataGridView.CurrentCell != null)
            {
                int RowId = UsersDataGridView.CurrentCell.RowIndex;
                Monitor.Enter(data.Users);
                data.database.DeleteUser(data.Users[RowId].ID);
                DeleteUserRow(RowId);
                Monitor.Exit(data.Users);
            }
            Refreshing = false;
        }

    }
}
