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

namespace CommonHelpers {

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

public bool PendingNewLine
{
   get { lock ( _InstanceSyncRoot_ ) return _PendingNewLine_; }
}

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

/// <exception cref="InvalidOperationException" />
public void Clear()
{
   lock ( _InstanceSyncRoot_ )
   {
      VerifyNotInTextWriterMode();
      if ( IsOnStdOutput )
      {
         VerifyNotInStdOutputBackground();
         Console.Clear();
      }
      else
      if ( ReliesOnProxy )
      {
         if ( _ProxySettings_.ClearCallback == null )
            throw new InvalidOperationException(
               "Console cleanup operation is not possible because the callback was not specified "+
               "during creation of the proxy." );
         _ProxySettings_.ClearCallback();
      }
      else
         HAssertionFailure.DEAD_BRANCH();
      _PendingNewLine_ = false;
   }
}

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

public void FlushPendingNewLine()
{
   lock ( _InstanceSyncRoot_ )
      if ( _PendingNewLine_ )
      {
         WriteLine(); _PendingNewLine_ = false;
      }
}

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

public string ExpandOutputText(string str)
{
   HArgChecking.VerifyNotNull( str );
   return str.Replace( HUnicode.EmDash.ToString(), LongDash );
}

public string ExpandOutputText(string stringFmt,params object[] parameters)
{
   return ExpandOutputText( string.Format(stringFmt,parameters) );
}

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

void PerformOutput(StringBuilder sb,bool feedLine)
{
   var stringBuilder = new StringBuilder();

   for (int i=0; i<sb.Length; i++)
      stringBuilder.Append( CharToPrintable( sb[i] ) );

   string outputStr = stringBuilder.ToString();

   if ( !_IgnoreFlushPendingNewLine_ )
      FlushPendingNewLine();

   if ( !IsInNativeVisualMode )
   {
      WriteOrWriteLine( outputStr, feedLine );
      if ( IsInTextWriterMode && AutoFlushTextWriter )
         TextWriter.Flush();
      return;
   }

   WriteOrWriteLine( outputStr, feedLine );
/*
   int width = _IsInStringInputRoutine_ ? Console.BufferWidth : Console.BufferWidth-1;
   while ( stringBuilder.Length > 0 )
   {
      if ( Console.CursorLeft >= width )
         WriteLine();
      int
         startPos = Console.CursorLeft,
         portionLength = Math.Min(
            HArith.ConfinePositiveOrZero( width - startPos ),
            stringBuilder.Length );
      var portionDest = new char[ portionLength ];
      stringBuilder.CopyTo( 0, portionDest, 0, portionLength );
      stringBuilder.Remove( 0, portionLength );
      string portionStr = new string( portionDest );
      if ( startPos + portionLength == width )
         WriteLine( portionStr );
      else
         Write( portionStr );
      if ( Console.CursorLeft == 0 )
         if ( stringBuilder.Length == 0 )
            feedLine = false;
         else
            if ( stringBuilder[ 0 ]==' ' )
               stringBuilder.Remove( 0, 1 );
   }
   if ( feedLine )
      WriteLine();
*/
}

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

void Write(string str)
{
   if ( IsOnStdOutput )
      Console.Write( str );
   else
   if ( ReliesOnProxy )
      _ProxySettings_.WriteCallback( _ProxyForegroundColor_, str );
   else
   if ( IsInTextWriterMode )
      TextWriter.Write( str );
   else
      HAssertionFailure.DEAD_BRANCH();
   CursorLeft_Calculated += str.Length;
}

void WriteLine(string str)
{
/*
   if ( IsInNativeVisualMode )
   {
      Console.Write( str );
      using ( new HConsoleColorRetention( this, null, InitialNativeBackgroundColor ) )
         Console.WriteLine();
   }
   else
*/
   if ( IsOnStdOutput )
      Console.WriteLine( str );
   else
   if ( ReliesOnProxy )
      _ProxySettings_.WriteLineCallback( _ProxyForegroundColor_, str );
   else
   if ( IsInTextWriterMode )
      TextWriter.WriteLine( str );
   else
      HAssertionFailure.DEAD_BRANCH();
   CursorLeft_Calculated = 0;
}

void WriteLine()
{
   WriteLine( "" );
}

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

void WriteOrWriteLine(string str,bool feedLine)
{
   if ( feedLine ) WriteLine( str );
   else Write( str );
}

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

} // CommonHelpers
