using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Foo.AddIn.Common;
using System.Runtime.InteropServices;

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

namespace Foo.Addin.Office
{
    public class PowerPoint_Workspace : IWorkspace
    {
        public const string PowerPoint_ProgId = "PowerPoint.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.PowerPoint.Application app = null;
                app = Functions.GetCOMObject(PowerPoint_ProgId) as Microsoft.Office.Interop.PowerPoint.Application;

                // If no existing PowerPoint App is open, open a new one
                if (app == null)
                {
                    app = new Microsoft.Office.Interop.PowerPoint.Application();
                    app.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
                }

                // If there is an existing presentation, don't position the window
                bool bThereIsAnExistingPresentation = (app.Presentations.Count > 0);

                // Open the PowerPoint Presentation
                Microsoft.Office.Interop.PowerPoint.Presentation presentation = null;
                presentation = app.Presentations.Open(strArtifactLocation, Microsoft.Office.Core.MsoTriState.msoFalse,
                                                        Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue);

                if (presentation != null)
                {
                    // Position the Window
                    if (!bThereIsAnExistingPresentation)
                    {
                        IntPtr hWnd = (IntPtr) app.HWND;
                        Functions.SetWindowPos(hWnd, IntPtr.Zero, WindowLeft, WindowTop, WindowHeight, WindowWidth, 0);
                    }

                    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.PowerPoint.Application app = null;
                app = Functions.GetCOMObject(PowerPoint_ProgId) as Microsoft.Office.Interop.PowerPoint.Application;

                // If no existing PowerPoint App is open, open a new one
                if (app == null)
                {
                    app = new Microsoft.Office.Interop.PowerPoint.Application();
                    app.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;
                }

                // Open the PowerPoint Presentation
                Microsoft.Office.Interop.PowerPoint.Presentation presentation = null;
                presentation = app.Presentations.Open(strArtifactLocation, Microsoft.Office.Core.MsoTriState.msoFalse, 
                                                        Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue);

                if (presentation != 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 RunningPowerPoints = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.PowerPoint.Presentation>();
                foreach (Microsoft.Office.Interop.PowerPoint.Presentation presentation in RunningPowerPoints)
                {
                    if (presentation.FullName.ToLower() == strArtifactLocation.ToLower())
                    {
                        switch (presentation.Application.Visible)
                        {
                            case Microsoft.Office.Core.MsoTriState.msoTrue:
                                {
                                    retVal.Type = FuncRetValEnum.NoAction_Needed;
                                    return retVal;
                                }

                            case Microsoft.Office.Core.MsoTriState.msoFalse:
                                {
                                    presentation.Application.Visible = Microsoft.Office.Core.MsoTriState.msoTrue;

                                    //Functions.ShowWindow((IntPtr)presentation.Application.HWND, (int)Functions.WindowAction.SW_SHOW);
                                    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 Hide(string strArtifactLocation)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPowerPoints = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.PowerPoint.Presentation>();
                foreach (Microsoft.Office.Interop.PowerPoint.Presentation presentation in RunningPowerPoints)
                {
                    if (presentation.FullName.ToLower() == strArtifactLocation.ToLower())
                    {
                        switch (presentation.Application.Visible)
                        {
                            case Microsoft.Office.Core.MsoTriState.msoTrue:
                                {
                                    presentation.Application.Visible = Microsoft.Office.Core.MsoTriState.msoFalse;

                                    //Functions.ShowWindow((IntPtr)presentation.Application.HWND, (int)Functions.WindowAction.SW_HIDE);
                                    retVal.Type = FuncRetValEnum.Action_Succeeded;
                                    return retVal;                                                                        
                                }

                            case Microsoft.Office.Core.MsoTriState.msoFalse:
                                {
                                    retVal.Type = FuncRetValEnum.NoAction_Needed;
                                    return retVal;
                                }
                        }
                    }
                }

                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 RunningPowerPoints = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.PowerPoint.Presentation>();
                foreach (Microsoft.Office.Interop.PowerPoint.Presentation presentation in RunningPowerPoints)
                {
                    if (presentation.FullName.ToLower() == strArtifactLocation.ToLower())
                    {
                        switch (presentation.Saved)
                        {
                            case Microsoft.Office.Core.MsoTriState.msoTrue:
                                {
                                    retVal.Type = FuncRetValEnum.Action_Succeeded;
                                    return retVal;
                                }

                            case Microsoft.Office.Core.MsoTriState.msoFalse:
                                {
                                    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, 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 RunningPowerPoints = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.PowerPoint.Presentation>();
                foreach (Microsoft.Office.Interop.PowerPoint.Presentation presentation in RunningPowerPoints)
                {
                    if (presentation.FullName.ToLower() == strArtifactLocation.ToLower())
                    {
                        var app = presentation.Application;

                        // Save this Presentation
                        if (bAutoSaveArtifact)
                            presentation.Save();

                        // Pass out the Window Information
                        WindowTop = (int) presentation.Application.Top;
                        WindowLeft = (int) presentation.Application.Left;
                        WindowHeight = (int) presentation.Application.Height;
                        WindowWidth = (int)presentation.Application.Width;

                        // Close this Presentation
                        presentation.Close();

                        Marshal.FinalReleaseComObject(presentation); // force clean-up

                        // Close PowerPoint if there are no more Presentations                        
                        if (app.Presentations.Count == 0)
                        {
                            app.Quit();
                            Marshal.FinalReleaseComObject(app); // force clean-up, kill application for sure
                        }

                        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)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPowerPoints = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.PowerPoint.Presentation>();
                foreach (Microsoft.Office.Interop.PowerPoint.Presentation presentation in RunningPowerPoints)
                {
                    if (presentation.FullName.ToLower() == strArtifactLocation.ToLower())
                    {
                        var app = presentation.Application;

                        // Save this Presentation
                        if(bAutoSaveArtifact)
                           presentation.Save();

                        // Close this Presentation
                        presentation.Close();

                        Marshal.FinalReleaseComObject(presentation); // force clean-up

                        // Close PowerPoint if there are no more Presentations                        
                        if (app.Presentations.Count == 0)
                        {
                            app.Quit();
                            Marshal.FinalReleaseComObject(app); // force clean-up, kill application for sure
                        }

                        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)
        {
            FuncRetVal retVal = new FuncRetVal();
            if (!Validate.IsValidArtifactLocation(strArtifactLocation, ref retVal))
                return retVal;

            try
            {
                var RunningPowerPoints = Functions.GetRunningObjectsOfType<Microsoft.Office.Interop.PowerPoint.Presentation>();
                foreach (Microsoft.Office.Interop.PowerPoint.Presentation presentation in RunningPowerPoints)
                {
                    if (presentation.FullName.ToLower() == strArtifactLocation.ToLower())
                    {
                        var app = presentation.Application;

                        // Save this Presentation
                        presentation.Save();

                        // Close this Presentation
                        presentation.Close();

                        Marshal.FinalReleaseComObject(presentation); // force clean-up

                        // Close PowerPoint if there are no more Presentations                        
                        if (app.Presentations.Count == 0)
                        {
                            app.Quit();
                            Marshal.FinalReleaseComObject(app); // force clean-up, kill application for sure
                        }

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

    }
}
