using System;
using System.Globalization;

using CommonHelpers;

namespace TypeInColor {

//**************************************************************************************************
static partial class Program {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

static void PrintSyntax()
{
   HConsole.PrintIntensive(
      "=== {0} utility {1} ({2}): ===",
      TypeInColor_Info.AssemblyName, //Assembly.GetEntryAssembly().GetName().Name
      TypeInColor_Info.VersionStringExCON,
      TypeInColor_Info.CopyrightCON );
   HConsole.PrintExpressive(
      "Syntax: TypeInColor \"<Color>\" \"<File to print>\"" );
   HConsole.PrintIntensive(
      "Supported parameters (valid \"...\" or empty: \"\"):" );
   HConsole.PrintExpressive(
      "1) Color value (decimal or hex.with prefix) or console color name (optional param.);\n"+
      "2) Text file path (required param.)." );
   HConsole.PrintFaint(
      "You may specify \"\" (empty value) for optional parameter(s)." );
   HConsole.PrintIntensive(
      "Color codes and names:" );
   HConsole.Print(
      "00 0x0 {0} Black\n"+
      "01 0x1 {0} DarkBlue\n"+
      "02 0x2 {0} DarkGreen\n"+
      "03 0x3 {0} DarkCyan\n"+
      "04 0x4 {0} DarkRed\n"+
      "05 0x5 {0} DarkMagenta\n"+
      "06 0x6 {0} DarkYellow\n"+
      "07 0x7 {0} Gray\n"+
      "08 0x8 {0} DarkGray\n"+
      "09 0x9 {0} Blue\n"+
      "10 0xA {0} Green\n"+
      "11 0xB {0} Cyan\n"+
      "12 0xC {0} Red\n"+
      "13 0xD {0} Magenta\n"+
      "14 0xE {0} Yellow\n"+
      "15 0xF {0} White",
      DashChar );
   HConsole.PrintFaint(
      "Color names are case insensitive." );
}

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

/// <exception cref="ArgumentNullException" />
static HAppFailureException CreateParameterError(int paramIdx,string message)
{
   HArgChecking.VerifyNotNull( message );
   return HAppFailureExceptionCreator.Create(
      "{0}\n"+
      "Parameter: {1} (argument number).",
      message, paramIdx+1 );
}
/// <exception cref="ArgumentNullException" />
static HAppFailureException CreateParameterError( int paramIdx,
                                                  string messageFmt,
                                                  params object[] parameters )
{
   return CreateParameterError( paramIdx, string.Format( messageFmt, parameters ) );
}

static string ArgumentNumDisplay(int paramIdx)
{
   return "#"+HInt32.ToNormalString( paramIdx+1 );
}

/// <exception cref="HAppFailureException" />
static void CheckParameterNormality(string value,int paramIdx)
{
   if ( HString.HasBoundaryWhiteSpace( value ) )
      throw CreateParameterError( paramIdx,
         "Parameter values must not have leading and/or trailing spaces." );
}

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

/// <exception cref="ArgumentNullException" />
static bool ParseColor(string strValue,out ConsoleColor value)
{
   bool IS_VALID_CODE(int num)
   {
      return HOps.IsBetween( num, 0, 0xF );
   }
   HArgChecking.VerifyNotNull( strValue );
   strValue = strValue.Trim();
   value = 0;
   int code;
   if ( strValue.StartsWith( "0x" ) )
   {
      if ( Int32.TryParse( strValue.Substring( 2 ),
                           NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture,
                           out code ) &&
           IS_VALID_CODE( code ) )
         goto FROM_CODE;
      return false;
   }
   if ( Int32.TryParse( strValue, 0, CultureInfo.InvariantCulture, out code ) &&
        IS_VALID_CODE( code ) )
      goto FROM_CODE;
   if ( Enum.TryParse<ConsoleColor>( strValue, true, out ConsoleColor color ) &&
        IS_VALID_CODE( (int)color ) )
   {
      value = color;
      return true;
   }
   return false;
FROM_CODE:
   value = (ConsoleColor)code;
   return true;
}

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

const char DashChar = HConsole.DashChar;
const string LongDash = HConsole.LongDash;

static string OnValueName  => "on";
static string OffValueName => "off";

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // Program
//**************************************************************************************************

} // TypeInColor
