using System;
using System.Text;

namespace CommonHelpers {

//**************************************************************************************************
partial class LnkVariableProcessor {
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/// <exception cref="VariableProcessingException" />
void Scan()
{
   while ( !EndOfSource )
   {
      char ch = CurrentChar;
      if ( IsVarOpen )
      {
         if ( IsPercentVariable && IsPercentChar )
            { CompleteVariable(); goto OUTPUT; }
         if ( IsDollarVariable && IsDVClosingBraketChar )
            { CompleteVariable(); goto NEXT; }
         ValidateCurrentCharAgainstOpenVarName();
         VarNameBuilder.Append( ch );
      }
      else
      {
         if ( CheckVariables && IsPercentChar )
            { OpenVariable(); goto OUTPUT; }
         if ( ExpandDollarVariables && IsDollarChar && NextCharIsDVOpeningBraket )
            { OpenVariable( true ); Next(); goto NEXT; }
      }
OUTPUT:
      if ( !IsDollarVariable )
         Output.Append( ch );
NEXT:
      Next();
   }
   if ( !IsVarOpen )
      return;
   if ( IsPercentVariable )
      throw CreateExceptionWithPosInfo(
         HLnkConverter.Verbose.
         REFERENCE_TO_ENVIRONMENT_VARIABLE_WAS_NOT_TERMINATED_BY_PERCENT_SIGN_0,
         PercentVariableChar );
   if ( IsDollarVariable )
      throw CreateExceptionWithPosInfo(
         HLnkConverter.Verbose.
         REFERENCE_TO_ENVIRONMENT_VARIABLE_WAS_NOT_TERMINATED_BY_PARENTHESIS_0,
         DVClosingBraketChar );
   HAssertion.FAIL();
}

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

/// <exception cref="VariableProcessingException" />
void CompleteVariable()
{
   HAssertion.Verify( IsVarOpen );
   string variableName = VarNameBuilder.ToString();
   if ( variableName == "" )
      throw CreateExceptionWithPosInfo( VariablePos, IsDollarVariable ?
         HLnkConverter.Verbose.
         REFERENCE_TO_EMPTY_NAME_OF_DOLLAR_VARIABLE_OF_ENVIRONMENT_WAS_ENCOUNTERED :
         HLnkConverter.Verbose.REFERENCE_TO_EMPTY_NAME_OF_ENVIRONMENT_VARIABLE_WAS_ENCOUNTERED );
   string variableValue;
   try {
      variableValue = Environment.GetEnvironmentVariable( variableName ); }
   catch (Exception e) {
      throw CreateExceptionWithPosInfo( VariablePos,
         HLnkConverter.Verbose.CAN_NOT_EXTRACT_VALUE_OF_ENVIRONMENT_VARIABLE_0__1,
         variableName, e.Message ); }
   if ( string.IsNullOrEmpty( variableValue ) )
      if ( IsDollarVariable && UndefinedDollarVarsAsEmpty )
         variableValue = "";
      else
         throw CreateExceptionWithPosInfo( VariablePos,
            HLnkConverter.Verbose.REFERENCE_TO_UNDETERMINED_OR_EMPTY_VARIABLE_OF_ENVIRONMENT_0,
            variableName );
   if ( IsDollarVariable )
      Output.Append( variableValue );
   CloseVariable();
}

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

/// <exception cref="VariableProcessingException" />
void ValidateCurrentCharAgainstOpenVarName()
{
   if ( !IsVarOpen )
      return;
   if ( IsDollarVariable )
   {
      if ( IsPercentChar )
         throw CreateExceptionWithPosInfo( HLnkConverter.Verbose.
            NAME_OF_DOLLAR_VARIABLE_OF_ENVIRONMENT_MUST_NOT_CONTAIN_PERCENT_SIGN_CHARACTERS_0,
            PercentVariableChar );
      if ( IsDVOpeningBraketChar || IsDVClosingBraketChar )
         throw CreateExceptionWithPosInfo( HLnkConverter.Verbose.
            NAME_OF_DOLLAR_VARIABLE_OF_ENVIRONMENT_MUST_NOT_CONTAIN_PARENTHESIS_0_1,
            DVOpeningBraketChar, DVClosingBraketChar );
   }
   //if ( IsPercentVariable )
   //{}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} // LnkVariableProcessor
//**************************************************************************************************

} // CommonHelpers
