using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Drawing;

namespace pcmp
{
    delegate bool EnumWindowsProcDelegate(IntPtr hWnd, int lParam);

    internal static class Win32
    {
        // Parameters for ListView-Headers
        public const Int32 HDI_FORMAT = 0x0004;
        public const Int32 HDF_LEFT = 0x0000;
        public const Int32 HDF_STRING = 0x4000;
        public const Int32 HDF_SORTUP = 0x0400;
        public const Int32 HDF_SORTDOWN = 0x0200;
        public const Int32 LVM_GETHEADER = 0x1000 + 31;  // LVM_FIRST + 31
        public const Int32 HDM_GETITEM = 0x1200 + 11;  // HDM_FIRST + 11
        public const Int32 HDM_SETITEM = 0x1200 + 12;  // HDM_FIRST + 12

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, ref COPYDATASTRUCT cpStruct);

        [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        public static extern int GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);

        [DllImport("user32.dll")]
        public static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        public static extern bool AttachThreadInput(int idAttach, int idAttachTo, bool fAttach);

        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();

        [DllImport("user32.dll", SetLastError = true)]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumWindows(EnumWindowsProcDelegate lpEnumFunc, int lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        #region obsolete

        [DllImport("user32.dll", SetLastError = true)]
        internal static extern bool ValidateRect(IntPtr window, IntPtr rect);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern int DrawText(IntPtr hdc, string lpStr, int nCount, ref RECT lpRect, int wFormat);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern int DrawTextEx(IntPtr hdc, string lpchText, int cchText, ref RECT lprc,
            uint dwDTFormat, ref DRAWTEXTPARAMS lpDTParams);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern bool TextOut(IntPtr hdc, int nXStart, int nYStart,
           string lpString, int cbString);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern bool ExtTextOut(IntPtr hdc, int X, int Y, uint fuOptions,
           [In] ref RECT lprc, string lpString, uint cbCount, //int[] lpDx);
            int lpDx);

        [DllImport("gdi32.dll")]
        public static extern uint SetTextAlign(IntPtr hdc, uint fMode);

        [DllImport("gdi32.dll")]
        public static extern int SetTextColor(IntPtr hdc, int crColor);

        [DllImport("gdi32.dll")]
        public static extern int SetBkColor(IntPtr hdc, int crColor);

        [DllImport("gdi32.dll")]
        public static extern int SetBkMode(IntPtr hdc, int iBkMode);

        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobj);

        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern bool GetTextExtentPoint32(IntPtr hdc, string lpString,
           int cbString, out SIZE lpSize);

        [DllImport("gdi32.dll", CharSet = CharSet.Unicode)]
        public static extern bool GetTextMetrics(IntPtr hdc, out TEXTMETRIC lptm);

        public static int ColorToRGB(Color crColor)
        {
            return crColor.B << 16 | crColor.G << 8 | crColor.R;
        }

        public const int TRANSPARENT = 1;
        public const int OPAQUE = 2;

        public struct SIZE
        {
            public int cx;
            public int cy;

            public SIZE(Size s)
            {
                this.cx = s.Width;
                this.cy = s.Height;
            }
        }

        public struct RECT
        {
            public int Left, Top, Right, Bottom;
            public RECT(Rectangle r)
            {
                this.Left = r.Left;
                this.Top = r.Top;
                this.Bottom = r.Bottom;
                this.Right = r.Right;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DRAWTEXTPARAMS
        {
            public uint cbSize;
            public int iTabLength;
            public int iLeftMargin;
            public int iRightMargin;
            public uint uiLengthDrawn;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct TEXTMETRIC
        {
            public int tmHeight;
            public int tmAscent;
            public int tmDescent;
            public int tmInternalLeading;
            public int tmExternalLeading;
            public int tmAveCharWidth;
            public int tmMaxCharWidth;
            public int tmWeight;
            public int tmOverhang;
            public int tmDigitizedAspectX;
            public int tmDigitizedAspectY;
            public char tmFirstChar;
            public char tmLastChar;
            public char tmDefaultChar;
            public char tmBreakChar;
            public byte tmItalic;
            public byte tmUnderlined;
            public byte tmStruckOut;
            public byte tmPitchAndFamily;
            public byte tmCharSet;
        } 
        #endregion

        [StructLayout(LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            public int dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct HDITEM
        {
            public Int32 mask;
            public Int32 cxy;
            [MarshalAs(UnmanagedType.LPTStr)]
            public String pszText;
            public IntPtr hbm;
            public Int32 cchTextMax;
            public Int32 fmt;
            public Int32 lParam;
            public Int32 iImage;
            public Int32 iOrder;
        };

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        public static extern IntPtr SendMessage(IntPtr Handle, Int32 msg, IntPtr wParam, ref HDITEM lParam);
    }

    [Flags()]
    public enum DrawTextFlags : uint
    {
        DT_TOP = 0x0,
        DT_LEFT = 0x0,
        DT_CENTER = 0x1,
        DT_RIGHT = 0x2,
        DT_VCENTER = 0x4,
        DT_BOTTOM = 0x8,
        DT_WORDBREAK = 0x10,
        DT_SINGLELINE = 0x20,
        DT_EXPANDTABS = 0x40,
        DT_TABSTOP = 0x80,
        DT_NOCLIP = 0x100,
        DT_EXTERNALLEADING = 0x200,
        DT_CALCRECT = 0x400,
        DT_NOPREFIX = 0x800,
        DT_INTERNAL = 0x1000,
        DT_EDITCONTROL = 0x2000,
        DT_PATH_ELLIPSIS = 0x4000,
        DT_END_ELLIPSIS = 0x8000,
        DT_MODIFYSTRING = 0x10000,
        DT_RTLREADING = 0x20000,
        DT_WORD_ELLIPSIS = 0x40000,
        DT_NOFULLWIDTHCHARBREAK = 0x80000,
        DT_HIDEPREFIX = 0x100000,
        DT_PREFIXONLY = 0x200000
    }

    // Text alignment constants
    // These are used with the SetTextAlign() system call
    [Flags()]
    public enum TextAlignmentFlags
    {
        TA_NOUPDATECP = 0,
        TA_UPDATECP = 1,

        TA_LEFT = 0,
        TA_RIGHT = 2,
        TA_CENTER = 6,

        TA_TOP = 0,
        TA_BOTTOM = 8,
        TA_BASELINE = 24,
        TA_RTLREADING = 256,
        TA_MASK = (TA_BASELINE + TA_CENTER + TA_UPDATECP + TA_RTLREADING),

        // These are used with the text layout is vertical
        VTA_BASELINE = TA_BASELINE,
        VTA_LEFT = TA_BOTTOM,
        VTA_RIGHT = TA_TOP,
        VTA_CENTER = TA_CENTER,
        VTA_BOTTOM = TA_RIGHT,
        VTA_TOP = TA_LEFT
    }

    public enum WindowsMessages
    {
        WM_COPYDATA = 0x4A,
        WM_QUERYENDSESSION = 0x11,
    }
}
