using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Aptech.UI;
using System.Data.SqlClient;
using System.Media;

namespace WindowsApplication25
{
    public partial class talk : Form
    {
        DataBase db;
        int fromUserId;  　// 消息的发起者
        int friendFaceId;  // 发消息的好友的头像Id  
        int messageImageIndex = 0;  // 工具栏中的消息图标的索引
        //构造函数部分
        public talk()
        {
            InitializeComponent();
        }
        //窗体初始化加载阶段代码：
        private void talk_Load(object sender, EventArgs e)
        {
           
            //设定外观美化皮肤文件
            skinEngine1.SkinFile = "MSN.ssk";
            //工具栏的消息图标
            toolStripButton4.Image = ilMessage.Images[0];
            //调用方法：ShowSelfInfo()，该方法用于显示个人的信息，见下。           
            ShowSelfInfo();
            //为第三方控件SideBar添加两个组：我的好友和陌生人组
            sideBar1.AddGroup("我的好友");
            sideBar1.AddGroup("陌生人");
            //调用方法：howFriendList()，该方法用于向我的好友组中添加我的好友列表
            ShowFriendList();
            MessageBox.Show("作者：07可视化A班陈苏华，曾乃庆，张浩。", "请尊敬的老师特别注意：版权所有",MessageBoxButtons.OK,MessageBoxIcon.Warning);
        }
        /// <summary>
        /// 该方法用于显示个人的信息
        /// </summary>
        public void ShowSelfInfo()
        {   //初始化DataBase类
            db = new DataBase();
            string nickName = "";  // 昵称
            int faceId = 0;        // 头像索引
            bool miss = false;    // 标识是否出现错误
            string sql = string.Format("SELECT NickName, FaceId FROM Users WHERE Id={0}", ID.Id);
            try
            {
                SqlDataReader reader = db.GetDataReader(sql);
                if (reader.Read())
                {
                    if (!(reader["NickName"] is DBNull))  // 判断数据库类型是否为空
                    {
                        nickName = Convert.ToString(reader["NickName"]);

                    }
                    faceId = Convert.ToInt32(reader["FaceId"].ToString());
                    ID.faceId = faceId;
                }

                reader.Close();
            }
            catch (Exception ex)
            {
                miss = true;
                MessageBox.Show(ex.Message);
            }
            finally
            {
                db.close();
                
            }

            // 根据操作数据库结果进行不同的操作
            if (miss)
            {
                MessageBox.Show("服务器请求失败！请重新登录！", "意外错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
            else
            {
                // 在窗体标题显示登录的昵称、号码
                this.Text = ID.Id.ToString();
                this.pictureBox1.Image = imageList1.Images[faceId];
                this.label1.Text = string.Format("{0}({1})", nickName,ID.Id.ToString());
            }
        }
        /// <summary>
        /// 向我的好友组中添加我的好友列表
        /// </summary>
        public void ShowFriendList()
        {  //初始化DataBase类
            db=new DataBase();
            // 清空原来的列表
            sideBar1.Groups[0].Items.Clear();
            bool miss = false;   // 标识数据库是否出错
            string sql = string.Format(
               "SELECT FriendId,NickName,FaceId FROM Users,Friends WHERE Friends.HostId={0} AND Users.Id=Friends.FriendId",
               ID.Id);
            try
            {
                // 循环添加好友列表
                System.Data.SqlClient.SqlDataReader reader = db.GetDataReader(sql);
                while ( reader.Read())
                {
                    // 创建一个SideBar项
                    SbItem item = new SbItem((string)db.dr["NickName"], (int)db.dr["FaceId"]);
                    item.Tag = (int)db.dr["FriendId"]; // 将号码放在Tag属性中

                    // SideBar中的组可以通过数组的方式访问，按照添加的顺序索引从0开始
                    // Groups[0]表示SideBar中的第一个组，也就是“我的好友”组
                     sideBar1.Groups[0].Items.Add(item); // 向SideBar的“我的好友”组中添加项
                }

                reader.Close();
            }
            catch (Exception ex)
            {
                miss = true;
                MessageBox.Show(ex.Message);
            }
            finally
            {
                db.close();
            }
            // 出错了
            if (miss)
            {
                MessageBox.Show("服务器发生意外错误！请尝试重新登录", "抱歉", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
        }
        // 窗体关闭后，退出应用程序
        private void talk_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }
        //位于底部toolStrip工具条的第一个按钮鼠标单击事件：显示个人信息窗口
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
           set frm= new set();
           frm.ShowDialog();
        }
        //位于底部toolStrip工具条的第二个按钮鼠标单击事件：显示查找好友窗口
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            changefriends frm = new changefriends();
            frm.ShowDialog();
        }
        //位于底部toolStrip工具条的第三个按钮鼠标单击事件：点击刷新好友列表
        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            ShowFriendList();//见下面该事件代码部分
        }
        //位于底部toolStrip工具条的第四个按钮鼠标单击事件：点击显示系统消息
        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            tmrAddFriend.Stop();  // 消息timer停止运行 
            // 图片恢复正常
            messageImageIndex = 0;
            toolStripButton4.Image = ilMessage.Images[0];

            // 显示系统消息窗体
            message frm = new message();
            frm.ShowDialog();
        }
        //位于底部toolStrip工具条的第五个按钮鼠标单击事件：退出聊天窗体
        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            DialogResult result = MessageBox.Show("确实要退出吗？", "操作确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (result == DialogResult.Yes)
            {
                Application.Exit();
            }
        }
        //第三方控件SideBar鼠标双击事件：发送消息时钟控件停止运行，显示聊天窗体
        private void sideBar1_ItemDoubleClick(SbItemEventArgs e)
        {
            // timer控件tmrChatRequest停止运行，即发送消息时钟控件停止运行。
            if (tmrChatRequest.Enabled == true)
            {
                tmrChatRequest.Stop();
                e.Item.ImageIndex = this.friendFaceId ;
            }
            // 显示聊天窗体
            talk_about frm = new talk_about();
            frm.friendId = Convert.ToInt32(e.Item.Tag);
            frm.nickName = e.Item.Text;
            frm.faceId = e.Item.ImageIndex+1;
            frm.ShowDialog();
        }
        //第三方控件SideBar中任何组件发生变化时候事件：判别一旦有消息，则使得声音发生变换
        private void sideBar1_VisibleGroupChanged(SbGroupEventArgs e)
        {
            SoundPlayer player = new SoundPlayer("folder.wav");//建立声音播放控件对象player
            player.Play();//播放加载声音
        }
        //快捷菜单控件cmsFriendList一旦发生下拉列表事件时候触发下面代码
        private void cmsFriendList_Opening(object sender, CancelEventArgs e)
        {
            // 第三方控件SideBar中如果没有选中的项，则快捷菜单中的删除项隐藏
            if (sideBar1.SeletedItem == null)
            {
                tsmiDelete.Visible = false;
            }
            else
            {
                tsmiDelete.Visible = true;//反之快捷菜单中的删除项显示
            }
            // 第三方控件SideBar中如果选中的是陌生人，则显示加为好友菜单
            if (sideBar1.SeletedItem != null && sideBar1.SeletedItem.Parent == sideBar1.Groups[1])
            {
                tsmiAddFriend.Visible = true;
            }
            else
            {
                tsmiAddFriend.Visible = false;//反之加为好友菜单不显示
            }
        }
        //一旦鼠标左键点击快捷菜单cmsFriendList中的“小头像”项目，则触发下面代码
        private void tsmiView_Click(object sender, EventArgs e)
        {
            //如果第三方控件SideBar中视图方式为大图标，则显示方式改为小图标
            if (sideBar1.View == SbView.LargeIcon)
            {
                sideBar1.View = SbView.SmallIcon;
                tsmiView.Text = "显示大头像";//并将tsmiView显示文本改为“显示大头像”
            }
            //如果第三方控件SideBar中视图方式为小图标，则显示方式改为大图标
            else if (sideBar1.View == SbView.SmallIcon)
            {
                sideBar1.View = SbView.LargeIcon;
                tsmiView.Text = "显示小头像";//并将tsmiView显示文本改为“显示小头像”
            }
        }
        //一旦鼠标左键点击快捷菜单cmsFriendList中的“加为好友”项目，则触发下面代码
        private void tsmiAddFriend_Click(object sender, EventArgs e)
        {
            int result = 0;  // 操作结果
            string sql = string.Format("INSERT INTO Friends (HostId, FriendId) VALUES({0},{1})",ID.Id, Convert.ToInt32(sideBar1.SeletedItem.Tag));
            try
            {
                db.open();
                SqlCommand command = new SqlCommand(sql, db.connection);
                result = command.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                db.close();
            }
            if (result == 1)
            {
                MessageBox.Show("添加成功！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                sideBar1.SeletedItem.Parent.Items.Remove(sideBar1.SeletedItem);
                ShowFriendList();   // 更新好友列表             
            }
            else
            {
                MessageBox.Show("添加失败，请稍候再试！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        //一旦鼠标左键点击快捷菜单cmsFriendList中的“删除”项目，则触发下面代码
        private void tsmiDelete_Click(object sender, EventArgs e)
        {
            DialogResult result;   // 对话框结果
            int deleteResult = 0;  // 操作结果
            if (sideBar1.SeletedItem != null)          
            {
                result = MessageBox.Show("确实要删除该好友吗？", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.Yes) // 确认删除
                {
                    if (sideBar1.VisibleGroup == sideBar1.Groups[0])
                    {
                        string sql = string.Format("DELETE FROM Friends WHERE HostId={0} AND FriendId={1}",ID.Id, Convert.ToInt32(sideBar1.SeletedItem.Tag));
                        try
                        {
                            db.open();
                            SqlCommand command = new SqlCommand(sql, db.connection);
                            deleteResult = command.ExecuteNonQuery();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }
                        finally
                        {
                            db.close();
                        }
                        if (deleteResult == 1)
                        {
                            MessageBox.Show("好友已删除", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            sideBar1.SeletedItem.Parent.Items.Remove(sideBar1.SeletedItem);
                        }
                    }
                    else
                    {
                        MessageBox.Show("好友已删除", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        sideBar1.SeletedItem.Parent.Items.Remove(sideBar1.SeletedItem);
                    }
                }
            }
        }
        /// <summary>
        /// 建立事件talk_Activated，该方法用于将imageList1图片列表控件中用户选择的头像图片显示给pictureBox1中的图像属性
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void talk_Activated(object sender, EventArgs e)
        {
            pictureBox1.Image = imageList1.Images[ID.faceId];
        }
        // 时间控件tmrMessage的Tick事件：该事件用于定时扫描数据库，找到发给登录用户的任何未读消息
        private void tmrMessage_Tick(object sender, EventArgs e)
        {
            db = new DataBase();
            ShowFriendList();       // 刷新好友列表
            int messageTypeId = 1;  // 消息类型
            int messageState = 1;   // 消息状态
            SqlCommand command;
            // 找出未读消息对应的好友Id
            string sql = string.Format("SELECT Top 1 FromUserId, MessageTypeId, MessageState FROM Messages WHERE ToUserId={0} AND MessageState=0",ID.Id);
            // 消息有两种类型：聊天消息、添加好友消息
            try
            {
                db.open();
                SqlDataReader dataReader = db.GetDataReader(sql);
                // 循环读出一个未读消息
                if (dataReader.Read())
                {
                    this.fromUserId = (int)dataReader["FromUserId"];
                    messageTypeId = (int)dataReader["MessageTypeId"];
                    messageState = (int)dataReader["MessageState"];
                }
                dataReader.Close();
            }
            catch (Exception ex)
            {
              MessageBox.Show(ex.Message);
            }
            finally
            {
                db.close();
            }

            // 判断消息类型，如果是添加好友消息，就启动喇叭timer，让小喇叭闪烁
            if (messageTypeId == 2 && messageState == 0)
            {
                SoundPlayer player = new SoundPlayer("system.wav");
                player.Play();
                tmrAddFriend.Start();
            }
            // 如果是聊天消息，就启动聊天timer，让好友头像闪烁
            else if (messageTypeId == 1 && messageState == 0)
            {
                // 获得发消息的人的头像Id
                sql = "SELECT FaceId FROM Users WHERE Id=" + this.fromUserId;
                try
                {
                    db.open();
                    command = new SqlCommand(sql, db.connection);
                    this.friendFaceId = Convert.ToInt32(command.ExecuteScalar());// 设置发消息的好友的头像索引
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
                finally
                {
                    db.close();
                }
                // 如果发消息的人没有在列表中就添加到陌生人列表中
                if (!HasShowUser(fromUserId))
                {
                    UpdateStranger(fromUserId);
                }
                SoundPlayer player = new SoundPlayer("msg.wav");
                player.Play();
                tmrChatRequest.Start();  // 启动闪烁头像定时器
            }
        }
        /// <summary>
        /// 判断发消息的人是否在列表中
        /// </summary>
        /// <param name="loginId"></param>
        /// <returns>返回值为布尔类型：True表示发消息的人已在列表中，False为发消息的人不在列表中</returns>
        private bool HasShowUser(int loginId)
        {
            bool find = false;  // 表示是否在当前显示出的用户列表中找到了该用户

            // 循环 SideBar 中的2个组，寻找发消息的人是否在列表中
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < sideBar1.Groups[i].Items.Count; j++)
                {
                    if (Convert.ToInt32(sideBar1.Groups[i].Items[j].Tag) == loginId)
                    {
                        find = true;
                    }
                }
            }
            return find;
        }
        /// <summary>
        /// 更新陌生人列表
        /// </summary>
        /// <param name="loginId">输入参数：用户登录后用户主键ID</param>
        private void UpdateStranger(int loginId)
        {
            // 选出这个人的基本信息
            string sql = "SELECT NickName, FaceId FROM Users WHERE Id=" + loginId;
            bool error = false; // 用来标识是否出现错误
            try
            {
                SqlDataReader dataReader = db.GetDataReader(sql); // 查询
                if (dataReader.Read())
                {
                    SbItem item = new SbItem((string)dataReader["NickName"], (int)dataReader["FaceId"]);
                    item.Tag = this.fromUserId;           // 将Id记录在Tag属性中
                    sideBar1.Groups[1].Items.Add(item);  // 向陌生人组中添加项
                }
                sideBar1.VisibleGroup = sideBar1.Groups[1];  // 设定陌生人组为可见组
            }
            catch (Exception ex)
            {
                error = true;
                MessageBox.Show(ex.Message);
            }
            finally
            {
                db.close();
            }
            // 出错了
            if (error)
            {
                MessageBox.Show("服务器出现意外错误！", "抱歉", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        ///  时间控件tmrChatRequest的Tick事件：该事件用于找到发消息的好友，并让他的头像闪烁
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmrChatRequest_Tick(object sender, EventArgs e)
        {
            //循环好友列表两个组中的每个item，找到发消息的好友，让他的头像闪烁
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < sideBar1.Groups[i].Items.Count; j++)
                {
                    if (Convert.ToInt32(sideBar1.Groups[i].Items[j].Tag) == this.fromUserId)
                    {
                        if (sideBar1.Groups[i].Items[j].ImageIndex < 100)
                        {
                            sideBar1.Groups[i].Items[j].ImageIndex = 100;// 索引为100的图片是一个空白图片
                        }
                        else
                        {
                            sideBar1.Groups[i].Items[j].ImageIndex = this.friendFaceId;
                        }
                       sideBar1.Invalidate();  // 重新绘制，只要告诉学生需要这句话才能正常闪烁头像就行
                    }
                }
            }
        }
        /// <summary>
        /// 时间控件tmrAddFriend的Tick事件：该事件用于判别是否有未读消息，如果有则toolStrip1底部工具条之中的系统消息图标闪烁
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void tmrAddFriend_Tick(object sender, EventArgs e)
        {
            // 反复修改它的图像
            messageImageIndex = messageImageIndex == 0 ? 1 : 0;
            toolStripButton4.Image = ilMessage.Images[messageImageIndex];
        }        
    }
}