using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using Foo.Platform.Win32;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Foo.WorkspaceMgr.Launchers
{
    internal class Launcher_Shell : ILaunch
    {
        #region ILaunch Members

        /// <summary>
        /// Checks to see if the file exists in the system i.e. can be reached over
        /// the network. if FileExists fails, we shouldn't be able to launch it.
        /// </summary>
        /// <param name="strArtifactLocation">location of the path + file to launch</param>
        /// <returns></returns>
        public FuncDepBoolType IQueryLaunch(string strArtifactLocation)
        {
            if (!String.IsNullOrEmpty(strArtifactLocation) && (strArtifactLocation.Length > 3))
            {
                if (File.Exists(strArtifactLocation))
                    return FuncDepBoolType.Success;
                else
                    return FuncDepBoolType.ArtifactLocationUnavailable;
            }
            else
            {
                return FuncDepBoolType.ParametersInvalid;
            }
        }

        /// <summary>        
        /// Generic Launcher should be able to handle any file type using Shell Execute
        /// ~This is NOT the same as Process.start(). When using ShellExecute, Excel workbooks
        /// launch in a different window (and for some reason Don't SHOW UP in the Excel DOM)
        /// ~this is why this is broken out (more testing is needed)
        /// </summary>
        /// <param name="strArtifactLocation">location of the path + file to launch</param>
        /// <returns></returns>
        public FuncDepBoolType ILaunch(string strArtifactLocation)
        {
            if (!String.IsNullOrEmpty(strArtifactLocation) && (strArtifactLocation.Length > 3))
            {                                               
                // Shellexecute works almost just like process.start except for the limitation
                // mentioned:
                // We could do process start but doing so means all excel docs open in the same
                // excel window (just like powerpoint does) ~this may or may not be desirable
                // ~excel docs won't show in the DOM, after being launched this way ~ - very odd
                bool bIsValidExe = false;
                string strExeOrDllPath = string.Empty;
                bool bFound = Win32_WrapperFunc.FindExeOrDll(strArtifactLocation, out strExeOrDllPath, out bIsValidExe);

                const int SEE_MASK_NOCLOSEPROCESS = 0x40;
                ShellExecuteInfo sei = new ShellExecuteInfo();
                sei.cbSize = Marshal.SizeOf(sei);
                sei.lpVerb = "open";
                sei.lpParameters = '\"' + strArtifactLocation + '\"';
                sei.nShow = (int)WindowAction.SW_SHOWNORMAL;
                sei.fMask = SEE_MASK_NOCLOSEPROCESS;

                // Use Shell32 or Explorer to launch the artifact
                if (bFound && bIsValidExe)
                    sei.lpFile = strExeOrDllPath;
                else
                    sei.lpFile = '\"' + Win32_WrapperFunc.GetWindowsPath() + "\\explorer.exe" + '\"';

                if (Win32Functions.ShellExecuteEx(ref sei))
                    return FuncDepBoolType.Success;
                else
                    return FuncDepBoolType.Failed;
            }
            return FuncDepBoolType.ParametersInvalid;            
        }

        #endregion
    }
}
