using System;
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 digioz.PollSystem;
using System.Collections.Specialized;
using digioz;

public partial class controls_admin_PollManager : System.Web.UI.UserControl
{
    /// <summary>
    /// Rebind the controls (GridView and detailsView) for PollSubject 
    /// </summary>
    /// <param name="bDelete"></param>
    private void BindPollSubject(bool bDelete)
    {
        string lsError2 = "";
        // Update datasource
        PollSubjectInfoList Data =
                    PollSubjectInfoManagement.GetPollSubjectList(out lsError2);

        // Rebind data controls
        dvSubjectDetails.DataSource = Data;
        gdSubjectList.DataSource = Data;
        dvSubjectDetails.DataBind();
        if (bDelete)
        {
            // After deletion, DetailsView automatically reset its index.
            // use this index to re-synch the two controls 
            // (i.e to re-synch DetailsView with gridView)
            gdSubjectList.SelectedIndex = (dvSubjectDetails.PageIndex % gdSubjectList.PageSize);
        }
        gdSubjectList.DataBind();
    }

    private void BindPollSubjectList()
    {
        string lsError = "";
        gdSubjectList.DataSource =
                PollSubjectInfoManagement.GetPollSubjectList(out lsError);
        gdSubjectList.DataBind();
    }

    private void BindPollSubjectDetails()
    {
        string lsError = "";
        dvSubjectDetails.DataSource =
                PollSubjectInfoManagement.GetPollSubjectList(out lsError);
        dvSubjectDetails.DataBind();
    }

    private void HandleDALError(string sError, string sUserError)
    {
        if (sError != string.Empty)
        {
            lblMsg.Visible = true;
            lblMsg.CssClass = "messageError";
            //if (UserPermission.isSuperUser(Convert.ToString(Session["permission"])) || UserPermission.isAdministrator(Convert.ToString(Session["permission"])))
            if (Convert.ToInt16(Session["permission"]) == 1)
            {
                lblMsg.Text = sError;
            }
            else
            {
                lblMsg.Text = sUserError;
            }
        }
    }

    private void SuccessMessage(string sMessage)
    {
        if (sMessage != string.Empty)
        {
            lblMsg.Visible = true;
            lblMsg.CssClass = "messageOk";
            lblMsg.Text = sMessage;
        }
    }

    private void SelectedIndexChanged()
    {
        // Activate DetailsView
        mlvPollManager.ActiveViewIndex = 1;

        // Keep GridView and DetailsView in synch
        dvSubjectDetails_SetIndex();

        if (gdSubjectList.SelectedIndex > -1)
        {
            mnNavigate.Items[1].Enabled = true;
            mnNavigate.Items[2].Enabled = true;

            // Select the detail menu
            mnNavigate.Items[1].Selected = true;
        }
        else
        {
            mnNavigate.Items[1].Enabled = false;
            mnNavigate.Items[2].Enabled = false;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        // Make the "Insert button" consistent with gdSubjectList row
        btnInsertSubject.BackColor = gdSubjectList.RowStyle.BackColor;
        btnInsertSubject.ForeColor = gdSubjectList.RowStyle.ForeColor;
        lblMsg.Visible = false;
        if (!IsPostBack)
        {
            BindPollSubject(false);
        }
        
    }

    /// <summary>
    /// Handle Select buton
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void gdSubjectList_SelectedIndexChanged(object sender, EventArgs e)
    {
        SelectedIndexChanged();
        BindPollSubjectDetails();
        gdOptionList.DataBind();
    }

    protected void gdSubjectList_DataBound(object sender, EventArgs e)
    {
        PollSubjectInfoList loData = (PollSubjectInfoList)gdSubjectList.DataSource;
        if (loData.Count == 0)
        {
            // Disable DetailsView and Options menu 
            //mnNavigate.Items[1].Enabled = false;
            mnNavigate.Items[2].Enabled = false;
            //mlvPollManager.ActiveViewIndex = 0;
        }
    }

    /// <summary>
    /// Handle PollSubject record deletion
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void gdSubjectList_RowDeleting(object sender, 
                                            GridViewDeleteEventArgs e)
    {
        string lsError = "";
        int liSubjectID = Int32.Parse(gdSubjectList.DataKeys[e.RowIndex].Value.ToString());
        if (PollSubjectInfoManagement.DeletePollSubject(liSubjectID,
                                                        out lsError))
        {
            BindPollSubject(true);
            gdOptionList.DataBind();
            SuccessMessage("Poll subject deleted");
        }
        else
        {
            HandleDALError(lsError, "Error deleting poll subject");
        }

    }

    protected void gdSubjectList_PageIndexChanging(object sender, 
                                            GridViewPageEventArgs e)
    {
        gdSubjectList.PageIndex = e.NewPageIndex;
        // Keep GridView and DetailsView in synch
        dvSubjectDetails_SetIndex();
        BindPollSubject(false);
        gdOptionList.DataBind();
    }


    /// <summary>
    /// Handle record selection in the detail view
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void dvSubjectDetails_PageIndexChanged(object sender, EventArgs e)
    {
        // Make the selected record the same in both the gridview and
        // the DetailsView
        gdSubjectList.SelectedIndex = dvSubjectDetails.PageIndex;
    }


    /// <summary>
    /// Update a Poll record in the database
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void dvSubjectDetails_ItemUpdating(object sender, 
                                                DetailsViewUpdateEventArgs e)
    {
        Trace.Write("dvSubjectDetails_ItemUpdating");
        string lsError = "";
        PollSubjectInfo loPsi = new PollSubjectInfo();
        OrderedDictionary loEditedValues = new OrderedDictionary();

        // Get the values entered by the user
        foreach (DetailsViewRow row in dvSubjectDetails.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                foreach (DataControlFieldCell cell in row.Cells)
                {
                    cell.ContainingField.ExtractValuesFromCell(
                                   loEditedValues,
                                   cell,
                                   DataControlRowState.Edit,
                                   true);

                }
            }
        }

        loPsi.ID = int.Parse(loEditedValues["ID"].ToString());
        loPsi.SubjectName = loEditedValues["SubjectName"].ToString();
        loPsi.SecretBallot = bool.Parse(loEditedValues["SecretBallot"].ToString());
        loPsi.Closed = bool.Parse(loEditedValues["Closed"].ToString());
        loPsi.SubjectDeadline = DateTime.Parse(loEditedValues["SubjectDeadline"].ToString());
        loPsi.SubjectDescription = loEditedValues["SubjectDescription"].ToString();

        if (PollSubjectInfoManagement.UpdatePollSubject(
                                                    loPsi, 
                                                    out lsError))
        {
            string lsError2 = "";
            dvSubjectDetails.ChangeMode(dvSubjectDetails.DefaultMode);
            // Update datasource
            PollSubjectInfoList Data =
                        PollSubjectInfoManagement.GetPollSubjectList(out lsError2);
            // Rebind data controls
            dvSubjectDetails.DataSource = Data;
            gdSubjectList.DataSource = Data;
            dvSubjectDetails.DataBind();
            gdSubjectList.DataBind();
            SuccessMessage("Poll subject updated");
        }
        else
        {
            HandleDALError(lsError, "Error updating poll subject");
        }
    }

    /// <summary>
    /// Insert a new PollSubject into the database
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void dvSubjectDetails_ItemInserting(object sender,
                                            DetailsViewInsertEventArgs e)
    {
        int liNewPollSubjectID = 0;
        string lsError = "";
        digioz.PollSystem.PollSubjectInfo loPsi =
            new digioz.PollSystem.PollSubjectInfo();
        OrderedDictionary loInsertedValues = new OrderedDictionary();

        // Get the values entered by the user
        foreach (DetailsViewRow row in dvSubjectDetails.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                foreach (DataControlFieldCell cell in row.Cells)
                {
                    cell.ContainingField.ExtractValuesFromCell(
                                   loInsertedValues, 
                                   cell,
                                   DataControlRowState.Insert|DataControlRowState.Alternate,
                                   true);

                }
            }
        }

        // Insert the values into the database
        loPsi.SubjectName = loInsertedValues["SubjectName"].ToString();
        loPsi.SecretBallot = bool.Parse(loInsertedValues["SecretBallot"].ToString());
        loPsi.SubjectDeadline = DateTime.Parse(loInsertedValues["SubjectDeadline"].ToString());
        loPsi.SubjectDescription = loInsertedValues["SubjectDescription"].ToString();

        if (PollSubjectInfoManagement.InsertPollSubject(loPsi,
                                             out liNewPollSubjectID,
                                             out lsError))
        {
            string lsError2 = "";
            dvSubjectDetails.ChangeMode(dvSubjectDetails.DefaultMode);
            
            // Update datasource
            PollSubjectInfoList Data = 
                        PollSubjectInfoManagement.GetPollSubjectList(out lsError2);
 
            // set index to the newly added record (Select new index)
            //int liIndex = Data.Find(liNewPollSubjectID);
            // Find the record whose "SubjectID" = liNewPollSubjectID
            int liIndex = Data.Find("ID", liNewPollSubjectID);
            gdSubjectList.SelectedIndex =  liIndex %  gdSubjectList.PageSize;
            gdSubjectList.PageIndex = liIndex / gdSubjectList.PageSize;
            dvSubjectDetails.DataSource = Data;
            gdSubjectList.DataSource = Data;

            // Handle SelectedIndexChanged and Rebind data controls
            SelectedIndexChanged();
            dvSubjectDetails.DataBind();
            gdSubjectList.DataBind();
            gdOptionList.DataBind();
            SuccessMessage("Poll subject added");
        }
        else
        {
            HandleDALError(lsError, "Error inserting new poll subject");
        }

    }

    

    protected void dvSubjectDetails_ItemDeleting(object sender, 
                                                DetailsViewDeleteEventArgs e)
    {
        string lsError = "";
        int liSubjectID = int.Parse(dvSubjectDetails.DataKey["ID"].ToString());
        if (PollSubjectInfoManagement.DeletePollSubject(liSubjectID,
                                                        out lsError))
        {
            BindPollSubject(true);
            gdOptionList.DataBind();
            SuccessMessage("Poll subject deleted");
        }
        else
        {
            HandleDALError(lsError, "Error deleting poll subject");
        }

    }


    /// <summary>
    /// Perform Display mode change et reset control if necessary
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void dvSubjectDetails_ModeChanging(object sender,
                                 DetailsViewModeEventArgs e)
    {
        dvSubjectDetails.ChangeMode(e.NewMode);
      
        // If canceling action, reset the control
        if (e.CancelingEdit == true)
        {
            dvSubjectDetails_SetIndex();
        }

        //dvSubjectDetails.DataBind();
        BindPollSubjectDetails();
    }

    private void dvSubjectDetails_SetIndex()
    {
        dvSubjectDetails.PageIndex = gdSubjectList.SelectedIndex + 
                          (gdSubjectList.PageIndex * gdSubjectList.PageSize);
    }

    protected void mnNavigate_MenuItemClick(object sender, MenuEventArgs e)
    {
        switch(e.Item.Value)
        {
            case "Subject List":
                mlvPollManager.ActiveViewIndex = 0;
                break;
            case "Subject Details":
                mlvPollManager.ActiveViewIndex = 1;
                if (dvSubjectDetails.Rows.Count == 0)
                {
                    // Put the detail view in insert mode
                    dvSubjectDetails.ChangeMode(DetailsViewMode.Insert);
                }
                break;
            case "Option List":
                mlvPollManager.ActiveViewIndex = 2;
                gdOptionList.Caption = this.PollCaption();
                btnSaveOptions.Enabled = true;
                btnAddNew.Enabled = true;
                break;
        }
    }

    /// <summary>
    /// Save all the changes (Edit) at one.
    /// Editing changes are saved in batch
    /// (Delete and Insertion are Instantaneous)
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnSaveOptions_Click(object sender, EventArgs e)
    {
        if (Page.IsValid)
        {
            // Loop through options List and check which ones need saving
            foreach (GridViewRow row in gdOptionList.Rows)
            {
                CheckBox cbSave = (CheckBox)row.FindControl("cbSave");
                if (cbSave.Checked)
                {
                    TextBox loOptionName = (TextBox)row.FindControl("TxtOptionName");
                    Label loOptionID = (Label)row.FindControl("TxtOptionID");
                    Label loSubjectID = (Label)row.FindControl("TxtSubjectID");
                    objDataSourceOption.UpdateParameters.Clear();
                    objDataSourceOption.UpdateParameters.Add("SubjectID", loSubjectID.Text);
                    objDataSourceOption.UpdateParameters.Add("OptionID", loOptionID.Text);
                    objDataSourceOption.UpdateParameters.Add("OptionName", loOptionName.Text);
                    objDataSourceOption.UpdateParameters.Add("sError", "");
                    objDataSourceOption.Update();
                }
            }
        }
    }

    protected void objDataSourceOption_Updating(object sender, 
                                ObjectDataSourceMethodEventArgs e)
    {
        IDictionary paramsFromPage = e.InputParameters;
        digioz.PollSystem.PollOptionInfo loPoi =
            new digioz.PollSystem.PollOptionInfo();

        loPoi.ID = int.Parse(paramsFromPage["OptionID"].ToString());
        loPoi.SubjectID = int.Parse(paramsFromPage["SubjectID"].ToString());
        loPoi.OptionName = paramsFromPage["OptionName"].ToString();
        
        paramsFromPage.Clear();
        paramsFromPage.Add("option", loPoi);
        paramsFromPage.Add("sError", "");
    }

    protected void objDataSourceOption_Inserting(object sender, 
                    ObjectDataSourceMethodEventArgs e)
    {
        IDictionary paramsFromPage = e.InputParameters;
        digioz.PollSystem.PollOptionInfo loPoi =
            new digioz.PollSystem.PollOptionInfo();
        loPoi.SubjectID = int.Parse(paramsFromPage["SubjectID"].ToString());
        loPoi.OptionName = paramsFromPage["OptionName"].ToString();

        paramsFromPage.Clear();
        paramsFromPage.Add("option", loPoi);
        paramsFromPage.Add("sError", "");
    }

    protected void objDataSourceOption_Deleting(object sender, 
                                ObjectDataSourceMethodEventArgs e)
    {
       e.InputParameters.Add("sError", "");
    }


    /// <summary>
    /// Handle the Inserted event on the ObjectDataSource
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void objDataSourceOption_Inserted(object sender, 
                                                ObjectDataSourceStatusEventArgs e)
    {
        // if insertion failed
        if ((bool)e.ReturnValue == false)
        {
            if ((string)e.OutputParameters["sError"] != string.Empty)
            {
                HandleDALError((string)e.OutputParameters["sError"], 
                               "Error adding poll option");
            }
        }
        else
        {
            // Hide the insertion row
            //gdOptionList.ShowFooter = false;
            OptionListInsertionMode(false);
            SuccessMessage("Poll option added");
        }
    }

    /// <summary>
    /// A poll option record has been deleted in the database
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void objDataSourceOption_Deleted(object sender, 
                                                ObjectDataSourceStatusEventArgs e)
    {
        // if deletion failed
        if ((bool)e.ReturnValue == false)
        {
            if ((string)e.OutputParameters["sError"] != string.Empty)
            {
                HandleDALError((string)e.OutputParameters["sError"],
                               "Error deleting poll option");
            }
        }
        else
        {
            SuccessMessage("Poll option deleted");
        }
    }

    /// <summary>
    /// A poll option record has been updated in the database
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void objDataSourceOption_Updated(object sender, 
                                                ObjectDataSourceStatusEventArgs e)
    {
        // if update failed
        if ((bool)e.ReturnValue == false)
        {
            if ((string)e.OutputParameters["sError"] != string.Empty)
            {
                HandleDALError((string)e.OutputParameters["sError"],
                               "Error updating poll option");
            }
        }
        else
        {
            SuccessMessage("Poll option updated");
        }
    }

    /// <summary>
    /// "Simulate" a row insertion as if initiated from the detail view
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnInsertSubject_Click(object sender, EventArgs e)
    {
        // Make sure we are in the Subject detail view 
        mlvPollManager.ActiveViewIndex = 1;

        // Select the Subject detail menu
        mnNavigate.Items[1].Enabled = true;
        mnNavigate.Items[1].Selected = true;

        // Put the detail view in insert mode
        dvSubjectDetails.ChangeMode(DetailsViewMode.Insert);
    }

    /// <summary>
    /// Add a poll option to the database
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnAddOption_Click(object sender, EventArgs e)
    {
        // Implemented in gdOptionList_RowCommand
    }

    /// <summary>
    /// Cancel poll option insertion (Hide the insertion row)
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnAddOptionCancel_Click(object sender, EventArgs e)
    {
        OptionListInsertionMode(false);
    }

    /// <summary>
    /// Activate insertion row
    /// This displays an "empty" row in the GridView
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnAddNew_Click(object sender, EventArgs e)
    {
        OptionListInsertionMode(true);
    }

    private void OptionListInsertionMode(bool ShowInsertionRow)
    {
        // No option in gridview. Use "EmptyDataTemplate" logic 
        if (gdOptionList.Rows.Count == 0)
        {
            // gdOptionList.Controls[0] --> System.Web.UI.WebControls.ChildTable
            // gdOptionList.Controls[0].Controls[0] --> GridViewRow
            // TODO: Find alternative to using those harcoded indexes
            HtmlTable table = (HtmlTable)((GridViewRow)gdOptionList.Controls[0].Controls[0]).FindControl("gdOptionListEmpty");
            if (table != null)
            {
                table.Visible = ShowInsertionRow;
            }
        }
        else
        {
            // Use footer of the grid view for the insertion
            gdOptionList.ShowFooter = ShowInsertionRow;
        }

        btnSaveOptions.Enabled = !ShowInsertionRow;
        btnAddNew.Enabled = !ShowInsertionRow;
    }

    /// <summary>
    /// A button is clicked in the gdOptionList gridview
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void gdOptionList_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        // Inserting a poll option record
        if ( ((Control)e.CommandSource).ID == "btnAddOption")
        {
            if (Page.IsValid)
            {
                GridViewRow row = (GridViewRow)((Control)e.CommandSource).NamingContainer;
                if (row != null)
                {
                    TextBox loOptionName = (TextBox)row.FindControl("TxtOptionName");
                    objDataSourceOption.InsertParameters.Clear();
                    objDataSourceOption.InsertParameters.Add("SubjectID", TypeCode.Int32, gdSubjectList.SelectedValue.ToString());
                    objDataSourceOption.InsertParameters.Add("OptionName", loOptionName.Text);
                    objDataSourceOption.InsertParameters.Add("sError", "");
                    objDataSourceOption.Insert();
                }
            }
        }
    }

    /// <summary>
    /// Add a caption to options list that displays the name of the PollSubject
    /// </summary>
    /// <returns></returns>
    private string PollCaption()
    {
        string lsCaption = "";

        if (gdSubjectList.SelectedIndex > -1)
        {
            OrderedDictionary loSelectedPollValues = new OrderedDictionary();
            foreach (DataControlFieldCell cell in gdSubjectList.SelectedRow.Cells)
            {
                cell.ContainingField.ExtractValuesFromCell(
                               loSelectedPollValues,
                               cell,
                               DataControlRowState.Selected,
                               true);

            }
            if (loSelectedPollValues["SubjectName"] != null)
            {
                lsCaption = string.Format("Options for Poll: {0}", 
                                    loSelectedPollValues["SubjectName"].ToString());
            }
        }

        return lsCaption;
    }

    protected void gdOptionList_PreRender(object sender, EventArgs e)
    {
        foreach (GridViewRow row in gdOptionList.Rows)
        {
            if (row.RowType == DataControlRowType.DataRow)
            {
                TextBox tbOptionName = (TextBox)row.FindControl("TxtOptionName");
                if (tbOptionName != null)
                {
                    CheckBox ckSave = (CheckBox)row.FindControl("cbSave");
                    if (ckSave != null)
                    {
                        // Add client script to textbox so that when it changes, 
                        // we can mark the row as a row to be saved
                        string id = ckSave.ClientID;
                        tbOptionName.Attributes.Add("onchange", "OptionChanged('" + id + "')");
                    }
                }
            }
        }
    }
    
}
