//\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
// AFXUI auxiliary module for Blazor-application (WASM) | Author: Sergei Y.Kitáev
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
using System;
using System.Threading.Tasks;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Components;

using CommonHelpers.WASM;

namespace AFXUI {

//**************************************************************************************************
public abstract partial class ULayoutComponentBase: LayoutComponentBase,IDisposable {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public bool WasLoaded { get; private set; }
public bool WasDisposed { get; private set; }

public void Dispose()
{
   try { OnDispose(); }
   finally { WasDisposed = true; }
}

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

public void InvokeStateHasChanged() => StateHasChanged();

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

public static bool HasExclusiveOperation => UCircuit.HasExclusiveOperation;
/// <exception cref="InvalidOperationException" />
public static bool WasXOpAbandonedOrCancelled => UCircuit.WasXOpAbandonedOrCancelled;
/// <exception cref="InvalidOperationException" />
public static bool WasExclusiveOpCancelled => UCircuit.WasExclusiveOpCancelled;

/// <exception cref="ArgumentOutOfRangeException" />
public static bool HasExclusiveOperationAt(int level) =>
   UCircuit.HasExclusiveOperationAt( level );

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

/// <exception cref="Exception" />
public static void ProcessRenderingError( Type componentType, Exception e,
                                          bool navigateToErrorPage = true ) =>
   UBreakdown.ProcessRenderingError( componentType, e, navigateToErrorPage );

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

protected override void OnAfterRender(bool firstRender) =>
go_nt(()=>{
   if ( firstRender ) On_Load();
   base.OnAfterRender( firstRender );
   if ( firstRender )
   {
      WasLoaded = true;
      On_AfterLoad();
   }
});
protected virtual void On_Load()
{}
protected virtual void On_AfterLoad()
{}

protected override Task OnAfterRenderAsync(bool firstRender) =>
go_nt(async()=>{
   if ( firstRender ) await On_Load_A();
   await base.OnAfterRenderAsync( firstRender );
   if ( firstRender ) await On_AfterLoad_A();
});
protected virtual async Task On_Load_A() =>
   await Task.Delay(0);
protected virtual async Task On_AfterLoad_A() =>
   await Task.Delay(0);

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

protected virtual void UpdateForRendering() =>
   StateHasChanged();

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

protected virtual void OnDispose()
{
   UCircuit.ExclusiveBegin -= ExclusiveBegin_Handler;
   UCircuit.ExclusiveEnd -= ExclusiveEnd_Handler;
}

protected virtual void OnExclusiveBegin()
{}
protected virtual void OnExclusiveEnd()
{}

protected virtual Task OnExclusiveBegin_A() => Task.Delay(0);
protected virtual Task OnExclusiveEnd_A() => Task.Delay(0);

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

protected override void OnInitialized()
{
   base.OnInitialized();
   UCircuit.ExclusiveBegin += ExclusiveBegin_Handler;
   UCircuit.ExclusiveEnd += ExclusiveEnd_Handler;
}

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

void ExclusiveBegin_Handler(ComponentBase? component) =>
   OnExclusiveBegin();
void ExclusiveEnd_Handler(ComponentBase? component) =>
   OnExclusiveEnd();

Task ExclusiveBegin_Handler_A(ComponentBase? component) =>
   OnExclusiveBegin_A();
Task ExclusiveEnd_Handler_A(ComponentBase? component) =>
   OnExclusiveEnd_A();

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // ULayoutComponentBase
//**************************************************************************************************

} // AFXUI
