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

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

using CommonHelpers;

namespace WFX {

//**************************************************************************************************
/// <summary>
/// </summary>
public partial class Form: WF.Form {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public event EventHandler WindowStateChanged;

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

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsBlockedForClose
{
   get { return _IsBlockedForClose_; }
   set { _IsBlockedForClose_ = value; ImplementIsBlockedForCloseProperty(); }
}

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ResetCursorOnShown { get; set; }

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DefaultValue(true)]
public bool SetsAnchorWindowOnActivation { get; set; }

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DefaultValue(true)]
public bool UpdateOnShown { get; set; }

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

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsMainAppForm
{
   get { return Application.MainForm == this; }
}

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

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsActive
{
   get { return WF.Form.ActiveForm == this; }
}

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

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsMaximized
{
   get { return WindowState == WF.FormWindowState.Maximized; }
}

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsMinimized
{
   get { return WindowState == WF.FormWindowState.Minimized; }
}

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool IsInNormalState
{
   get { return WindowState == WF.FormWindowState.Normal; }
}

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

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public WF.FormWindowState PreviousWindowState
{
   get { return _PreviousWindowState_; }
}

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

public Form()
{
   _WindowState_ = _PreviousWindowState_ = WindowState;
   UpdateOnShown = true;
   SetsAnchorWindowOnActivation = true;
}

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

public bool CenterBy([HOptional] WF.Control centerByElement)
{
   return CenterBy( this, centerByElement );
}

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

public bool TryFitIntoWorkingArea()
{
   return TryFitIntoWorkingArea( this );
}

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

public new WF.DialogResult ShowDialog()
{
   return ShowDialog( this );
}
public WF.DialogResult ShowDialog(bool saveCursor)
{
   return ShowDialog( this, saveCursor );
}

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

public WF.DialogResult ShowDialogWithOwner([HOptional] WF.Form owner)
{
   return ShowDialogWithOwner( this, owner );
}
public WF.DialogResult ShowDialogWithOwner([HOptional] WF.Form owner,bool saveCursor)
{
   return ShowDialogWithOwner( this, owner, saveCursor );
}

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

public WF.DialogResult ShowDialogByMainForm()
{
   return ShowDialogByMainForm( this );
}
public WF.DialogResult ShowDialogByMainForm(bool saveCursor)
{
   return ShowDialogByMainForm( this, saveCursor );
}

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

public void Reshow()
{
   Restore(); Visible = true; Activate();
}

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

public void Restore()
{
   if ( WindowState == WF.FormWindowState.Minimized )
      WindowState = PreviousWindowState;
}

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

public bool BringToForeground()
{
   HOperationFailedException error;
   return BringToForeground(out error);
}

public bool BringToForeground(out HOperationFailedException error)
{
   if ( !Win32.SetForegroundWindow( Handle ) )
   {
      error = HOpFailedExceptionCreator.Create( HWin32Error.CreateExceptionFromLastError() );
      return false;
   }
   error = null; return true;
}

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

public void UpdateForWaiting()
{
   Form.UpdateForWaiting( this );
}

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

public void CloseAndDispose()
{
   CloseAndDispose( this );
}

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

protected override void OnLoad(EventArgs e)
{
   ImplementIsBlockedForCloseProperty();
   base.OnLoad( e );
}

protected override void OnShown(EventArgs e)
{
   if ( UpdateOnShown ) Update();
   base.OnShown( e );
   if ( ResetCursorOnShown ) WFX.Cursor.Reset();
}

protected override void OnFormClosing(WF.FormClosingEventArgs e)
{
   if ( IsBlockedForClose && !Application.IsClosing )
   {
      if ( IsMainAppForm ) HSound.PlayDisabled();
      e.Cancel = true; return;
   }
   base.OnFormClosing( e );
}

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

protected override void OnActivated(EventArgs e)
{
   if ( SetsAnchorWindowOnActivation )
      Application.AnchorWindow = this;
   base.OnActivated( e );
   Application.RaiseFormActivated( this );
}

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

protected override void OnClientSizeChanged(EventArgs e)
{
   base.OnClientSizeChanged( e );
   if ( WindowState != _WindowState_ )
   {
      _PreviousWindowState_ = HOps.Exchange( ref _WindowState_, WindowState );
      OnLastWindowStateChanged( e );
   }
}

protected virtual void OnLastWindowStateChanged(EventArgs e)
{
   ImplementIsBlockedForCloseProperty();
   if ( WindowStateChanged != null )
      WindowStateChanged( this, e );
}

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

void ImplementIsBlockedForCloseProperty()
{
   EnableSystemMenuCloseItem( this, !_IsBlockedForClose_ );
}

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

bool
   _IsBlockedForClose_;
WF.FormWindowState
   _WindowState_,
   _PreviousWindowState_;

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

} // WFX
