/*
CLASS {NATIVE_Alien_windows|_CSharp}, NATIVE:

*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Runtime.InteropServices;
using System.Diagnostics;


public class AL4_windows
{
    
    [DllImport("user32.dll")]
    static extern IntPtr GetForegroundWindow();
    public static IntPtr Get_foreground()  {
        return GetForegroundWindow();
    }
   
    //[DllImport("user32.dll")]
    //static extern IntPtr GetDesktopWindow();
    //public static IntPtr Get_desktop()  {
    //    return GetDesktopWindow();
    //}
   
    [DllImport("user32.dll")]
    static extern void SetForegroundWindow(IntPtr handle);
    public static void Set_foreground(IntPtr h)  {
        SetForegroundWindow(h);
    }
   
    [DllImport("user32.dll")]
    static extern int GetWindowText(
            IntPtr hWnd, 
            StringBuilder text, 
            int count);
    public static string Get_text( IntPtr handle ) {
        int n = 4096;
        StringBuilder buff = new StringBuilder(n);
        if (GetWindowText(handle, buff, n) > 0)
            return buff.ToString();
        return "";
    }
    
    [DllImport("user32.dll")]
    static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    public static IntPtr Find(string Class, string Caption) {
    	if (Class == "") Class = null;
        return FindWindow(Class, Caption);
    }
    
    [DllImport("user32.dll")]
    static extern bool EnumWindows(EnumWindowsProc enumProc, int lParam);
    protected delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
    public static void List_desktop(AL4.ArrayInt Array, bool Visible_only) {
        handles = new List<IntPtr>();
        //EnumDelegate efunc = new EnumDelegate(Enum_windows_proc);
        EnumWindows(new EnumWindowsProc(Enum_windows_proc), Visible_only ? 1 : 0);
        Array.Clear();
        for (int i = 0; i < handles.Count; i++)
            Array.Add((int)handles[i]);
    }
    
    static List<IntPtr> handles;
    public static bool Enum_windows_proc(IntPtr hWnd, int lParam) {
        if (lParam == 0 || IsWindowVisible(hWnd))
        handles.Add(hWnd);
        return true;
    }
    
    [DllImport("user32.dll")]
    static extern bool IsWindow(IntPtr hWnd);
    public static bool Is_window(IntPtr hWnd) {
        return IsWindow(hWnd);
    }
    
    [DllImport("user32.dll")]
    static extern bool IsWindowVisible(IntPtr hWnd);
    public static bool Is_visible(IntPtr hWnd) {
        return IsWindowVisible(hWnd);
    }
    
    [DllImport("user32.dll")]
    static extern bool IsZoomed(IntPtr hWnd);
    public static bool Is_zoomed(IntPtr hWnd) {
        return IsZoomed(hWnd);
    }

    [DllImport("user32.dll")]
    static extern bool IsIconic(IntPtr hWnd);
    public static bool Is_iconic(IntPtr hWnd) {
        return IsIconic(hWnd);
    }

    [DllImport("user32.dll")]
    static extern int GetClassName(IntPtr hWnd, StringBuilder text, 
            int count);
    public static string Get_class(IntPtr handle) {
        int n = 4096;
        StringBuilder buff = new StringBuilder(n);
        if (GetClassName(handle, buff, n) > 0)
           return buff.ToString();
        return "";
    }
    
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int X, Y, Right, Bottom;
    }
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    public static void Get_loc(IntPtr hWnd, AL4.ArrayInt Coords) {
        Coords.Clear();
        RECT r;
        if (GetWindowRect(hWnd, out r)) {
            Coords.Add(r.X);
            Coords.Add(r.Y);
            Coords.Add(r.Right - r.X);
            Coords.Add(r.Bottom - r.Y);
        }
    }

        public const int SWP_NOSIZE = 0x1;    
        public const int SWP_NOMOVE = 0x2;    
        public const int SWP_NOZORDER = 0x4;    
        public const int SWP_NOACTIVATE = 0x10;    
        public const int SWP_SHOWWINDOW = 0x40;    
    [DllImport("user32.dll")]
    static extern bool SetWindowPos(
            IntPtr hWnd,
            IntPtr hWndInsertAfter,
            int X,
            int Y,
            int cx,
            int cy,
            int flags);
    [DllImport("User32.dll", ExactSpelling=true,
		CharSet=System.Runtime.InteropServices.CharSet.Auto)]
	private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int cx,
		int cy, bool repaint);
    public static void Set_loc(IntPtr hWnd, int X, int Y, bool XY, int W, int H) {
        if (XY && W > 0 && H > 0 && Is_visible(hWnd))
        	MoveWindow((IntPtr)hWnd, X, Y, W, H, true);
        else
	        SetWindowPos(hWnd, (IntPtr)0, X, Y, W, H, (XY ? 0:SWP_NOMOVE) | 
	        (W == 0 && Y == 0 ? SWP_NOSIZE:0) | SWP_NOACTIVATE | SWP_NOZORDER |
	        SWP_SHOWWINDOW);
    }

        public const int SW_HIDE = 0;
        public const int SW_SHOWNORMAL = 1;
        public const int SW_NORMAL = 1;
        public const int SW_SHOWMINIMIZED = 2;
        public const int SW_SHOWMAXIMIZED = 3;
        public const int SW_MAXIMIZE = 3;
        public const int SW_SHOWNOACTIVATE = 4;
        public const int SW_SHOW = 5;
        public const int SW_MINIMIZE = 6;
        public const int SW_SHOWMINNOACTIVE = 7;
        public const int SW_SHOWNA = 8;
        public const int SW_RESTORE = 9;
    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int CmdShow);
    public static void Show(IntPtr hWnd, int show_command, bool activate) {
        if (show_command == SW_SHOW && !activate )
            show_command = SW_SHOWNOACTIVATE;
        ShowWindow(hWnd, show_command);
    }
    
    //[DllImport("user32.dll")]
    //static extern bool BringWindowToTop(IntPtr hWnd);
    public static void Bring_to_front(IntPtr hWnd) {
        //BringWindowToTop(hWnd);
        SetWindowPos(hWnd,
            (IntPtr)0 /* HWND_TOP */,
            0,
            0,
            0,
            0,
            SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    }
    
        public const int WM_CLOSE = 0x10;   
    [DllImport("user32.dll")]
    static extern int PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
    
    public static void Close_window(IntPtr hWnd) {
        PostMessage(hWnd, WM_CLOSE, 0, 0);
    }
    
    	//public const int WM_CANCEL_MODE = 0x1F;
    	public const int WM_KEYDOWN = 0x100;
    	public const int WM_KEYUP = 0x101;
    	public const int WM_CHAR = 0x102;
    	//public const int WM_SYSCOMMAND = 0x112;
    	//public const int SC_CLOSE = 0xF060;
    public static void Send_escape(IntPtr hWnd) {
        //SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0);
        PostMessage(hWnd, WM_KEYDOWN, 27, 0);
        PostMessage(hWnd, WM_CHAR, 0x1B0001, 0);
        PostMessage(hWnd, WM_KEYUP, 27, 0);
        //SendMessage(hWnd, WM_CANCEL_MODE, 0, 0);
    }
    
    [DllImport("user32.dll")]
    static extern uint GetWindowThreadProcessId(
            IntPtr hWnd,
            out int lpdwProcessId);
    
    public static void Close_app(IntPtr hWnd, bool wait) {
        int pid;
        GetWindowThreadProcessId(hWnd, out pid);
        Process p = Process.GetProcessById(pid);
        if (p.CloseMainWindow() && wait)
            p.WaitForExit();
    }
    
    [DllImport("user32.dll")]
    static extern bool EnumChildWindows(
            IntPtr hwndParent, 
            EnumWindowsProc enumProc,
            int lParam);
    delegate bool EnumChildDelegate(IntPtr hWnd, int lParam);
    
    public static void List_child_windows(
            IntPtr hWndParent,
            AL4.ArrayInt Array) {
        handles = new List<IntPtr>();
        EnumChildWindows(hWndParent, new EnumWindowsProc(Enum_child_windows_proc), 0);
        Array.Clear();
        for (int i = 0; i < handles.Count; i++)
            Array.Add((int)handles[i]);
    }
    
    public static bool Enum_child_windows_proc(IntPtr hWnd, int lParam) {
        handles.Add(hWnd);
        return true;
    }
    
    [DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)] 
    public static extern IntPtr GetParent(IntPtr hWnd);
    
    public static long Get_parent_window(
            IntPtr hWnd) {
        return (long)GetParent(hWnd);
    }
    

    /*
    
CONST STR :
    NATIVE_Import_alien_windows = @
    ""

    NATIVE_Caption_fore = @
    "   IntPtr handle = AL4_windows.Get_foreground();"
    "   RESULT = AL4_windows.Get_text(handle);"
    
    NATIVE_Window_fore = @
    "   IntPtr handle = AL4_windows.Get_foreground();"
    "   RESULT = (int)handle;"
    
    //NATIVE_Desktop_window = @
    //"   IntPtr handle = AL4_windows.Get_desktop();"
    //"   RESULT = (int)handle;"
    
    NATIVE_Find_window = @
    "   RESULT = (int)AL4_windows.Find(X_Class, X_Caption);"
    
    NATIVE_List_windows = @
    "   AL4_windows.List_desktop(X_Array, X_Visible);"
    
    NATIVE_Is_window = @
    "   RESULT = AL4_windows.Is_window((IntPtr)X_Handle);"
    
    NATIVE_Is_visible_win = @
    "   RESULT = AL4_windows.Is_visible((IntPtr)X_Handle);"
    
    NATIVE_Is_maximized = @
    "   RESULT = AL4_windows.Is_zoomed((IntPtr)X_Handle);"
    
    NATIVE_Is_minimized = @
    "   RESULT = AL4_windows.Is_iconic((IntPtr)X_Handle);"
    
    NATIVE_Window_caption = @
    "   RESULT = AL4_windows.Get_text((IntPtr)X_Handle);"
    
    NATIVE_Window_class = @
    "   RESULT = AL4_windows.Get_class((IntPtr)X_Handle);"
    
    NATIVE_Window_loc = @
    "   AL4_windows.Get_loc((IntPtr)X_Handle, X_Coord);"
    
    NATIVE_Show_window = @
    "   AL4_windows.Show((IntPtr)X_Handle, "
    "       X_Show ? AL4_windows.SW_SHOW : AL4_windows.SW_HIDE, X_Activate);"
    
    NATIVE_Bring_to_front = @
    "   AL4_windows.Bring_to_front((IntPtr)X_Handle);"
    
    NATIVE_Set_window_loc = @
    "   AL4_windows.Set_loc((IntPtr)X_Handle, "
    "		(int)X_X, (int)X_Y, X_XY, (int)X_W, (int)X_H);"
    
    NATIVE_Minimize = @
    "   AL4_windows.Show((IntPtr)X_Handle, AL4_windows.SW_MINIMIZE, false);"
    
    NATIVE_Restore = @
    "   AL4_windows.Show((IntPtr)X_Handle, AL4_windows.SW_RESTORE, false);"
    
    NATIVE_Cancel_key = @
    "   AL4_windows.Send_escape((IntPtr)X_Handle);"
    
    NATIVE_Close_window = @
    "   AL4_windows.Close_window((IntPtr)X_Handle);"

    NATIVE_Close_app = @
    "   AL4_windows.Close_app((IntPtr)X_Handle, X_Wait);"
    
	NATIVE_Set_foreground = @
	"	AL4_windows.Set_foreground((IntPtr)X_Handle);"
    
    NATIVE_List_child = @
    "   AL4_windows.List_child_windows((IntPtr)X_Handle, X_Child);"
    
    NATIVE_Parent_window = @
    "	RESULT = (int)AL4_windows.Get_parent_window((IntPtr)X_Handle);"     
    
    .
        
    */

}

/*
END
*/
