//-----------------------------------------------------------------------
// Copyright 2015 Tobii Technology AB. All rights reserved.
//-----------------------------------------------------------------------

#if UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN

using System;
using System.Text;
using System.Diagnostics;

namespace Tobii.EyeTracking
{
    /// <summary>
    /// Contains utility functions for window handling.
    /// </summary>
    public static class WindowHelpers
    {
        /// <summary>
        /// Shows the current window.
        /// </summary>
        public static void ShowCurrentWindow()
        {
            IntPtr hwnd = FindWindowWithThreadProcessId(Process.GetCurrentProcess().Id);
            Win32Helpers.ShowWindowAsync(hwnd, Win32Helpers.SW_SHOWDEFAULT);
        }

        internal static IntPtr FindWindowWithThreadProcessId(int processId)
        {
            var window = new IntPtr();

            Win32Helpers.EnumWindows(delegate (IntPtr wnd, IntPtr param)
            {
                var windowProcessId = 0;
                Win32Helpers.GetWindowThreadProcessId(wnd, out windowProcessId);
                if (windowProcessId != processId || !IsMainWindow(wnd))
                {
                    return true;
                }

                window = wnd;
                return false;
            },
            IntPtr.Zero);

            if (window.Equals(IntPtr.Zero))
            {
                UnityEngine.Debug.LogError("Could not find any window with process id " + processId);
            }

            return window;
        }

        private static bool IsMainWindow(IntPtr hwnd)
        {
            return (Win32Helpers.GetWindow(hwnd, Win32Helpers.GW_OWNER) == IntPtr.Zero) && Win32Helpers.IsWindowVisible(hwnd);
        }

        internal static IntPtr GetGameViewWindowHandle(int processId)
        {
            const string GameViewCaption = "UnityEditor.GameView";
            const string UnityContainerClassName = "UnityContainerWndClass";

            var window = new IntPtr();

            Win32Helpers.EnumWindows(delegate (IntPtr hWnd, IntPtr lParam)
            {
                if (!Win32Helpers.IsWindowVisible(hWnd))
                {
                    return true;
                }

                var windowProcessId = 0;
                Win32Helpers.GetWindowThreadProcessId(hWnd, out windowProcessId);

                if (windowProcessId == processId)
                {
                    StringBuilder builder = new StringBuilder(256);
                    Win32Helpers.GetClassName(hWnd, builder, 256);

                    if (builder.ToString() == UnityContainerClassName)
                    {
                        //Ok, we found one of our containers, let's try to find the game view handle among the children
                        Win32Helpers.EnumChildWindows(hWnd, delegate (IntPtr childHwnd, IntPtr childParam)
                        {
                            if (!Win32Helpers.IsWindowVisible(childHwnd))
                            {
                                return true;
                            }

                            int childLength = Win32Helpers.GetWindowTextLength(childHwnd);
                            if (childLength == 0)
                            {
                                return true;
                            }

                            StringBuilder childBuilder = new StringBuilder(childLength);
                            Win32Helpers.GetWindowText(childHwnd, childBuilder, childLength + 1);

                            if (childBuilder.ToString() == GameViewCaption)
                            {
                                //Found it!
                                window = childHwnd;
                                return false;
                            }

                            return true;
                        },
                        IntPtr.Zero);
                    }
                }

                return true;

            }, IntPtr.Zero);

            if (window.Equals(IntPtr.Zero))
            {
                UnityEngine.Debug.LogError("Could not find game view!");
            }

            return window;
        }
    }

}

#else
using System;
namespace Tobii.EyeTracking
{
    public static class WindowHelpers
    {
        public static void ShowCurrentWindow()
        {
            throw new InvalidOperationException("Not available on this platform.");
        }
    }
}
#endif
