//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//
// WFX satellite library | Author: Sergei Y.Kitáev
//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;

using WF = System.Windows.Forms;
using DRW = System.Drawing;

using CommonHelpers;

namespace WFX {

//**************************************************************************************************
partial class Form {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public static WF.DialogResult ShowDialog(WF.Form form)
{
   return ShowDialog( form, false );
}

public static WF.DialogResult ShowDialog(WF.Form form,bool saveCursor)
{
   return ShowDialogWithOwner( form, Application.AnchorWindow, saveCursor );
}

//--------------------------------------------------------------------------------------------------

public static WF.DialogResult ShowDialogWithOwner(WF.Form form,[HOptional] WF.IWin32Window owner)
{
   return ShowDialogWithOwner( form, owner, false );
}

public static WF.DialogResult ShowDialogWithOwner( WF.Form form,
                                                   [HOptional] WF.IWin32Window owner,
                                                   bool saveCursor )
{
   HArgChecking.VerifyNotNull( form );
   HProgram.VerifyInMainThread();

   WF.Cursor savedCursor = null;

   if ( saveCursor )
      savedCursor = WF.Cursor.Current;

   var result = owner!=null ? form.ShowDialog( owner ) : form.ShowDialog();

   if ( saveCursor )
      WFX.Cursor.Override( savedCursor );

   return result;
}

//--------------------------------------------------------------------------------------------------

public static WF.DialogResult ShowDialogByMainForm(WF.Form form)
{
   return ShowDialogWithOwner( form, Application.MainForm, false );
}

public static WF.DialogResult ShowDialogByMainForm(WF.Form form,bool saveCursor)
{
   return ShowDialogWithOwner( form, Application.MainForm, saveCursor );
}

//==================================================================================================

public static bool IsWindowEnabled(WF.Form form)
{
   HArgChecking.VerifyNotNull( form );
   HProgram.VerifyInMainThread();
   return IsWindowEnabled( form.Handle );
}

public static bool IsWindowEnabled(IntPtr hWnd)
{
   return Win32.IsWindowEnabled( hWnd );
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
public static bool EnableSystemMenuCloseItem(WF.Form form)
{
   return EnableSystemMenuCloseItem( form, true );
}

/// <exception cref="ArgumentNullException" />
public static bool EnableSystemMenuCloseItem(WF.Form form,bool enable)
{
   HArgChecking.VerifyNotNull( form );
   IntPtr hMenu = Win32.GetSystemMenu(
      form.Handle, false );
   return
      hMenu != IntPtr.Zero &&
      Win32.EnableMenuItem( hMenu, Win32.SC_CLOSE,
         Win32.MF_BYCOMMAND | (enable ? Win32.MF_ENABLED : Win32.MF_GRAYED) )
      != unchecked((uint)-1);
}

//--------------------------------------------------------------------------------------------------

/// <exception cref="ArgumentNullException" />
public static bool DisableSystemMenuCloseItem(WF.Form form)
{
   return EnableSystemMenuCloseItem( form, false );
}

//==================================================================================================

/// <exception cref="ArgumentNullException" />
public static void UpdateForWaiting(WF.Form form)
{
   HArgChecking.VerifyNotNull( form ); WFX.Cursor.SetWait(); form.Update();
}

//==================================================================================================

public static bool CloseAndDispose([HOptional] WF.Form form)
{
   if ( form == null ) return false;
   form.Close(); form.Dispose(); return true;
}

[CLSCompliant(false)]
public static bool CloseAndDispose([HOptional] ref WF.Form form)
{
   if ( !CloseAndDispose( form ) ) return false;
   form = null; return true;
}

//==================================================================================================

[HOptionalResult]
public static WF.Form FromHandle([HOptional] WF.IWin32Window window)
{
   return window != null ?
      WF.Control.FromHandle( window.Handle ) as WF.Form :
      null;
}

//==================================================================================================

public static bool CenterBy(WF.Form form,[HOptional] WF.Control centerByElement)
{
   HArgChecking.VerifyNotNull( form );
   HProgram.VerifyInMainThread();

   var screen = WF.Screen.FromControl( form );
   if ( centerByElement != null &&
         WF.Screen.FromControl( centerByElement ).DeviceName != screen.DeviceName )
      return false;
   var wa = screen.WorkingArea;

   DRW.Point leftTop;
   int x, y, w, h;

   if ( centerByElement != null )
   {
      leftTop = centerByElement is WF.Form ?
         new DRW.Point( centerByElement.Left, centerByElement.Top ) :
         centerByElement.PointToScreen( new DRW.Point() );
      w = centerByElement.Width;
      h = centerByElement.Height;
   }
   else
   {
      leftTop = new DRW.Point( wa.Left, wa.Top );
      w = wa.Width; h = wa.Height;
   }

   x = leftTop.X + HArith.RoundDiv( w-form.Width, 2 );
   y = leftTop.Y + HArith.RoundDiv( h-form.Height, 2 );

   form.Location = new DRW.Point(
      (int)Math.Max( Math.Min(x,wa.Right-form.Width), wa.Left ),
      (int)Math.Max( Math.Min(y,wa.Bottom-form.Height), wa.Top ) );

   return true;
}

//--------------------------------------------------------------------------------------------------

public static bool TryFitIntoWorkingArea(WF.Form form)
{
   HArgChecking.VerifyNotNull( form );
   HProgram.VerifyInMainThread();

   var wa = WF.Screen.FromControl( form ).WorkingArea;

   form.Location = new DRW.Point(
      Math.Max( wa.Left, Math.Min( form.Left, wa.Right-form.Width ) ),
      Math.Max( wa.Top, Math.Min( form.Top, wa.Bottom-form.Height ) )
   );

   return
      form.Left >= wa.Left && form.Right <= wa.Right &&
      form.Top  >= wa.Top  && form.Bottom <= wa.Bottom;
}

//==================================================================================================

static Form()
{
   WFX_Library.Access();
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // Form
//**************************************************************************************************

} // WFX
