using System;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace VictorWinApp
{

[DefaultEvent("ValueChanged")]
[ComVisible(true)]
[DefaultProperty("Value")]
[DefaultBindingProperty("Value")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class ExtendedDateTimePicker : DateTimePicker
{
    #region General
    public ExtendedDateTimePicker()
    {
        //this.ShowCheckBox = true;
    }
    #endregion


    private const int GWL_STYLE = (-16);
    private const int MCM_FIRST = 0x1000;
    private const int MCM_GETMINREQRECT = (MCM_FIRST + 9);
    private const int MCS_WEEKNUMBERS = 0x4;
    private const int DTM_FIRST = 0x1000;
    private const int DTM_GETMONTHCAL = (DTM_FIRST + 8);
    private const Int32 WS_BORDER = 0x800000;
    private const int GWL_HWNDPARENT = (-8);

    private bool m_ShowWeekNumbers;        
    private int m_TextWeek;
    /*
    [DllImport("User32.dll")]
    private static extern int GetWindowLong(IntPtr h, int index);

    [DllImport("User32.dll")]
    private static extern int SetWindowLong(IntPtr h, int index, int value);

    [DllImport("User32.dll")]
    private static extern IntPtr SendMessage(IntPtr h,
                    int msg, int param, int data);

    [DllImport("User32.dll")]
    private static extern int SendMessage(IntPtr h, int msg,
                    int param, ref Rectangle data);

    [DllImport("User32.dll")]
    private static extern int MoveWindow(IntPtr h, int x, int y,
                    int width, int height, bool repaint);
                           */
    [DllImport("User32.dll")]
    public static extern int GetWindowLong(IntPtr h, int index);

    [DllImport("User32.dll")]
    public static extern int SetWindowLong(IntPtr h, int index, int value);

    [DllImport("User32.dll")]
    private static extern IntPtr SendMessage(IntPtr h, int msg, int param, int data);

    [DllImport("User32.dll")]
    private static extern int SendMessage(IntPtr h, int msg, int param, ref Rectangle data);

    [DllImport("User32.dll")]
    private static extern int MoveWindow(IntPtr h, int x, int y, int width, int height, bool repaint);

    [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    private static extern IntPtr GetParent(IntPtr hWnd);

    /// <summary>
    /// Gets or sets whether to show week numbers.
    /// </summary>
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [DefaultValue(false)]
    public bool ShowWeekNumbers
    {
        get
        {
            return m_ShowWeekNumbers;
        }
        set
        {
            m_ShowWeekNumbers = value;
        }
    }

    /// <summary>
    /// Gets or sets whether to show week numbers.
    /// </summary>
    [Browsable(true)]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [DefaultValue(0)]
    public int TextWeek
    {
        get
        {
            // Gets the Calendar instance associated with a CultureInfo.
            //CultureInfo myCI = new CultureInfo("en-US");
            CultureInfo myCI = new CultureInfo("ko-KR");
            Calendar myCal = myCI.Calendar;

            // Gets the DTFI properties required by GetWeekOfYear.
            CalendarWeekRule myCWR = myCI.DateTimeFormat.CalendarWeekRule;
            DayOfWeek myFirstDOW = myCI.DateTimeFormat.FirstDayOfWeek;

            m_TextWeek = myCal.GetWeekOfYear(this.Value, myCWR, myFirstDOW);                
            return m_TextWeek;
        }
        set
        {
            m_TextWeek = value;
        }
    }

    /// <summary>
    /// Gets or sets the date/time value assigned to the control.
    /// </summary>
    /// <exception cref="System.ArgumentOutOfRangeException">
    /// The set value is less than System.Windows.Forms.DateTimePicker.MinDate or more than System.Windows.Forms.DateTimePicker.MaxDate.
    /// </exception>
    //[RefreshProperties(RefreshProperties.All)]
    //[Bindable(true)]
    //public new DateTime? Value
    //{
    //    get
    //    {
    //        if (!base.Checked)
    //        {
    //            return null;
    //        }

    //        return base.Value;
    //    }
    //    set
    //    {
    //        if (value.HasValue)
    //        {
    //            base.Checked = true;

    //            if (this.Format == DateTimePickerFormat.Short)
    //            {
    //                base.Value = value.Value.Date;
    //            }
    //            else if (this.Format == DateTimePickerFormat.Time)
    //            {
    //                base.Value = default(DateTime).Add(value.Value.TimeOfDay);
    //            }
    //            else
    //            {
    //                base.Value = value.Value;
    //            }
    //        }
    //        else
    //        {
    //            base.Checked = false;
    //        }
    //    }
    //}


    /// <summary>
    /// Raises the System.Windows.Forms.DateTimePicker.DropDown event.
    /// </summary>
    /// <param name="e">An System.EventArgs that contains the event data.</param>
    protected override void OnDropDown(EventArgs e)
    {
        //IntPtr monthView = SendMessage(Handle, DTM_GETMONTHCAL, 0, 0);
        //int style = GetWindowLong(monthView, GWL_STYLE);
        //if (ShowWeekNumbers)
        //{
        //    style = style | MCS_WEEKNUMBERS;
        //}
        //else
        //{
        //    style = style & ~MCS_WEEKNUMBERS;
        //}
        //Rectangle rect = new Rectangle();
        //SetWindowLong(monthView, GWL_STYLE, style);
        //SendMessage(monthView, MCM_GETMINREQRECT, 0, ref rect);
        //MoveWindow(monthView, 0, 0, rect.Right + 2, rect.Bottom, true);
        //base.OnDropDown(e);

        //IntPtr hMonthView = SendMessage(this.Handle, DTM_GETMONTHCAL, 0, 0);
        //Int32 hMonthViewParent = GetWindowLong(hMonthView, GWL_HWNDPARENT);
        //// set style to include week numbers
        //Int32 dwStyle = GetWindowLong(hMonthView, GWL_STYLE);
        //if (this.ShowWeekNumbers)
        //{
        //    dwStyle = dwStyle | MCS_WEEKNUMBERS | WS_BORDER;
        //}
        //else
        //{
        //    dwStyle = dwStyle & ~MCS_WEEKNUMBERS;
        //}
        //Rectangle rct = new Rectangle();
        //SetWindowLong(hMonthView, GWL_STYLE, dwStyle);
        //SendMessage(hMonthView, MCM_GETMINREQRECT, 0, ref rct);
        //MoveWindow((IntPtr)hMonthViewParent, 0, 0, rct.Right, rct.Bottom, true);
        //MoveWindow(hMonthView, 0, 0, rct.Right, rct.Bottom, true);
        //base.OnDropDown(e);

        IntPtr monthView = SendMessage(this.Handle, DTM_GETMONTHCAL, 0, 0);
        int style = GetWindowLong(monthView, GWL_STYLE);

        if (this.ShowWeekNumbers)
        {
            style = style | MCS_WEEKNUMBERS;
        }
        else
        {
            style = style & ~MCS_WEEKNUMBERS;
        }
        Rectangle rect = new Rectangle();
        SetWindowLong(monthView, GWL_STYLE, style);
        SendMessage(monthView, MCM_GETMINREQRECT, 0, ref rect);
        MoveWindow(monthView, 0, 0, rect.Right + 3, rect.Bottom, true);
        //
        // Resize the surrounding window to let the new text fit
        //
        IntPtr parent = GetParent(monthView);

        Rectangle mainRect = new Rectangle();
        SendMessage(parent, MCM_GETMINREQRECT, 0, ref mainRect);
        MoveWindow(parent, 0, 0, mainRect.Right + 6, mainRect.Bottom + 6, true);

        base.OnDropDown(e);
    }
}

}