using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foo.AddIn.Common;
using System.Diagnostics;

// Ignore 'Ambiguity' warning message, seems like no way around those
#pragma warning disable 0467

namespace Foo.Addin.Office
{
    public class Publisher_Workspace : IWorkspace
    {
        public const string Publisher_ProgId = "Publisher.Application";

        public FuncRetVal Launch(string strArtifactLocation, int WindowHeight, int WindowWidth, int WindowTop, int WindowLeft)
        {            
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                Microsoft.Office.Interop.Publisher.Application app = new Microsoft.Office.Interop.Publisher.Application();

                // Opens Publisher
                Microsoft.Office.Interop.Publisher.Document doc = null;
                doc = app.Open(strArtifactLocation, false, false, Microsoft.Office.Interop.Publisher.PbSaveOptions.pbSaveChanges);                

                // Position the Window
                IntPtr hWnd = (IntPtr)doc.ActiveWindow.Hwnd;
                Functions.SetWindowPos(hWnd, IntPtr.Zero, WindowLeft, WindowTop, WindowHeight, WindowWidth, 0);

                if (doc != null)
                {                    
                    retVal.Type = FuncRetValEnum.Action_Succeeded;
                }
                else
                {
                    retVal.Type = FuncRetValEnum.Action_Failed;
                }
            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;
        }

        public FuncRetVal Launch(string strArtifactLocation)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                Microsoft.Office.Interop.Publisher.Application app = new Microsoft.Office.Interop.Publisher.Application();                

                // Opens Publisher
                Microsoft.Office.Interop.Publisher.Document doc = null;
                doc = app.Open(strArtifactLocation, false, false, Microsoft.Office.Interop.Publisher.PbSaveOptions.pbSaveChanges);                

                if (doc != null)
                {
                    retVal.Type = FuncRetValEnum.Action_Succeeded;
                }
                else
                {
                    retVal.Type = FuncRetValEnum.Action_Failed;
                }
            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;            
        }

        public FuncRetVal Show(string strArtifactLocation)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPublisherApps = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.Publisher.Application>();
                foreach (Microsoft.Office.Interop.Publisher.Application app in RunningPublisherApps)
                {
                    foreach (Microsoft.Office.Interop.Publisher.Document pubDoc in app.Documents)
                    {
                        if (pubDoc.FullName.ToLower() == strArtifactLocation.ToLower())
                        {

                            if (pubDoc.ActiveWindow.Visible)
                            {
                                retVal.Type = FuncRetValEnum.NoAction_Needed;
                                return retVal;
                            }
                            else
                            {
                                pubDoc.ActiveWindow.Visible = true;
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                            }                                                            
                        }
                    }
                }
                retVal.Type = FuncRetValEnum.ArtifactUnavailable;                
            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;             
        }

        public FuncRetVal Hide(string strArtifactLocation)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPublisherApps = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.Publisher.Application>();
                foreach (Microsoft.Office.Interop.Publisher.Application app in RunningPublisherApps)
                {
                    foreach (Microsoft.Office.Interop.Publisher.Document pubDoc in app.Documents)
                    {
                        if (pubDoc.FullName.ToLower() == strArtifactLocation.ToLower())
                        {

                            if (!pubDoc.ActiveWindow.Visible)
                            {
                                retVal.Type = FuncRetValEnum.NoAction_Needed;
                                return retVal;
                            }
                            else
                            {
                                pubDoc.ActiveWindow.Visible = false;
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                            }
                        }
                    }
                }
                retVal.Type = FuncRetValEnum.ArtifactUnavailable;
            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;
        }

        public FuncRetVal QueryClose(string strArtifactLocation)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPublisherApps = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.Publisher.Application>();
                foreach (Microsoft.Office.Interop.Publisher.Application app in RunningPublisherApps)
                {
                    foreach (Microsoft.Office.Interop.Publisher.Document pubDoc in app.Documents)
                    {
                        if (pubDoc.FullName.ToLower() == strArtifactLocation.ToLower())
                        {
                            if (pubDoc.Saved)
                            {
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                                return retVal;
                            }
                            else
                            {
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                                return retVal;
                            }                         
                        }
                    }
                }

                retVal.Type = FuncRetValEnum.ArtifactUnavailable;
            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;
        }

        public FuncRetVal Close(string strArtifactLocation, bool bAutoSaveArtifact, out int WindowHeight, out int WindowWidth, out int WindowTop, out int WindowLeft)
        {
            FuncRetVal retVal = new FuncRetVal();
            WindowTop = 0;
            WindowLeft = 0;
            WindowWidth = 0;
            WindowHeight = 0;

            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPublisherApps = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.Publisher.Application>();
                foreach (Microsoft.Office.Interop.Publisher.Application app in RunningPublisherApps)
                {
                    foreach (Microsoft.Office.Interop.Publisher.Document pubDoc in app.Documents)
                    {
                        if (pubDoc.FullName.ToLower() == strArtifactLocation.ToLower())
                        {
                            // Save the Document
                            if (bAutoSaveArtifact)
                                pubDoc.Save();

                            // Get the Window properties
                            WindowTop = pubDoc.ActiveWindow.Top;
                            WindowLeft = pubDoc.ActiveWindow.Left;
                            WindowWidth = pubDoc.ActiveWindow.Width;
                            WindowHeight = pubDoc.ActiveWindow.Height;
                           
                            // Get the Handle
                            IntPtr hWnd = (IntPtr)pubDoc.ActiveWindow.Hwnd;
                            Process process = Functions.GetProcessFromHandle(hWnd);

                            // Send Close Message
                            if (Functions.SendMessage((IntPtr)hWnd, Functions.FuncEnum.WindowMessage.WM_CLOSE, IntPtr.Zero, IntPtr.Zero) == 0)
                            {
                                process.Kill();
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                                return retVal;
                            }
                            else
                            {
                                retVal.Type = FuncRetValEnum.Action_Failed;
                                return retVal;
                            }
                        }
                    }
                }

                retVal.Type = FuncRetValEnum.ArtifactUnavailable;

            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal; 
        }

        public FuncRetVal Close(string strArtifactLocation, bool bAutoSaveArtifact)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPublisherApps = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.Publisher.Application>();
                foreach (Microsoft.Office.Interop.Publisher.Application app in RunningPublisherApps)
                {
                    foreach (Microsoft.Office.Interop.Publisher.Document pubDoc in app.Documents)
                    {
                        if (pubDoc.FullName.ToLower() == strArtifactLocation.ToLower())
                        {
                            // Save the Document
                            if(bAutoSaveArtifact)
                               pubDoc.Save();

                            // Get the Handle
                            IntPtr hWnd = (IntPtr)pubDoc.ActiveWindow.Hwnd;
                            Process process = Functions.GetProcessFromHandle(hWnd);

                            // Send Close Message
                            if (Functions.SendMessage((IntPtr)hWnd, Functions.FuncEnum.WindowMessage.WM_CLOSE, IntPtr.Zero, IntPtr.Zero) == 0)
                            {
                                process.Kill();
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                                return retVal;
                            }
                            else
                            {
                                retVal.Type = FuncRetValEnum.Action_Failed;
                                return retVal;
                            }
                        }
                    }
                }

                retVal.Type = FuncRetValEnum.ArtifactUnavailable;

            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;            
        }

        public FuncRetVal Close(string strArtifactLocation)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPublisherApps = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.Publisher.Application>();
                foreach (Microsoft.Office.Interop.Publisher.Application app in RunningPublisherApps)
                {
                    foreach (Microsoft.Office.Interop.Publisher.Document pubDoc in app.Documents)
                    {
                        if (pubDoc.FullName.ToLower() == strArtifactLocation.ToLower())
                        {
                            // Save the Document
                            pubDoc.Save();

                            // Get the Handle
                            IntPtr hWnd = (IntPtr)pubDoc.ActiveWindow.Hwnd;
                            Process process = Functions.GetProcessFromHandle(hWnd);

                            // Send Close Message
                            if (Functions.SendMessage((IntPtr)hWnd, Functions.FuncEnum.WindowMessage.WM_CLOSE, IntPtr.Zero, IntPtr.Zero) == 0)
                            {
                                process.Kill();
                                retVal.Type = FuncRetValEnum.Action_Succeeded;
                                return retVal;
                            }
                            else
                            {
                                retVal.Type = FuncRetValEnum.Action_Failed;
                                return retVal;
                            }
                        }
                    }
                }

                retVal.Type = FuncRetValEnum.ArtifactUnavailable;

            }
            catch (Exception e)
            {
                retVal.Message = e.Message;
                retVal.Type = FuncRetValEnum.ErrorThrown;
            }
            return retVal;
        }

    }
}
