/** @file
  Main file for attrib shell level 2 function.

  (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2009 - 2014, Intel Corporation. All rights reserved. <BR>
  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "UefiShellLevel3CommandsLib.h"

STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
  {L"-sfo", TypeFlag},
  {NULL,    TypeMax}
  };

/**
  Function for 'cls' command.

  @param[in] ImageHandle  Handle to the Image (NULL if Internal).
  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).
**/
SHELL_STATUS
EFIAPI
ShellCommandRunCls (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS    Status;
  LIST_ENTRY    *Package;
  UINTN         Background;
  UINTN         Foreground;
  CHAR16        *ProblemParam;
  SHELL_STATUS  ShellStatus;
  CONST CHAR16  *BackColorStr;
  CONST CHAR16  *ForeColorStr;

  //
  // Initialize variables
  //
  ShellStatus   = SHELL_SUCCESS;
  ProblemParam  = NULL;
  Background    = 0;
  Foreground    = 0;

  //
  // initialize the shell lib (we must be in non-auto-init...)
  //
  Status = ShellInitialize();
  ASSERT_EFI_ERROR(Status);

  //
  // parse the command line
  //
  Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
  if (EFI_ERROR(Status)) {
    if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
      ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel3HiiHandle, L"cls", ProblemParam);  
      FreePool(ProblemParam);
      ShellStatus = SHELL_INVALID_PARAMETER;
    } else {
      ASSERT(FALSE);
    }
  } else {
    //
    // check for "-?"
    //
    if (ShellCommandLineGetFlag(Package, L"-?")) {
      ASSERT(FALSE);
    } else if (ShellCommandLineGetFlag (Package, L"-sfo")) {
      if (ShellCommandLineGetCount (Package) > 1) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"cls");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        Background = (gST->ConOut->Mode->Attribute >> 4) & 0x7;
        Foreground = gST->ConOut->Mode->Attribute & 0x0F;
        ShellPrintHiiEx (
          -1,
          -1,
          NULL,
          STRING_TOKEN (STR_CLS_OUTPUT_SFO),
          gShellLevel3HiiHandle,
          gST->ConOut->Mode->Attribute,
          Foreground,
          Background
          );
      }
    } else {
      //
      // If there are 0 value parameters, clear sceen
      //
      BackColorStr = ShellCommandLineGetRawValue (Package, 1);
      ForeColorStr = ShellCommandLineGetRawValue (Package, 2);

      if (BackColorStr == NULL && ForeColorStr == NULL) {
        //
        // clear screen
        //
        gST->ConOut->ClearScreen (gST->ConOut);
      } else if (ShellCommandLineGetCount (Package) > 3) {
        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellLevel3HiiHandle, L"cls");
        ShellStatus = SHELL_INVALID_PARAMETER;
      } else {
        if (BackColorStr != NULL) {
          if ((ShellStrToUintn (BackColorStr) > 7) || (StrLen (BackColorStr) > 1) || (!ShellIsDecimalDigitCharacter (*BackColorStr))) {
            ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"cls", BackColorStr);
            ShellStatus = SHELL_INVALID_PARAMETER;
          } else {
            switch (ShellStrToUintn (BackColorStr)) {
              case 0:
                Background = EFI_BACKGROUND_BLACK;
                break;
              case 1:
                Background = EFI_BACKGROUND_BLUE;
                break;
              case 2:
                Background = EFI_BACKGROUND_GREEN;
                break;
              case 3:
                Background = EFI_BACKGROUND_CYAN;
                break;
              case 4:
                Background = EFI_BACKGROUND_RED;
                break;
              case 5:
                Background = EFI_BACKGROUND_MAGENTA;
                break;
              case 6:
                Background = EFI_BACKGROUND_BROWN;
                break;
              case 7:
                Background = EFI_BACKGROUND_LIGHTGRAY;
                break;
            }

            if (ForeColorStr != NULL) {
              if ((ShellStrToUintn (ForeColorStr) > 15) || (StrLen (ForeColorStr) > 2) || (!ShellIsDecimalDigitCharacter (*ForeColorStr))) {
                ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellLevel3HiiHandle, L"cls", ForeColorStr);
                ShellStatus = SHELL_INVALID_PARAMETER;
              } else {
                switch (ShellStrToUintn (ForeColorStr)) {
                  case 0:
                    Foreground = EFI_BLACK;
                    break;
                  case 1:
                    Foreground = EFI_BLUE;
                    break;
                  case 2:
                    Foreground = EFI_GREEN;
                    break;
                  case 3:
                    Foreground = EFI_CYAN;
                    break;
                  case 4:
                    Foreground = EFI_RED;
                    break;
                  case 5:
                    Foreground = EFI_MAGENTA;
                    break;
                  case 6:
                    Foreground = EFI_BROWN;
                    break;
                  case 7:
                    Foreground = EFI_LIGHTGRAY;
                    break;
                  case 8:
                    Foreground = EFI_DARKGRAY;
                    break;
                  case 9:
                    Foreground = EFI_LIGHTBLUE;
                    break;
                  case 10:
                    Foreground = EFI_LIGHTGREEN;
                    break;
                  case 11:
                    Foreground = EFI_LIGHTCYAN;
                    break;
                  case 12:
                    Foreground = EFI_LIGHTRED;
                    break;
                  case 13:
                    Foreground = EFI_LIGHTMAGENTA;
                    break;
                  case 14:
                    Foreground = EFI_YELLOW;
                    break;
                  case 15:
                    Foreground = EFI_WHITE;
                    break;
                }
              }
            } else {
              //
              // Since foreground color is not modified, so retain
              // existing foreground color without any change to it.
              //
              Foreground = gST->ConOut->Mode->Attribute & 0x0F;
            }

            if (ShellStatus == SHELL_SUCCESS) {
              Status = gST->ConOut->SetAttribute (gST->ConOut, (Foreground | Background) & 0x7F);
              ASSERT_EFI_ERROR (Status);
              Status = gST->ConOut->ClearScreen (gST->ConOut);
              ASSERT_EFI_ERROR (Status);
            }
          }
        }
      }
    }
  }
  //
  // free the command line package
  //
  ShellCommandLineFreeVarList (Package);

  //
  // return the status
  //
  return (ShellStatus);
}

