using System;
using System.IO;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using digioz;

public partial class controls_PrivateMessages : System.Web.UI.UserControl
{
    public string csEncryptionKey = ConfigurationManager.AppSettings["DBEncryptKey"];
    public string csEncryptionVector = ConfigurationManager.AppSettings["DBEncryptVector"];
    public string csURLEncryptionKey = ConfigurationManager.AppSettings["URLEncryptKey"];
    public string csPrivateMessageView;
    public string csMode;
    public string psMsgview = "I";
    public string csPageProfile;
    private int ciPriMsg_IDDel;
    private string psFromDate;
    private string psToDate;
    private bool pbDeleteExt = false;

    const long MAX_LENGTH = 40000;

    protected void Page_Load(object sender, EventArgs e)
    {
        // Encode URL String for Grid display ---------------------------------------------
            csPrivateMessageView = Server.UrlEncode(digioz.Encryption64.Encrypt("Private Messages", csURLEncryptionKey));
            // Check for Login ----------------------------------------------------------

            if (Session["userid"] == null || Convert.ToString(Session["userid"]) == String.Empty)
            {
                Response.Redirect("Login.aspx");
            }

            int liUserID = Convert.ToInt16(Session["userid"]);

            if (Convert.ToString(Request.QueryString["msgview"]) != null)
            {
                psMsgview = Convert.ToString(Request.QueryString["msgview"]);
            }
            else
            {
                psMsgview = "I";
            }

            //javascript to count the number of characters in the message box
            txtMessage.Attributes.Add("onkeypress", "countChars('" + txtMessage.ClientID + "','" + lblCharCount.ClientID + "'," + MAX_LENGTH + ")");

            //Load default tab (inbox)
            LoadTabPMList(liUserID, psMsgview);

            //encrypt link to user profile page
            csPageProfile = Server.UrlEncode(digioz.Encryption64.Encrypt("Profile", csURLEncryptionKey));

            //Confirm delete
            btnDeleteView.Attributes.Add("onclick", "return ConfirmOnDelete();"); //attach the JavaScript function
            chkDeleteExt.Attributes.Add("onclick", "if(this.checked)return ConfirmDeleteExt();"); //attach the JavaScript function

            if (Convert.ToString(Request.QueryString["MsgID"]) != null)
            {
                LoadTabPMView(Convert.ToInt16(Request.QueryString["MsgID"]), Convert.ToString(Request.QueryString["msgview"]));
            }
    }

    private void LoadTabPMList(int liUserID, string psMsgview)
    {
        //Load the list of messages in the inbox (default) or outbox.
        //Default delete flag to "false"
         pbDeleteExt = false;
        PrivateMessageList loPrivateMessageList = PrivateMessageManagement.GetPrivateMessageList(liUserID, psMsgview, pbDeleteExt);

        if (loPrivateMessageList.Count == 0)
        {
            if (psMsgview == "O")
            {
                lblInfoMessageO.Text = "Your private message outbox is empty.";
                lblInfoMessageI.Text = "";
                grdPMessagesO.DataSource = loPrivateMessageList;
                grdPMessagesO.DataBind();
            }
            else
            {
                lblInfoMessageI.Text = "Your private message inbox is empty.";
                lblInfoMessageO.Text = "";
                grdPMessagesI.DataSource = loPrivateMessageList;
                grdPMessagesI.DataBind();
            }
        }
        else
        {
            if (psMsgview == "O")
            {
                grdPMessagesO.DataSource = loPrivateMessageList;
                grdPMessagesO.DataBind();
                grdPMessagesO.Visible = true;
                mvPM.ActiveViewIndex = 1;
            }
            else
            {
                grdPMessagesI.DataSource = loPrivateMessageList;
                grdPMessagesI.DataBind();
                grdPMessagesI.Visible = true;
                mvPM.ActiveViewIndex = 0;
            }
        }

    }

    protected void grdPMessagesI_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header) //check for RowType
        {
            Button b = (Button)e.Row.FindControl("BtnDeleteI"); //access the LinkButton from the Header TemplateField using FindControl
            b.Attributes.Add("onclick", "return ConfirmOnDelete();"); //attach the JavaScript function
        }
    }

    protected void grdPMessagesO_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header) //check for RowType
        {
            Button b = (Button)e.Row.FindControl("BtnDeleteO"); //access the LinkButton from the Header TemplateField using FindControl
            b.Attributes.Add("onclick", "return ConfirmOnDelete();"); //attach the JavaScript function
        }
    }

    protected void chkDeleteI_CheckedChanged(object sender, EventArgs e)
    {
        //action taken if delete button is clicked in PMList tab
        StringCollection scMsgList = new StringCollection();
        string lsMsgID = string.Empty;

        for (int i = 0; i < grdPMessagesI.Rows.Count; i++)//loop the GridView Rows
        {
            CheckBox lcbMsgID = (CheckBox)grdPMessagesI.Rows[i].Cells[0].FindControl("chkDeleteI"); //find the CheckBox
            if (lcbMsgID != null)
            {
                if (lcbMsgID.Checked)
                {
                    lsMsgID = grdPMessagesI.Rows[i].Cells[1].Text; // get the id of the field to be deleted
                    scMsgList.Add(lsMsgID); // add the id to be deleted in the StringCollection
                }
            }
        }
        PrivateMessageManagement.deletePrivateMessage(scMsgList);
        grdPMessagesI.DataBind();    // Bind GridView to reflect changes made here
        Response.Redirect("Default.aspx?page=" + Server.UrlEncode(digioz.Encryption64.Encrypt("Private Messages", csURLEncryptionKey)) + "&msgview=I");
    }

    protected void chkDeleteO_CheckedChanged(object sender, EventArgs e)
    {
        //action taken if delete button is clicked in PMList tab
        StringCollection scMsgList = new StringCollection();
        string lsMsgID = string.Empty;

        for (int i = 0; i < grdPMessagesO.Rows.Count; i++)//loop the GridView Rows
        {
            CheckBox lcbMsgID = (CheckBox)grdPMessagesO.Rows[i].Cells[0].FindControl("chkDeleteO"); //find the CheckBox
            if (lcbMsgID != null)
            {
                if (lcbMsgID.Checked)
                {
                    lsMsgID = grdPMessagesO.Rows[i].Cells[1].Text; // get the id of the field to be deleted
                    scMsgList.Add(lsMsgID); // add the id to be deleted in the StringCollection
                }
            }
        }

        PrivateMessageManagement.deletePrivateMessage(scMsgList);
        grdPMessagesO.DataBind();    // Bind GridView to reflect changes made here
        Response.Redirect("Default.aspx?page=" + Server.UrlEncode(digioz.Encryption64.Encrypt("Private Messages", csURLEncryptionKey)) + "&msgview=O");
    }

    protected void topMenu_MenuItemClick(object sender, MenuEventArgs e)
    {
        int liUserID = Convert.ToInt16(Session["userid"]);

        mvPM.ActiveViewIndex = Int32.Parse(e.Item.Value);

        if (mvPM.ActiveViewIndex == 0)
        {
            LoadTabPMList(liUserID, "I");
        }
        else if (mvPM.ActiveViewIndex == 1)
        {
            LoadTabPMList(liUserID, "O");
        }
        else if (mvPM.ActiveViewIndex == 2)
        {
            LoadTabPMNew(liUserID);
        }
        else if (mvPM.ActiveViewIndex == 4)
        {
            LoadTabPMSave(liUserID);
        }
    }

    private void LoadTabPMNew(int liUserID)
    {
        mvPM.ActiveViewIndex = 2;
        ddlTo.Attributes.Add("onchange", "Choice('" + ddlTo.ClientID + "','" + txtTo.ClientID + "')");
        populateToBox();
    }

    private void LoadTabPMSave(int liUserID)
    {
        mvPM.ActiveViewIndex = 4;
        rlSelect.SelectedValue = "Received";
    }

    private void LoadTabPMView(int ciPriMsg_ID, string csMsgview)
    {
        mvPM.ActiveViewIndex = 3;
        PrivateMessageList loPrivateMessage = PrivateMessageManagement.GetPrivateMessage(ciPriMsg_ID, csMsgview);

        if (loPrivateMessage.Count == 0)
        {
            lblInfoMessage.ForeColor = System.Drawing.Color.Red;
            lblInfoMessage.Font.Bold = true;
            lblInfoMessage.Text = "The message could not be retrieved.";
        }
        else
        {
            lstMessage.DataSource = loPrivateMessage;
            lstMessage.DataBind();
            ciPriMsg_IDDel = ciPriMsg_ID;

            // We will mark the message as read only if they are displayed
            // in the inbox
            if (csMsgview == "I")
            {
                MarkMessageAsRead(loPrivateMessage);
            }
        }

    }

    protected void btnSubmitNew_Click(object sender, EventArgs e)
    {
        csMode = Convert.ToString(Request.QueryString["mode"]);
        int liUserID = Convert.ToInt16(Session["userid"]);
        string lsSubject = txtSubject.Text;
        string lsMessage = txtMessage.Text;
        DateTime ldCurrentDateTime = DateTime.Now;
        string lsDateTime = ldCurrentDateTime.ToString();
        string lsTmpRURL = Convert.ToString(Session["referringURL"]);

        if (lsSubject == String.Empty)
        {
            lblPrompt.Text = "Please enter a subject.";
            txtSubject.Focus();
            mvPM.ActiveViewIndex = 2;
            return;
        }
        else if (lsMessage == String.Empty)
        {
            lblPrompt.Text = "Please enter a message.";
            txtMessage.Focus();
            mvPM.ActiveViewIndex = 2;
            return;
        }
        else if (txtTo.Text == string.Empty)
        {
            lblPrompt.Text = "Please enter a recipient.";
            txtTo.Focus();
            mvPM.ActiveViewIndex = 2;
            return;
        }

        //check that "to" is a valid user
        int liToUser;
        string[] lsUserList = txtTo.Text.Split(';');
        foreach (string lsToUser in lsUserList)
        {
            try
            {
                //if (lsToUser != null)
                if (lsToUser.Trim() != "")
                {
                    liToUser = UserManagement.GetUserByUsername(lsToUser.Trim()).ID;
                }
            }
            catch
            {
                lblPrompt.Text = "Recipient " + lsToUser + " does not exist.";
                txtTo.Focus();
                mvPM.ActiveViewIndex = 2;
                return;
            }
        }

        foreach (string lsToUser in lsUserList)
        {
            if (lsToUser.Trim() != "")
            {
                liToUser = UserManagement.GetUserByUsername(lsToUser.Trim()).ID;

                string lsFromUser = UserManagement.GetUserByID(liUserID).Username.ToString();

                PrivateMessage loPrivateMessage = new PrivateMessage();

                loPrivateMessage.PriMsg_title = lsSubject;
                loPrivateMessage.PriMsg_message = lsMessage;
                loPrivateMessage.Sent_time = Convert.ToDateTime(lsDateTime);
                loPrivateMessage.Create_time = Convert.ToDateTime(lsDateTime);
                loPrivateMessage.To_userID = liToUser;
                loPrivateMessage.To_username = txtTo.Text;
                loPrivateMessage.From_userID = liUserID;
                loPrivateMessage.From_username = lsFromUser;

                if (csMode == "reply")
                {
                    PrivateMessageManagement.InsertPrivateMessage(loPrivateMessage, "reply");
                }
                else
                {
                    PrivateMessageManagement.InsertPrivateMessage(loPrivateMessage, "post");
                }
            }
        }

        Response.Redirect("Default.aspx?page=" + Server.UrlEncode(digioz.Encryption64.Encrypt("Private Messages", csURLEncryptionKey)) + "&msgview=I");
    }
    protected void btnCancelNew_Click(object sender, EventArgs e)
    {
        Response.Redirect("Default.aspx?page=" + Server.UrlEncode(digioz.Encryption64.Encrypt("Private Messages", csURLEncryptionKey)) + "&msgview=I");
    }

    protected void btnDeleteView_Click(object sender, EventArgs e)
    {
        StringCollection scPriMsg_ID = new StringCollection();
        scPriMsg_ID.Add(ciPriMsg_IDDel.ToString());

        PrivateMessageManagement.deletePrivateMessage(scPriMsg_ID);
        int liUserID = Convert.ToInt16(Session["userid"]);
        LoadTabPMList(liUserID, psMsgview);
    }
    protected void btnExtract_Click(object sender, EventArgs e)
    {
        int liUserID = Convert.ToInt16(Session["userid"]);
        if (rlSelect.SelectedValue == "Sent")
        {
            psMsgview = "O";
        }
        else
        {
            psMsgview = "I";
        }
        extractMsg(psMsgview, liUserID);
    }
    protected void extractMsg(string psMsgview, int liUserID)
    {
        PrivateMessageList loPrivateMessageList;
        pbDeleteExt = chkDeleteExt.Checked;
        psFromDate = calFrom.SelectedDate.ToString();
        psToDate = calTo.SelectedDate.ToString();
        if (psFromDate != DateTime.MinValue.ToString())
        {
            //if a "from" date is selected, default "to" date to today
            if (psToDate == DateTime.MinValue.ToString())
            {
                psToDate = DateTime.Now.ToString();
            }
            loPrivateMessageList = PrivateMessageManagement.GetPrivateMessageList(liUserID, psMsgview, psFromDate, psToDate, pbDeleteExt);
        }
        else
        {
            loPrivateMessageList = PrivateMessageManagement.GetPrivateMessageList(liUserID, psMsgview, pbDeleteExt);
        }

        if (loPrivateMessageList.Count == 0)
        {
            lblInfoMsgX.Text = "No messages matched your selection.";
        }
        else
        {
            lblInfoMsgX.Text = "";
        }

        //Create the return memorystream object that will hold the buffered data.
        MemoryStream ReturnStream = new MemoryStream();

        //Create a streamwriter to write to the memory stream
        StreamWriter swMsg = new StreamWriter(ReturnStream);

        StringBuilder sbMsg = new StringBuilder(50);

        foreach (PrivateMessage PMsg in loPrivateMessageList)
        {
            sbMsg.Append("From:  ");
            sbMsg.Append(PMsg.From_username);
            sbMsg.Append("\r\n");
            sbMsg.Append("To:  ");
            sbMsg.Append(PMsg.To_username);
            sbMsg.Append("\r\n");
            sbMsg.Append("Sent:  ");
            sbMsg.Append(PMsg.Sent_time);
            sbMsg.Append("\r\n");
            sbMsg.Append("Subject:  ");
            sbMsg.Append(PMsg.PriMsg_title);
            sbMsg.Append("\r\n");
            sbMsg.Append(PMsg.PriMsg_message);
            sbMsg.Append("\r\n");
            sbMsg.Append("------------------------------\r\n");
        }

        //write the data to the memory stream
        //swMsg.WriteLine(sbMsg);

        //generate filename
        string lsFileName;
        DateTime fileDate = System.DateTime.Now;
        string lsDate = (fileDate.ToString("d"));
        string lsTime = (fileDate.ToString("T"));
        if (psMsgview == "I")
        {
            lsFileName = "received_" + lsDate + lsTime;
        }
        else
        {
            lsFileName = "sent_" + lsDate + lsTime;
        }

        lsFileName = Regex.Replace(lsFileName, " ", "");
        lsFileName = Regex.Replace(lsFileName, "/", "");
        lsFileName = Regex.Replace(lsFileName, ":", "");
        lsFileName = lsFileName.Substring(0, lsFileName.Length - 2);

        //send file to user
        Response.Clear();
        Response.ContentType = "application/octet-stream";
        Response.AppendHeader("content-disposition", "attachment; filename=" + lsFileName + ".txt");
        Response.Flush();
        Response.Write(sbMsg);
        Response.End();

        //delete messages if user opted
        if (chkDeleteExt.Checked)
        {
            if (psFromDate != DateTime.MinValue.ToString())
            {
                PrivateMessageManagement.deletePrivateMessageList(liUserID, psMsgview, psFromDate, psToDate);
            }
            else
            {
                PrivateMessageManagement.deletePrivateMessageList(liUserID, psMsgview);
            }
        }

        //reset selection criteria
        calFrom.SelectedDate = DateTime.MinValue;
        calTo.SelectedDate = DateTime.MinValue;
        chkDeleteExt.Checked = false;

        //Clean up the stream writer
        swMsg.Flush();
        swMsg.Close();

        //go back to default inbox
        Response.Redirect("Default.aspx?page=" + Server.UrlEncode(digioz.Encryption64.Encrypt("Private Messages", csURLEncryptionKey)) + "&msgview=I");

    }   //end extractMsg

    //Get list of users for drop-down
    public void populateToBox()
    {
        ddlTo.DataSource = UserManagement.GetUserList();
        ddlTo.DataValueField = "Username";
        ddlTo.DataTextField = "Username";
        ddlTo.DataBind();
    }   //end populateToBox

    protected void calFrom_OnVisibleMonthChanged(object sender, MonthChangedEventArgs e)
    {
        mvPM.ActiveViewIndex = 4;
    }

    protected void calTo_OnVisibleMonthChanged(object sender, MonthChangedEventArgs e)
    {
        mvPM.ActiveViewIndex = 4;
    }

    protected void calFrom_SelectionChanged(object sender, EventArgs e)
    {
        mvPM.ActiveViewIndex = 4;
        lblFromDate.Text = calFrom.SelectedDate.ToShortDateString();
    }
    protected void calTo_SelectionChanged(object sender, EventArgs e)
    {
        mvPM.ActiveViewIndex = 4;
        lblToDate.Text = calTo.SelectedDate.ToShortDateString();
    }

    /// <summary>
    /// Mark messages that have been displayed as read.
    /// </summary>
    /// <param name="poPrivateMessage"></param>
    private void MarkMessageAsRead(PrivateMessageList poPrivateMessage)
    {
        foreach (PrivateMessage message in poPrivateMessage)
        {
            message.ReadFlag = "1";
            message.View_time = DateTime.Now;
            PrivateMessageManagement.UpdatePrivateMessage(message);
        }
    }

    /// <summary>
    /// This sets the url that points to the sender ofthe private message
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void lstMessage_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        if (e.Item.ItemType == ListItemType.Item ||
            e.Item.ItemType == ListItemType.AlternatingItem)
        {
            DataListItem theItem = e.Item;
            string lsSenderName = ((PrivateMessage)e.Item.DataItem).From_username;
            HyperLink lnMessageSender = (HyperLink)e.Item.FindControl("linkSender");
            lnMessageSender.NavigateUrl = String.Format("../Default.aspx?page={0}&username={1}",
                                                 csPageProfile,
                                                 HttpUtility.UrlEncode(digioz.Encryption64.Encrypt(lsSenderName, csURLEncryptionKey)));
        }
    }
}



