/** @file
  Add external EblCmd Lib

  Copyright (c) 2007, Intel Corporation<BR>
  Portions copyright (c) 2008-2009, Apple Inc. All rights reserved.

  All rights reserved. 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 <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/EblAddExternalCommandLib.h>
#include <Protocol/EblAddCommand.h>

STATIC BOOLEAN   gInstalledCommand = FALSE;
STATIC EFI_EVENT mEblCommandRegistration = NULL;

STATIC const EBL_COMMAND_TABLE *mAddExternalCmdLibTemplate = NULL;
STATIC UINTN                   mAddExternalCmdLibTemplateSize = 0;
EBL_ADD_COMMAND_PROTOCOL      *gEblExternalCommand = NULL;


/**
  Return a keypress or optionally timeout if a timeout value was passed in.
  An optional callback funciton is called evey second when waiting for a
  timeout.

  @param  Key           EFI Key information returned
  @param  TimeoutInSec  Number of seconds to wait to timeout
  @param  CallBack      Callback called every second during the timeout wait 

  @return EFI_SUCCESS  Key was returned
  @return EFI_TIMEOUT  If the TimoutInSec expired

**/
EFI_STATUS
EFIAPI
EblGetCharKey (
  IN OUT EFI_INPUT_KEY            *Key,
  IN     UINTN                    TimeoutInSec,
  IN     EBL_GET_CHAR_CALL_BACK   CallBack   OPTIONAL
  )
{
  if (gEblExternalCommand != NULL) {
    return gEblExternalCommand->EblGetCharKey (Key, TimeoutInSec, CallBack);
  }
  return EFI_TIMEOUT;
}


/**
  This routine is used prevent command output data from scrolling off the end
  of the screen. The global gPageBreak is used to turn on or off this feature.
  If the CurrentRow is near the end of the screen pause and print out a prompt
  If the use hits Q to quit return TRUE else for any other key return FALSE.
  PrefixNewline is used to figure out if a newline is needed before the prompt
  string. This depends on the last print done before calling this function.
  CurrentRow is updated by one on a call or set back to zero if a prompt is 
  needed.

  @param  CurrentRow  Used to figure out if its the end of the page and updated
  @param  PrefixNewline  Did previous print issue a newline

  @return TRUE if Q was hit to quit, FALSE in all other cases.

**/
BOOLEAN
EFIAPI
EblAnyKeyToContinueQtoQuit (
  IN  UINTN   *CurrentRow,
  IN  BOOLEAN PrefixNewline
  )
{
  if (gEblExternalCommand != NULL) {
    return gEblExternalCommand->EblAnyKeyToContinueQtoQuit (CurrentRow, PrefixNewline);
  }
  return FALSE;
}



/**
  Update mFvbEntry. Add new entry, or update existing entry if Fvb protocol is
  reinstalled.

  @param Event      The Event that is being processed
  @param Context    Event Context

**/
VOID
EFIAPI
EblAddCommandNotificationEvent (
  IN  EFI_EVENT       Event,
  IN  VOID            *Context
  )
{
  EFI_STATUS                  Status;

  if (!gInstalledCommand) {
    Status = gBS->LocateProtocol (&gEfiEblAddCommandProtocolGuid, NULL, (VOID **)&gEblExternalCommand);
    if (!EFI_ERROR (Status)) {
      gEblExternalCommand->AddCommands (mAddExternalCmdLibTemplate, mAddExternalCmdLibTemplateSize);
      gInstalledCommand = TRUE;
    }
  }
}



/**
  The user Entry Point for the driver. The user code starts with this function
  as the real entry point for the image goes into a library that calls this 
  function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.  
  @param[in] SystemTable    A pointer to the EFI System Table.
  
  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
EblAddExternalCommands (
  IN const EBL_COMMAND_TABLE   *EntryArray,
  IN UINTN                     ArrayCount
  )
{
  if (mAddExternalCmdLibTemplate != NULL) {
    return EFI_ALREADY_STARTED;
  }

  mAddExternalCmdLibTemplate     = EntryArray;
  mAddExternalCmdLibTemplateSize = ArrayCount;
  
  EfiCreateProtocolNotifyEvent (
    &gEfiEblAddCommandProtocolGuid,
    TPL_CALLBACK,
    EblAddCommandNotificationEvent,
    NULL,
    &mEblCommandRegistration
    );
  
  return EFI_SUCCESS;
}

