using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using Microsoft.Windows.Controls;
using System.Data;
using System.ComponentModel;

// Foo Namespace
using Foo.WorkspaceMgr;
using Foo.DataAccessLayer;
using Foo.DataAccessLayer.DataTypes;
using Foo.GUILib;

namespace Foo.ClientServices.GUIWPForms
{    
    /// <summary>
    /// Interaction logic for WorkspaceSelector_StandardPage.xaml
    /// </summary>
    public partial class WorkspaceSelector_StandardPage : Page
    {
        // passed to us by parent
        private WorkspaceSelector m_WorkspaceSelectorObj = null;
        private bool m_bPerformanceCache = false;        

        // WorkspaceMgr - Imp
        private WorkspaceMgr.WorkspaceMgr m_WorkspaceMgr = null;

        // private DT holds all information needed for the DataGrid
        public DataTable WorkspacesDT { get; private set; }        

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="bPerformanceCache"></param>
        public WorkspaceSelector_StandardPage(bool bPerformanceCache)
        {
            // We preload & require the WorkspaceMgr in this class
            m_WorkspaceMgr = new WorkspaceMgr.WorkspaceMgr();

            // Preload Database call - to make sure it is fast when the user sees it
            String[] workspaceNames = Data.Workspace.GetAllWorkspaceNames(SortOrderForWorkspaces.Ascending);

            m_bPerformanceCache = bPerformanceCache;
            if (!m_bPerformanceCache)
            {                
            }

            InitializeComponent();
        }           
                       
        /// <summary>
        /// Called when we want to Update the DataGrid with new DataTable Items
        /// ~Responsible for reloading the WorkspacesDT
        /// </summary>
        private void UpdateWorkspaceGridItems(SortOrderForWorkspaces sortOrder)
        {            
            // First Step - Clear the Grid
            WorkspacesDT.Rows.Clear();

            // Second Step - Fill the Grid with the WorkspaceNames
            String[] workspaceNames = Data.Workspace.GetAllWorkspaceNames(sortOrder);

            int i = 0;
            int selectedIndex = -1;
            foreach (string workspaceName in workspaceNames)
            {
                var row = WorkspacesDT.NewRow();
                WorkspacesDT.Rows.Add(row);
                row["WorkspaceName"] = workspaceName;
                row["ButtonResUri"] = "PageImages/Launch.png";//"PageImages/Launch.png";
                row["ButtonToolTipText"] = "Launch This Workspace";

                // Let's Determine which index is supposed to be selected
                if (!String.IsNullOrEmpty(GUIState.LastSelectedWorkspaceName) &&
                    (workspaceName == GUIState.LastSelectedWorkspaceName))
                    selectedIndex = i;                    

                i = i + 1; // incr.
            } 

            // Third Step - Refresh The DataGrid                                    
            dataGridWorkspaces.ItemsSource = WorkspacesDT.DefaultView;
            // Other ways to refresh * appears to not be needed here * could be useful later
            //dataGridWorkspaces.ItemsSource = (WorkspacesDT as IListSource).GetList();
            //dataGridWorkspaces.Items.Refresh(); 

            // Fourth Step - Reset the ColumnWidth of the WorkspaceName if no Scrollbar is visible
            if (workspaceNames.Length <= 13)
            {
                // scrollbar not visible
                DataGridLength gridbuffer = new DataGridLength(188 + 18);
                dataGridWorkspaces.Columns[0].Width = gridbuffer;
            }
            else
            {
                // scrollbar visible
                DataGridLength gridbuffer = new DataGridLength(188);
                dataGridWorkspaces.Columns[0].Width = gridbuffer;
            }

            // Fifth Step - Set the Selected Index of the DataGrid to the last set
            //              Workspace Or 0 if not found
            if (selectedIndex >= 0)
                dataGridWorkspaces.SelectedIndex = selectedIndex;
            else
                dataGridWorkspaces.SelectedIndex = 0;
        }

        #region Page Events

        /// <summary>
        /// Called when the Page is loaded
        /// </summary>
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            if (!m_bPerformanceCache)
            {
                // Make sure that the Selector Frame is big enough to hold this page
                m_WorkspaceSelectorObj = (WorkspaceSelector)this.Tag;
                m_WorkspaceSelectorObj.Height = this.Height + m_WorkspaceSelectorObj.MarginTopBottom;
                m_WorkspaceSelectorObj.Width = this.Width;

                // InitializeWorkspaceDT
                WorkspacesDT = new DataTable("WorkspaceData");
                WorkspacesDT.Columns.Add(new DataColumn("WorkspaceName", typeof(string)));                
                WorkspacesDT.Columns.Add(new DataColumn("ButtonResUri", typeof(string)));
                WorkspacesDT.Columns.Add(new DataColumn("ButtonToolTipText", typeof(string)));

                // Set Workspaces Label
                lblCurrentWorkspace.Content = "Workspaces";

                // Load ComboBox Sort Orders
                comboBoxSortBy.Items.Add(WPFHelper.CreateAComboBoxItem("Sort By Last Accessed", SortOrderForWorkspaces.LastAccessedDescending));
                comboBoxSortBy.Items.Add(WPFHelper.CreateAComboBoxItem("Sort By Most Frequently Used", SortOrderForWorkspaces.MostFrequentlyAccessedDescending));
                comboBoxSortBy.Items.Add(WPFHelper.CreateAComboBoxItem("Sort By Name", SortOrderForWorkspaces.Ascending));

                // Load GUI State (or Default Index)
                comboBoxSortBy.SelectedIndex = GUIState.LastSelectedSotOrderWorkspacesIndex;

                // Assign ToolTips for the Buttons
                btnNew.ToolTip = WPFHelper.CreateNewStringToolTip("New Workspace", 0, 120);
                btnEdit.ToolTip = WPFHelper.CreateNewStringToolTip("Rename Workspace", 0, 120);
                btnDelete.ToolTip = WPFHelper.CreateNewStringToolTip("Delete Workspace", 0, 120);
                btnCloseAll.ToolTip = WPFHelper.CreateNewStringToolTip("Close All Workspaces", 0, 120);
            }
        }

        #endregion

        #region ComboBox Events

        /// <summary>
        /// Combo Box - SortBy - Selection Change Event * Deal with repopulating the Workspace Datagrid
        /// </summary>        
        private void comboBoxSortBy_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox combobox = sender as ComboBox;
            if (combobox != null)
            {
                ComboBoxItem item = (ComboBoxItem)combobox.SelectedItem;
                string Content = item.Content.ToString();
                SortOrderForWorkspaces sortOrder = (SortOrderForWorkspaces)item.Tag;

                // Save the State Information * Last SortOrder and Last SortOrder Index *
                GUIState.LastSelectedSotOrderWorkspaces = sortOrder;
                GUIState.LastSelectedSotOrderWorkspacesIndex = combobox.SelectedIndex;

                // Update The Grid
                UpdateWorkspaceGridItems(sortOrder);                
            }
        }

        #endregion

        #region DataGrid Events

        /// <summary>
        /// Upon double-click we should be launching the Workspace (unload any previously loaded ones)
        /// </summary>        
        private void dataGridWorkspaces_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (!String.IsNullOrEmpty(strWorkspaceName))
            {

            }                       
        }               

        /// <summary>
        /// Selection changed - Keep track of last selected workspace in GUIState
        /// </summary>        
        private void dataGridWorkspaces_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {
            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (!String.IsNullOrEmpty(strWorkspaceName))
                GUIState.LastSelectedWorkspaceName = strWorkspaceName;
        }

        /// <summary>
        /// Get Whatever Workspace the User currently has selected in the Grid
        /// </summary>
        /// <returns>Selected Workpsace Or Empty String if there is none</returns>
        private string dataGrid_GetSelectedWorkspaceIfThereIsOne()
        {
            String strWorkspaceName = String.Empty;

            // We only allow single selection
            IList<DataGridCellInfo> cells = dataGridWorkspaces.SelectedCells;
            if (cells.Count > 0)
            {
                DataGridCellInfo cell = cells[0];
                DataRowView row = (DataRowView)cell.Item;
                strWorkspaceName = row["WorkspaceName"].ToString();
            }
            return strWorkspaceName;
        } 

        /// <summary>
        /// Creates the DataGrid Context Menu according to the Selected Workspace State
        /// </summary>
        /// <returns>valid Context Menu or Null</returns>
        private ContextMenu dataGrid_CreateDataGridContextMenu()
        {
            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (!String.IsNullOrEmpty(strWorkspaceName))
            {
                // We also want to load the state of the workspace here
                ContextMenu menu = new ContextMenu();
                menu.PlacementTarget = this;

                // Load all the MenuItems 
                MenuItem m1 = new MenuItem();
                m1.Header = "Launch";
                m1.Click += new RoutedEventHandler(ContextMenu_Item_Click);
                m1.FontWeight = FontWeights.Bold;
                m1.Icon = WPFHelper.CreateWPFImageFromRelativeResourceUri("PageImages/Launch.png", 16, 16);
                menu.Items.Add(m1);

                MenuItem m2 = new MenuItem();
                m2.Header = "Show";
                m2.Click += new RoutedEventHandler(ContextMenu_Item_Click);
                m2.Icon = WPFHelper.CreateWPFImageFromRelativeResourceUri("PageImages/Hide.png", 16, 16);
                menu.Items.Add(m2);

                MenuItem m3 = new MenuItem();
                m3.Header = "Hide";
                m3.Click += new RoutedEventHandler(ContextMenu_Item_Click);
                m3.Icon = WPFHelper.CreateWPFImageFromRelativeResourceUri("PageImages/Hide.png", 16, 16);
                menu.Items.Add(m3);

                MenuItem m4 = new MenuItem();
                m4.Header = "Close";
                m4.Click += new RoutedEventHandler(ContextMenu_Item_Click);
                m4.Icon = WPFHelper.CreateWPFImageFromRelativeResourceUri("PageImages/Close.png", 16, 16);
                menu.Items.Add(m4);

                // Load all the Events
                menu.Closed += new RoutedEventHandler(ContextMenu_Closed);
                menu.MouseLeave += new MouseEventHandler(ContextMenu_MouseLeave);
                return menu;
            }
            return null;
        }        

        /// <summary>
        /// We need to manually implement the context menu upon right click and not use wpf,
        /// because of the mouse leave event
        /// </summary>
        private void dataGridWorkspaces_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            ContextMenu menu = dataGrid_CreateDataGridContextMenu();
            if (menu != null)
            {
                // Make sure that leave doesn't work
                m_WorkspaceSelectorObj.DontCloseOnMouseLeave = true;

                // Show the Context Menu
                menu.IsOpen = true;
            }
        }

        #endregion

        #region ContextMenu Events

        /// <summary>
        /// Context Menu - Closed Event
        /// </summary>        
        void ContextMenu_Closed(object sender, RoutedEventArgs e)
        {
            // Make sure that navigator leave works again
            m_WorkspaceSelectorObj.DontCloseOnMouseLeave = false;

            // Close the Navigation Form *if the mouse is NOT over it*
            if (!WPFHelper.IsMouseCursorOverWPFormWindow(m_WorkspaceSelectorObj))
                m_WorkspaceSelectorObj.Close();            
        }

        /// <summary>
        /// Context Menu - Mouse Leave Event
        /// </summary>        
        void ContextMenu_MouseLeave(object sender, MouseEventArgs e)
        {
            // On Leave just close the Menu
            ContextMenu menu = (ContextMenu)sender;
            menu.IsOpen = false;
        }

        /// <summary>
        /// Context Menu - Menu Item Clicked Event
        /// </summary>        
        void ContextMenu_Item_Click(object sender, RoutedEventArgs e)
        {
            MenuItem m = (MenuItem)sender;

            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (!String.IsNullOrEmpty(strWorkspaceName))
            {
                bool bSuccess = false;
                switch (m.Header.ToString())
                {
                    case "Launch":
                        {
                            bSuccess = m_WorkspaceMgr.LaunchWorkspace(strWorkspaceName);
                        }
                        break;

                    case "Show":
                        {
                            bSuccess = m_WorkspaceMgr.HideShowWorkspace(strWorkspaceName, true);
                        }
                        break;

                    case "Hide":
                        {
                            bSuccess = m_WorkspaceMgr.HideShowWorkspace(strWorkspaceName, false);
                        }
                        break;

                    case "Close":
                        {
                            bSuccess = m_WorkspaceMgr.CloseWorkspace(strWorkspaceName);
                        }
                        break;
                }
            }
        }

        #endregion

        #region Button Click Events

        /// <summary>
        /// New Button - Event Handler
        /// </summary>        
        private void btnNew_Click(object sender, RoutedEventArgs e)
        {
            m_WorkspaceSelectorObj.NavigateToChildPage(ChildPages.WorkspaceSelector_NewWorkspacePage);
        }

        /// <summary>
        /// Edit Button - Event Handler
        /// </summary>        
        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (!String.IsNullOrEmpty(strWorkspaceName))
            {
                GUIState.LastSelectedWorkspaceName = strWorkspaceName;
                m_WorkspaceSelectorObj.NavigateToChildPage(ChildPages.WorkspaceSelector_RenameWorkspacePage);
            }
        }

        /// <summary>
        /// Delete Button - Event Handler
        /// </summary>        
        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (!String.IsNullOrEmpty(strWorkspaceName))
            {
                GUIState.LastSelectedWorkspaceName = strWorkspaceName;
                m_WorkspaceSelectorObj.NavigateToChildPage(ChildPages.WorkspaceSelector_DeleteWorkspacePage);
            }
        }

        /// <summary>
        /// CloseAll Button - Event Handler
        /// </summary>     
        private void btnCloseAll_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Does Nothing");
        }

        /// <summary>
        /// Button on the Grid is being clicked - Event Handler
        /// </summary>        
        private void ButtonGrid_Click(object sender, RoutedEventArgs e)
        {
            string strWorkspaceName = dataGrid_GetSelectedWorkspaceIfThereIsOne();
            if (String.IsNullOrEmpty(strWorkspaceName))
                return;
        }

        #endregion        
    }
}
