
// For GUIDebugStepExe Debugging Only - Uncomment this #define
#define GUIDEBUGSTEPEXE

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Windows.Interop;
using System.EnterpriseServices;
using System.Windows;
using System.IO;
using System.Windows.Threading;
using System.Collections;
using System.Reflection;

// Ooganizer Namespaces
using Foo.GUILib;
using Foo.Platform;
using Foo.Platform.Win32;
using Foo.Platform.Interacters;
using Foo.Platform.ErrorReporting;

namespace Foo.ClientServices.ButtonWPForm
{   
    
    /// <summary>
    /// ButtonWPFormCCW - Com Callable Wrapper Class exposed to ButtonHook.
    /// This class is responsible for creating the ButtonWPForm (a form created in response to a ButtonHook W32 Click)
    /// </summary>
    [Guid("6F108F0B-9CEB-4d3d-B1D9-7685F9F39E50")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Foo.ClientServices.ButtonWPFormCCW")]
    [ComVisible(true)]
    [ObjectPooling(Enabled = true, MinPoolSize = 1, MaxPoolSize = 2500, CreationTimeout = 5000)]
#if GUIDEBUGSTEPEXE
    public class ButtonWPFormCCW : IButtonForm, IClientEvents
#else
    public class ButtonWPFormCCW : ServicedComponent, IButtonForm, IClientEvents, IProcessInitializer
#endif
    {
        
        ////
        // Member Variables
        ////
        private IntPtr m_hWnd = IntPtr.Zero;
        private IntPtr m_hWndParent = IntPtr.Zero;
        private IntPtr m_hWndButton = IntPtr.Zero;
        
        BHInteracter.BUTTON_HOOK_STATE m_ButtonState = BHInteracter.BUTTON_HOOK_STATE.BUTTON_NONE;

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

        #region Construction / Destruction
        public ButtonWPFormCCW() {}
        ~ButtonWPFormCCW() {}
        #endregion

#if GUIDEBUGSTEPEXE
        #region GuiDebugStepCustomStarterStopers
        public void Start()
        {
            Log.Info(string.Format("{0}() - ComponentState Application Is being started", MethodBase.GetCurrentMethod().Name));
            ComponentState.ApplicationIsRunning = true;
        }
        public void Stop()
        {
            Log.Info(string.Format("{0}() - ComponentState Application Is being stopped", MethodBase.GetCurrentMethod().Name));
            ComponentState.ApplicationIsRunning = false;
        }
        #endregion
#else
        #region IProcessInitializer Members
        public void Startup(object punkProcessControl)
        {
            Log.Info(string.Format("{0}() - ComponentState Application Is being started", MethodBase.GetCurrentMethod().Name));
            ComponentState.ApplicationIsRunning = true;
        }

        public void Shutdown()
        {
            Log.Info(string.Format("{0}() - ComponentState Application Is being stopped", MethodBase.GetCurrentMethod().Name));
            ComponentState.ApplicationIsRunning = false;
        }                
        #endregion
#endif

        #region ButtonHook Activation/Deactivation
        /// <summary>
        /// This is called first time when the buttonhook is attaching into a Window. It passes us 
        /// important handle information that we need or may need to communicate back state information.        
        /// </summary>
        /// <param name="hParentWND">the handle to the window the buttonhook is hooked into</param>
        /// <param name="hButtonWND">the handle to the button Window (we need it if we want to communicat with it)</param>
        public void WPFThreadProc_ButtonWPForm_Activated(int hParentWND, int hButtonWND)
        {            
            // Store the handle information for later use
            m_hWndParent = (IntPtr)hParentWND;
            m_hWndButton = (IntPtr)hButtonWND;
        }

        /// <summary>      
        /// Called when the buttonhook is unattaching itself from a Window. 
        /// Here, we can do any cleanup that we may have to do.
        /// </summary>        
        public void WPFThreadProc_ButtonWPForm_Deactivated()
        {
            try
            {
                if ((m_hWndParent != IntPtr.Zero) && (ComponentState.ButtonFormMgr != null))
                     ComponentState.ButtonFormMgr.Delete_ButtonFormDISP((int)m_hWndParent);
            }
            catch (Exception e)
            {
                Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e);
            }
        }
        #endregion

        #region Custom Events
        /// <summary>
        /// This function is called when the Win32 button is clicked. This function should
        /// handle the creation of the wpfform and display it over the window
        /// </summary>        
        /// <returns>the window handle to the newly created wpfform to be stored by the caller</returns>
        public int W32BUTTONCLICKED()
        {
            try
            {
                // Let's Position the Window and snapshot it...
                Image snapshot = null;
                try
                {
                    BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_NONE);
                    System.Threading.Thread.Sleep(100);
                    snapshot = GUICommon.PositionWindowToGoldenPosAndTakeSnapshot(m_hWndParent, true);                    
                }
                catch (Exception e)
                {
                    UserError.Show("Snapshot Failed", "Obtaining a Snaphot for the Window Failed.");
                    Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e);
                    return 0;
                }

                if (snapshot != null)
                {
                    // Create the WpfForm object and then create the wpfform window and show it. 
                    ComponentState.ButtonFormMgr.Create_ButtonFormDISP((int)m_hWndParent, snapshot);
                    m_hWnd = (IntPtr) ComponentState.ButtonFormMgr.Create_ButtonFormWindowDISP((int)m_hWndParent);
                    return (int)m_hWnd;
                }
                else
                {
                    UserError.Show("Snapshot Failed", "Obtaining a Snaphot for the Window Failed.");
                    Log.Error(string.Format("{0}() - UserError.Show() - Obtaining a Snapshot Failed", MethodBase.GetCurrentMethod().Name));
                    return 0;
                }                
            }
            catch (Exception e)
            {
                UserError.Show("Snapshot Failed", "Obtaining a Snaphot for the Window Failed.");
                Log.Error(string.Format("{0}() - error thrown", MethodBase.GetCurrentMethod().Name), e);
                return 0;
            }
        }
        #endregion

        #region Window Events we can extend on
        public void WindowEvent_MaximizeOccured(int nHeight, int nWidth)
        {
        }

        public void WindowEvent_MinimizeOccured()
        {
        }

        public void WindowEvent_WindowActivated()
        {
        }

        public void WindowEvent_WindowDeactivated()
        {
        }
        #endregion

        #region Resolver Client Events                        
        public void ReResolve(int pid, IntPtr hWnd)
        {
            Log.Debug(string.Format("{0}() - Debug - ReResolve is called for {0} and {1}", pid, hWnd));
        }

        public void hWndInitialActivate(int pid, IntPtr hWnd, string ProcessStartUpPrms)
        {
            try
            {

                m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_ADD);

                Log.Debug(string.Format("{0}() - --- TEST --- ProcessStartUpPrms", ProcessStartUpPrms));

                //// We need to resolve the window here
                //ResolverDispatch resolver = new Resolver.ResolverDispatch();
                //ArtifactGroup artifacts = resolver.GetArtifacts((IntPtr)hWnd);

                //// If we can resolve this window then we want to be checking
                //if (artifacts.Length >= 1)
                //{
                //    Artifact curArtifact = artifacts.GetPrimary;
                //    bool bFound = SrvrCommon.IsArtifactInCurrentWorkspace(curArtifact);

                //    if (bFound)
                //        m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_DELETE);
                //    else
                //        m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_ADD);
                //}
                //else
                //{
                //    Log.Error(string.Format("{0}() - WPForm could not resolve this Window - disabling the Caption Button", MethodBase.GetCurrentMethod().Name));
                //    m_ButtonState = BHInteracter.SetW32ButtonToNewState(m_hWndParent, BHInteracter.BUTTON_HOOK_STATE.BUTTON_NONE);
                //}
            }
            catch (Exception e)
            {
                Log.Error(string.Format("{0}() - WPForm could not resolve this Window - disabling the Caption Button", MethodBase.GetCurrentMethod().Name), e);
            }
        }

        public void hWndLastDeactivate(int pid, IntPtr hWnd)
        {
            Log.Debug(string.Format("{0}() - Debug - hWndLastDeactivate is called for {0} and {1}", pid, hWnd));
        }

        public void DragNDropOccured(int pid, IntPtr hWnd, int nFiles, string SemiColonSepFileNames)
        {
            Log.Debug(string.Format("{0}() - Debug - DragNDropOccured is called with {0} and {1} and {2}", pid, hWnd, nFiles, SemiColonSepFileNames));
        }

        public void OpenOrSaveFileDialogOccured(int pid, IntPtr hWnd, string possibleLocAndFileName, string FileTypes)
        {
            Log.Debug(string.Format("{0}() - Debug - DragNDropOccured is called with {0} and {1} and {2}", pid, hWnd, possibleLocAndFileName, FileTypes));
        }
        #endregion

    }
}
