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.Shapes;
using System.Windows.Interop;
using System.Reflection;
using System.Windows.Threading;

using Foo.Platform;
using Foo.GUILib;


namespace Foo.ClientServices.GUIWPForms
{
    public enum ChildPages
    {
        WorkspaceSelector_StandardPage,
        WorkspaceSelector_NewWorkspacePage,
        WorkspaceSelector_RenameWorkspacePage,
        WorkspaceSelector_DeleteWorkspacePage,
    }    

    /// <summary>
    /// Interaction logic for WorkspaceSelector.xaml
    /// </summary>
    public partial class WorkspaceSelector : Window
    {
        private bool m_bPerformanceCache = false;
        private Page[] m_ChildPages = null;

        // Declare the Log4net Variable        
        private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);

        // Allow Childresn access to the Frame
        public Frame WorkspaceSelectorFrm { get { return frmWorkspaceSelector; } }

        // Allow Children to overwrite MouseLeave Close Behavior
        public bool DontCloseOnMouseLeave { get; set; }

        // Allow Children access to margin top/bottom
        public int MarginTopBottom { get; set; }

        // internal flags
        private bool m_bMouseFirstTimeEnter = false;
        private bool m_bMouseHasEnteredBack = false;
        private bool m_bMouseLeaveTimerCreated = false;

        /// <summary>
        /// Child Page Creation Factory * should only be called internally *
        /// </summary>
        /// <param name="page">the page to instantiate</param>
        /// <returns>a new page object or null</returns>
        private Page CreateChildPage(ChildPages page)
        {
            Page pageObj = null;
            switch (page)
            {
                case ChildPages.WorkspaceSelector_NewWorkspacePage:
                    pageObj = new WorkspaceSelector_NewWorkspacePage(m_bPerformanceCache);
                    break;

                case ChildPages.WorkspaceSelector_RenameWorkspacePage:
                    pageObj = new WorkspaceSelector_RenameWorkspacePage(m_bPerformanceCache);
                    break;

                case ChildPages.WorkspaceSelector_DeleteWorkspacePage:
                    pageObj = new WorkspaceSelector_DeleteWorkspacePage(m_bPerformanceCache);
                    break;

                case ChildPages.WorkspaceSelector_StandardPage:
                    pageObj = new WorkspaceSelector_StandardPage(m_bPerformanceCache);
                    break;
            }
            return pageObj;
        }

        /// <summary>
        /// Use this to actually navigate to a child page object on the WorkspaceSelector
        /// </summary>
        /// <param name="page">a page to navigate to</param>
        public void NavigateToChildPage(ChildPages page)
        {
            try
            {
                Page pageObj = CreateChildPage(page);                
                if (pageObj != null)
                {
                    pageObj.Tag = this; // pass out this object
                    if (!frmWorkspaceSelector.Navigate(pageObj))
                        Log.Info(string.Format("{0}() - WorkspaceSelector could not navigate to ChildPage {1}", MethodBase.GetCurrentMethod().Name, (int)page));
                }
            }
            catch (Exception e)
            {
                Log.Error(string.Format("{0}() - Error Thrown", MethodBase.GetCurrentMethod().Name, e));
            }
        }   
             
        /// <summary>
        /// WorkspaceSelector Constructor - set's default values for the object
        /// Instantiates all child pages when in Performance Mode
        /// </summary>
        /// <param name="bPerformanceCache">true if this is a cached form for performance, false every other time</param>
        public WorkspaceSelector(bool bPerformanceCache)
        {
            InitializeComponent();

            // * For Performance Caching *
            if (WPFHiddenWindow.HiddenWindowConstructor(this, bPerformanceCache))
            {
                m_bPerformanceCache = true;

                // Performance Load the Child Pages as well
                int n = Enum.GetValues(typeof(ChildPages)).Length;
                m_ChildPages = new Page[n];

                // Iterate thru enums and create the corresponding objects in the Cache
                for (int i = 0; i < n; ++i)
                {
                    ChildPages page = (ChildPages)Enum.ToObject(typeof(ChildPages), i);
                    m_ChildPages[i] = CreateChildPage(page);
                }
            }            

            // By default allow mouse leave to close the form
            DontCloseOnMouseLeave = false;

            // MarginTopBottom is the space up and below the frame 2 * 6 = 12 (but we want 2 pixels trimmed)
            MarginTopBottom = 10;
        }      

        #region Window Events

        /// <summary>
        /// Window Load Event - Hook into MessageHook if in performance mode,
        /// otherwise load default child
        /// </summary>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        { 
            // * For Performance Caching *
            if (WPFHiddenWindow.HiddenWindowOnLoad(this, m_bPerformanceCache))
            {
                // To Anything her you may want to do                
            }
            else
            {
                // Navigate to the Default Page
                NavigateToChildPage(ChildPages.WorkspaceSelector_StandardPage);

                // Set the GUI State to this object
                GUIState.CurrentlyShowingWPFWindow = this;

                // Start the Load Mouse Enter Timer for 1.5 seconds
                DispatcherTimer dispatcherTimer = new DispatcherTimer();
                dispatcherTimer.Tick += new EventHandler(dispatcherTimerOnLoadMouseEnter_Tick);
                dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1, 500);
                dispatcherTimer.Start();
            }
        }

        /// <summary>
        /// keep track of window closed
        /// </summary>
        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            // * For Performance Caching *
            if (WPFHiddenWindow.HiddenWindowClosing(this, m_bPerformanceCache))
            {
                // To Anything her you may want to do                
            }
            else
            {
                // Set the GUI State to this object
                GUIState.CurrentlyShowingWPFWindow = null;
            }            
        }     

        /// <summary>
        /// Keep track of mouse enter
        /// </summary>        
        private void Window_MouseEnter(object sender, MouseEventArgs e)
        {
            m_bMouseFirstTimeEnter = true;
            m_bMouseHasEnteredBack = true;
        }

        /// <summary>
        /// General Standard behavior - Close the form on Mouse Leave, except when
        /// children overwrite this behavior via DontCloseOnMouseLeave
        /// </summary>        
        private void Window_MouseLeave(object sender, MouseEventArgs e)
        {
            m_bMouseHasEnteredBack = false;
            if (!m_bMouseLeaveTimerCreated)
            {
                // Start Mouse Leave Timer for 1.5 seconds
                DispatcherTimer dispatcherTimer = new DispatcherTimer();
                dispatcherTimer.Tick += new EventHandler(dispatcherTimerMouseLeave_Tick);
                dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1, 500);
                dispatcherTimer.Start();

                // Set flag
                m_bMouseLeaveTimerCreated = true;
            }
        }

        #endregion

        /// <summary>
        /// Run One Time - after Mouse Leaves. Closes Form if Mouse has not entered
        /// </summary>        
        void dispatcherTimerMouseLeave_Tick(object sender, EventArgs e)
        {
            // Turn off the timer
            DispatcherTimer dispatcherTimer = (DispatcherTimer)sender;
            dispatcherTimer.Stop();
            m_bMouseLeaveTimerCreated = false;

            // Close this window, but only if the mouse has not entered back ||
            // we are told not to do it
            if (!m_bMouseHasEnteredBack && !DontCloseOnMouseLeave)
                this.Close();
        }

        /// <summary>
        /// Run One Time - Upon Load. Closes form if mouse has not entered
        /// </summary>        
        void dispatcherTimerOnLoadMouseEnter_Tick(object sender, EventArgs e)
        {
            // We only want to run this timer Once * Always *
            DispatcherTimer dispatcherTimer = (DispatcherTimer)sender;
            dispatcherTimer.Stop();

            // Close this window, but only if the mouse has not entered back
            // Close this Form *always*
            if (!m_bMouseFirstTimeEnter && !DontCloseOnMouseLeave)                                
                this.Close();
        }
  
    }
}
