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

namespace CommonHelpers {

//**************************************************************************************************
partial class HConsole {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine, string caption,
                                  string[] actions, [HOptional] bool[] enablings )
{
   return PerformNumberedDialog(insertBlankLine,caption,actions,enablings,null);
}

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

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      null, actions, enablings,
      cancelAction, cancelAction!=null ? ConsoleKey.Escape : 0 );
}

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction,
                                  [HOptional] ConsoleKey cancelKey )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      null, actions, enablings,
      cancelAction, cancelKey );
}

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction,
                                  [HOptional] ConsoleKey cancelKey,
                                  [HOptional] ConsoleModifiers cancelModifiers )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      null, actions, enablings,
      cancelAction, cancelKey, cancelModifiers );
}

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

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  string[] actions,
                                  [HOptional] bool[] enablings )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, false, actions, enablings,
      null, 0 );
}

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

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, false, actions, enablings,
      cancelAction, cancelAction!=null ? ConsoleKey.Escape : 0 );
}

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction,
                                  [HOptional] ConsoleKey cancelKey )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, false, actions, enablings,
      cancelAction, cancelKey );
}

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction,
                                  [HOptional] ConsoleKey cancelKey,
                                  [HOptional] ConsoleModifiers cancelModifiers )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, false, actions, enablings,
      cancelAction, cancelKey, cancelModifiers );
}

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

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  bool placeZeroActionDown,
                                  string[] actions,
                                  [HOptional] bool[] enablings )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, placeZeroActionDown, actions, enablings,
      null, 0 );
}

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

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  bool placeZeroActionDown,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, placeZeroActionDown, actions, enablings,
      cancelAction, cancelAction!=null ? ConsoleKey.Escape : 0 );
}

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  bool placeZeroActionDown,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction,
                                  [HOptional] ConsoleKey cancelKey )
{
   return PerformNumberedDialog(
      insertBlankLine, caption,
      zeroAction, placeZeroActionDown, actions, enablings,
      cancelAction, cancelKey, 0 );
}

/// <exception cref="InvalidOperationException" />
/// <exception cref="HAbortConsoleInputException" />
public int PerformNumberedDialog( bool insertBlankLine,
                                  string caption,
                                  [HOptional] string zeroAction,
                                  bool placeZeroActionDown,
                                  string[] actions,
                                  [HOptional] bool[] enablings,
                                  [HOptional] string cancelAction,
                                  [HOptional] ConsoleKey cancelKey,
                                  [HOptional] ConsoleModifiers cancelModifiers )
{
   HArgChecking.VerifyNotNull( caption );
   HArgChecking.VerifyNotNulls( actions );

   if ( zeroAction==null && placeZeroActionDown ||
        !( cancelAction!=null && cancelKey!=0 ||
           cancelAction==null && cancelKey==0 && cancelModifiers==0 ) ||
        enablings!=null && enablings.Length!=actions.Length )
      throw HArgChecking.ArgumentException_IncorrectArguments;

   int actionCount = actions.Length;

   if (!HOps.IsBetween(actionCount,1,9))
      throw HArgumentOutOfRangeExceptionCreator.Create(
         "Numbered dialog actions count must be within 1..9." );

   int nonZeroActionCount = actionCount;

   if (zeroAction!=null)
      actionCount++;

   bool startWithZeroAction =
      zeroAction!=null && !placeZeroActionDown;

   var keyArray = new ConsoleKey[ actionCount ];

   if (zeroAction!=null)
   {
      actions = startWithZeroAction ?
         HArray.Prefix( actions, zeroAction ) :
         HArray.Append( actions, zeroAction );
      int zeroActionIdx =
         startWithZeroAction ? 0 : actionCount-1;
      keyArray[ zeroActionIdx ] = ConsoleKey.D0;
      actions [ zeroActionIdx ] = zeroAction;
   }

   for ( int i=0, j=0;
         i < nonZeroActionCount;
         i++, j++ )
      keyArray[ i + (startWithZeroAction ? 1 : 0) ] =
         (ConsoleKey)( (int)ConsoleKey.D1 + j );

   int dialogResult = PerformDialog(
      insertBlankLine, caption,
      actions, enablings, keyArray,
      cancelAction, cancelKey, cancelModifiers );

   if (dialogResult<0)
      return dialogResult;
   if (placeZeroActionDown)
      return dialogResult < actionCount-1 ? dialogResult+1 : 0;
   return dialogResult;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // HConsole
//**************************************************************************************************

} // CommonHelpers
