# Terminal Input - Examples

Here you can find examples of `Input` class usage.

## Instance

To use the `Input` class, you need to access it through the `CLI` class, as demonstrated in the example below:

```php
use const Bootgly\CLI;

$Input = CLI->Terminal->Input;
```

## Configuration

`configure()` examples:

### Blocking, canonical and echo modes disabled

```php
$Input->configure(blocking: false, canonical: false, echo: false);
```

When using Input in this way, you configure the Terminal to receive the data automatically as they are typed by the user. Each character is received and already sent to input without going through a buffer.

Use a loop to process the data input (see example below).

To reset all Terminal settings to the default, just call configure without passing any arguments:

```php
$Input->configure();
```

## Use

### Reading data with reading()

```php
reading(\Closure $CAPI, \Closure $SAPI)
```

Example of a `reading` method implementation:

```php
<?php
namespace Bootgly\CLI;


use const Bootgly\CLI;


$Input = CLI->Terminal->Input;
$Output = CLI->Terminal->Output;


$Output->render(<<<OUTPUT
/* @*:
 * @#green: Bootgly CLI Terminal (<<) - reading method @;
 * @#yellow: @@ Demo - Example #1 @;
 * {$location}
 */\n\n
OUTPUT);


$Input->reading(
   // Terminal Client API
   CAPI: function ($read, $write) // Client Input { $read, $write }
   use ($Output)
   {
      // * Config
      $expire = true;
      $timeout = 20; // total timeout in seconds since client was started
      // @ Mode
      $secret = false;
      $hidden = false;
      // * Data
      $line = '';
      $decoded = '';
      // * Meta
      $started = microtime(true);
      // @ ANSI Code
      $decoding = false;

      $Output->render("@:info: Type any character (even special characters)...\n");
      $Output->render("@:info: Type `enter` to send to Terminal Server... @;\n");
      $Output->render("@:info: Type `*` or `#` to toggle the input mode to secret/hidden... @;\n\n");

      while (true) {
         // @ Autoread each character from Terminal Input (in non-blocking mode)
         // This is as if the terminal input buffer is disabled
         $char = $read(length: 1); // Only length === 1 is acceptable (for now)

         // @ Check timeout
         if ($expire && (microtime(true) - $started) > $timeout) {
            echo "Client: `Terminal Input timeout! Closing Client...`\n\n";
            exit(0);
         }

         // @ Parse char
         // No data
         if ($char === '') {
            $write(data: $char); // No effect
            usleep(100000);
            continue;
         }
         // ANSI Code
         if ( $char === "\e" || ($decoding && $char === '[') ) {
            $decoding = true;
            $char = '';
            continue;
         }
         // EOL
         if ($char === "\n") {
            // @ Write user data to Terminal Input (Client => Server)
            $write(data: $line);
            $line = '';
            continue;
            #break;
         }
         // ...

         // @ Toggle modes
         if ($char === '*') {
            $secret = ! $secret;
            continue;
         } else if ($char === '#') {
            $hidden = ! $hidden;
            continue;
         }

         // @ Parse Output
         if ($line === '') {
            $Output->write("\nClient: ");
         }

         $line .= $char;

         if ($hidden) continue;
         else if ($secret) $char = '*';

         if ($decoding) {
            $decoded = match ($char) {
               'A' => '⬆️',
               'B' => '⬇️',
               'C' => '➡️',
               'D' => '⬅️',
               default => ''
            };

            $decoding = false;

            $decoded ? $Output->write($decoded) : $Output->metaencode($char);

            continue;
         }

         $Output->metaencode($char);
      }
   },
   // Terminal Server API
   SAPI: function ($reading) // Server Input { $reading }
   use ($Output)
   {
      // * Config
      $timeout = 12000000; // in microseconds (1 second = 1000000 microsecond)

      // You can use while before $reading!

      // @ Reading input data from the Client Terminal
      foreach ($reading(timeout: $timeout) as $data) {
         // @ Write user data to Terminal Output (Server => Client)
         if ($data === null) {
            $Output->write(data: "Server: `No data received from Client. Timeout reached?`\n");
         } else if ($data === false) {
            $Output->write(data: "Server: `Unexpected data! Client is dead?`\n");
         } else {
            $Output->render(data: "\nServer: `You entered: @#cyan:" . json_encode($data) . " @;`\n\n");
         }
      }

      $Output->write(data: "Closing Server...`\n\n");
   }
);

echo "Bye...\n";
sleep(3);
```
