/** @file
    Defines the Main Editor data type - 
     - Global variables 
     - Instances of the other objects of the editor
     - Main Interfaces
  
  Copyright (c) 2005 - 2012, 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 "HexEditor.h"
#include "EditStatusBar.h"
#include "EditInputBar.h"

HEFI_EDITOR_COLOR_ATTRIBUTES    HOriginalColors;
INTN                            HOriginalMode;

//
// the first time editor launch
//
BOOLEAN                         HEditorFirst;

//
// it's time editor should exit
//
BOOLEAN                         HEditorExit;

BOOLEAN                         HEditorMouseAction;

extern HEFI_EDITOR_BUFFER_IMAGE HBufferImage;
extern HEFI_EDITOR_BUFFER_IMAGE HBufferImageBackupVar;

extern BOOLEAN                  HBufferImageMouseNeedRefresh;
extern BOOLEAN                  HBufferImageNeedRefresh;
extern BOOLEAN                  HBufferImageOnlyLineNeedRefresh;

HEFI_EDITOR_GLOBAL_EDITOR       HMainEditor;
HEFI_EDITOR_GLOBAL_EDITOR       HMainEditorBackupVar;

//
// basic initialization for MainEditor
//
HEFI_EDITOR_GLOBAL_EDITOR       HMainEditorConst = {
  &HBufferImage,
  {
    {0, 0}
  },
  {
    0,
    0
  },
  FALSE,
  NULL,
  0,
  0,
  1,
  1
};

/**
  Help info that will be displayed.
**/
EFI_STRING_ID  HexMainMenuHelpInfo[] = {
  STRING_TOKEN(STR_HEXEDIT_HELP_TITLE),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_LIST_TITLE),
  STRING_TOKEN(STR_HEXEDIT_HELP_DIV),
  STRING_TOKEN(STR_HEXEDIT_HELP_GO_TO_OFFSET),
  STRING_TOKEN(STR_HEXEDIT_HELP_SAVE_BUFFER),
  STRING_TOKEN(STR_HEXEDIT_HELP_EXIT),
  STRING_TOKEN(STR_HEXEDIT_HELP_SELECT_START),
  STRING_TOKEN(STR_HEXEDIT_HELP_SELECT_END),
  STRING_TOKEN(STR_HEXEDIT_HELP_CUT),
  STRING_TOKEN(STR_HEXEDIT_HELP_PASTE),
  STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_FILE),
  STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_DISK),
  STRING_TOKEN(STR_HEXEDIT_HELP_OPEN_MEMORY),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_EXIT_HELP),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_BLANK),
  STRING_TOKEN(STR_HEXEDIT_HELP_DIV),
  0
};


/**
  show help menu.

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
HMainCommandDisplayHelp (
  VOID
  )
{
  INT32    CurrentLine;
  CHAR16 * InfoString;
  EFI_INPUT_KEY  Key;

  CurrentLine = 0;
  // print helpInfo      
  for (CurrentLine = 0; 0 != HexMainMenuHelpInfo[CurrentLine]; CurrentLine++) {
    InfoString = HiiGetString(gShellDebug1HiiHandle, HexMainMenuHelpInfo[CurrentLine]
, NULL);
    ShellPrintEx (0,CurrentLine+1,L"%E%s%N",InfoString);        
  }
  
  // scan for ctrl+w
  do {
    gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
  } while(SCAN_CONTROL_W != Key.UnicodeChar); 

  // update screen with buffer's info
  HBufferImageNeedRefresh = TRUE;
  HBufferImageOnlyLineNeedRefresh = FALSE;
  HBufferImageRefresh ();

  return EFI_SUCCESS;
}

/**
  Move cursor to specified lines.

  @retval EFI_SUCCESS   The operation was successful.
**/
EFI_STATUS
HMainCommandGoToOffset (
  VOID
  )
{
  UINTN       Size;
  UINT64      Offset;
  EFI_STATUS  Status;
  UINTN       FRow;
  UINTN       FCol;

  //
  // variable initialization
  //
  Size    = 0;
  Offset  = 0;
  FRow    = 0;
  FCol    = 0;

  //
  // get offset
  //
  Status = InputBarSetPrompt (L"Go To Offset: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (8);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {

      return EFI_SUCCESS;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
      if (EFI_ERROR (Status)) {
        StatusBarSetStatusString (L"Invalid Offset");
        return EFI_SUCCESS;
      }

      break;
    }
  }

  Size = HBufferImageGetTotalSize ();
  if (Offset >= Size) {
    StatusBarSetStatusString (L"Invalid Offset");
    return EFI_SUCCESS;
  }

  FRow  = (UINTN)DivU64x32(Offset , 0x10) + 1;
  FCol  = (UINTN)ModU64x32(Offset , 0x10) + 1;

  HBufferImageMovePosition (FRow, FCol, TRUE);

  HBufferImageNeedRefresh         = TRUE;
  HBufferImageOnlyLineNeedRefresh = FALSE;
  HBufferImageMouseNeedRefresh    = TRUE;

  return EFI_SUCCESS;
}

/**
  Save current opened buffer.
  If is file buffer, you can save to current file name or 
  save to another file name.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandSaveBuffer (
  VOID
  )
{
  EFI_STATUS          Status;
  BOOLEAN             Done;
  CHAR16              *FileName;
  BOOLEAN             OldFile;
  CHAR16              *Str;
  EFI_FILE_INFO       *Info;
  SHELL_FILE_HANDLE   ShellFileHandle;

  if (HMainEditor.BufferImage->BufferType != FileTypeFileBuffer) {
    if (!HMainEditor.BufferImage->Modified) {
      return EFI_SUCCESS;
    }

    Status = InputBarSetPrompt (L"Dangerous to save disk/mem buffer. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // the answer is just one character
    //
    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // loop for user's answer
    // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
    //
    while (1) {
      Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString()[0]) {
      case L'y':
      case L'Y':
        //
        // want to save this buffer first
        //
        Status = HBufferImageSave (
                  NULL,
                  HMainEditor.BufferImage->DiskImage->Name,
                  HMainEditor.BufferImage->DiskImage->Offset,
                  HMainEditor.BufferImage->DiskImage->Size,
                  HMainEditor.BufferImage->MemImage->Offset,
                  HMainEditor.BufferImage->MemImage->Size,
                  HMainEditor.BufferImage->BufferType
                  );

        if (EFI_ERROR (Status)) {
          StatusBarSetStatusString (L"BufferSave: Problems Writing");
          return Status;
        }

        return EFI_SUCCESS;

      case L'n':
      case L'N':
        //
        // the file won't be saved
        //
        return EFI_SUCCESS;

      case L'c':
      case L'C':
        return EFI_SUCCESS;
      }
      //
      // end of switch
      //
    }
    //
    // ENDOF WHILE
    //
  }
  //
  // ENDOF != FILEBUFFER
  //
  // This command will save currently opened file to disk.
  // You can choose save to another file name or just save to
  // current file name.
  // Below is the scenario of Save File command: (
  //    Suppose the old file name is A )
  // 1. An Input Bar will be prompted:    "File To Save: [ old file name]"
  //    IF user press ESC, Save File command ends .
  //    IF user press Enter, input file name will be A.
  //    IF user inputs a new file name B,  input file name will be B.
  //
  // 2. IF input file name is A, go to do Step 3.
  //    IF input file name is B, go to do Step 4.
  //
  // 3. IF A is read only, Status Bar will show "Access Denied"
  //       and Save File commands ends.
  //    IF A is not read only, save file buffer to disk
  //       and remove Modified flag in Title Bar , then Save File command ends.
  //
  // 4. IF B does not exist, create this file and save file buffer to it.
  //       Go to do Step 7.
  //    IF B exits, do Step 5.
  //
  // 5. An Input Bar will be prompted:
  //       "File Exists. Overwrite ( Yes/No/Cancel ) ?"
  //      IF user press 'y' or 'Y', do Step 6.
  //      IF user press 'n' or 'N', Save File commands ends.
  //      IF user press 'c' or 'C' or ESC, Save File commands ends.
  //
  // 6. IF B is a read-only file, Status Bar will show "Access Denied"
  //       and Save File commands ends.
  //    IF B can be read and write, save file buffer to B.
  //
  // 7. Update File Name field in Title Bar to B
  //       and remove the Modified flag in Title Bar.
  //
  Str = CatSPrint(NULL, 
          L"File to Save: [%s]",
          HMainEditor.BufferImage->FileImage->FileName
          );
  if (Str == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (StrLen (Str) >= 50) {
    //
    // replace the long file name with "..."
    //
    Str[46] = L'.';
    Str[47] = L'.';
    Str[48] = L'.';
    Str[49] = L']';
    Str[50] = L'\0';
  }

  Status = InputBarSetPrompt (Str);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (100);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // get new file name
  //
  Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

  //
  // if user pressed ESC
  //
  if (Status == EFI_NOT_READY) {
    SHELL_FREE_NON_NULL (Str);
    return EFI_SUCCESS;
  }

  SHELL_FREE_NON_NULL (Str);

  //
  // if just enter pressed, so think save to current file name
  //
  if (StrLen (InputBarGetString()) == 0) {
    FileName = CatSPrint(NULL, 
                L"%s",
                HMainEditor.BufferImage->FileImage->FileName
                );
  } else {
    FileName = CatSPrint(NULL, L"%s", InputBarGetString());
  }

  if (FileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (!IsValidFileName (FileName)) {
    StatusBarSetStatusString (L"Invalid File Name");
    SHELL_FREE_NON_NULL (FileName);
    return EFI_SUCCESS;
  }

  OldFile = FALSE;

  //
  // save to the old file
  //
  if (StringNoCaseCompare (
        &FileName,
        &HMainEditor.BufferImage->FileImage->FileName
        ) == 0) {
    OldFile = TRUE;
  }

  if (OldFile) {
    //
    // if the file is read only, so can not write back to it.
    //
    if (HMainEditor.BufferImage->FileImage->ReadOnly) {
      StatusBarSetStatusString (L"Access Denied");
      SHELL_FREE_NON_NULL (FileName);
      return EFI_SUCCESS;
    }
  } else {
    Status = ShellOpenFileByName (FileName, &ShellFileHandle, EFI_FILE_MODE_READ, 0);

    if (!EFI_ERROR (Status)) {

      Info = ShellGetFileInfo(ShellFileHandle);

      ShellCloseFile(&ShellFileHandle);
      //
      // check if read only
      //
      if (Info->Attribute & EFI_FILE_READ_ONLY) {
        StatusBarSetStatusString (L"Access Denied");
        SHELL_FREE_NON_NULL (FileName);
        return EFI_SUCCESS;
      } 

      SHELL_FREE_NON_NULL(Info);
      //
      // ask user whether to overwrite this file
      //
      Status = InputBarSetPrompt (L"File exists. Overwrite (Yes/No/Cancel) ? ");
      if (EFI_ERROR (Status)) {
        SHELL_FREE_NON_NULL (FileName);
        return Status;
      }

      Status = InputBarSetStringSize (1);
      if (EFI_ERROR (Status)) {
        SHELL_FREE_NON_NULL (FileName);
        return Status;
      }

      Done = FALSE;
      while (!Done) {
        Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

        if (Status == EFI_NOT_READY) {
          SHELL_FREE_NON_NULL (FileName);
          return EFI_SUCCESS;
        }

        switch (InputBarGetString()[0]) {
        case L'y':
        case L'Y':
          Done = TRUE;
          break;
        case L'n':
        case L'N':
          SHELL_FREE_NON_NULL (FileName);
          return EFI_SUCCESS;
        case L'c':
        case L'C':
          SHELL_FREE_NON_NULL (FileName);
          return EFI_SUCCESS;
        } // switch
      } // while
    } // if opened existing file
  } // if OldFile
  
  //
  // save file back to disk
  //
  Status = HBufferImageSave (
            FileName,
            HMainEditor.BufferImage->DiskImage->Name,
            HMainEditor.BufferImage->DiskImage->Offset,
            HMainEditor.BufferImage->DiskImage->Size,
            HMainEditor.BufferImage->MemImage->Offset,
            HMainEditor.BufferImage->MemImage->Size,
            FileTypeFileBuffer
            );
  SHELL_FREE_NON_NULL (FileName);

  if (EFI_ERROR (Status)) {
    return EFI_LOAD_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Load a disk buffer editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandSelectStart (
  VOID
  )
{
  UINTN Start;

  Start = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;

  //
  // last line
  //
  if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
    if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
      StatusBarSetStatusString (L"Invalid Block Start");
      return EFI_LOAD_ERROR;
    }
  }

  if (HMainEditor.SelectEnd != 0 && Start > HMainEditor.SelectEnd) {
    StatusBarSetStatusString (L"Invalid Block Start");
    return EFI_LOAD_ERROR;
  }

  HMainEditor.SelectStart = Start;

  HBufferImageNeedRefresh = TRUE;

  return EFI_SUCCESS;
}

/**
  Load a disk buffer editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandSelectEnd (
  VOID
  )
{
  UINTN End;

  End = (HMainEditor.BufferImage->BufferPosition.Row - 1) * 0x10 + HMainEditor.BufferImage->BufferPosition.Column;

  //
  // last line
  //
  if (HMainEditor.BufferImage->CurrentLine->Link.ForwardLink == HMainEditor.BufferImage->ListHead) {
    if (HMainEditor.BufferImage->BufferPosition.Column > HMainEditor.BufferImage->CurrentLine->Size) {
      StatusBarSetStatusString (L"Invalid Block End");
      return EFI_LOAD_ERROR;
    }
  }

  if (HMainEditor.SelectStart != 0 && End < HMainEditor.SelectStart) {
    StatusBarSetStatusString (L"Invalid Block End");
    return EFI_SUCCESS;
  }

  HMainEditor.SelectEnd   = End;

  HBufferImageNeedRefresh = TRUE;

  return EFI_SUCCESS;
}

/**
  Cut current line to clipboard.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandCut (
  VOID
  )
{
  UINTN             Index;
  LIST_ENTRY    *Link;
  UINT8             *Buffer;
  UINTN             Count;

  //
  // not select, so not allowed to cut
  //
  if (HMainEditor.SelectStart == 0) {
    StatusBarSetStatusString (L"No Block is Selected");
    return EFI_SUCCESS;
  }
  //
  // not select, so not allowed to cut
  //
  if (HMainEditor.SelectEnd == 0) {
    StatusBarSetStatusString (L"No Block is Selected");
    return EFI_SUCCESS;
  }

  Link = HMainEditor.BufferImage->ListHead->ForwardLink;
  for (Index = 0; Index < (HMainEditor.SelectEnd - 1) / 0x10; Index++) {
    Link = Link->ForwardLink;
  }

  Count   = HMainEditor.SelectEnd - HMainEditor.SelectStart + 1;
  Buffer  = AllocateZeroPool (Count);
  if (Buffer == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // cut the selected area
  //
  HBufferImageDeleteCharacterFromBuffer (
    HMainEditor.SelectStart - 1,
    Count,
    Buffer
    );

  //
  // put to clipboard
  //
  HClipBoardSet (Buffer, Count);

  HBufferImageNeedRefresh         = TRUE;
  HBufferImageOnlyLineNeedRefresh = FALSE;

  if (!HMainEditor.BufferImage->Modified) {
    HMainEditor.BufferImage->Modified = TRUE;
  }

  //
  // now no select area
  //
  HMainEditor.SelectStart = 0;
  HMainEditor.SelectEnd   = 0;

  return EFI_SUCCESS;
}

/**
  Paste line to file buffer.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandPaste (
  VOID
  )
{

  BOOLEAN           OnlyLineRefresh;
  HEFI_EDITOR_LINE  *Line;
  UINT8             *Buffer;
  UINTN             Count;
  UINTN             FPos;

  Count = HClipBoardGet (&Buffer);
  if (Count == 0 || Buffer == NULL) {
    StatusBarSetStatusString (L"Nothing to Paste");
    return EFI_SUCCESS;
  }

  Line            = HMainEditor.BufferImage->CurrentLine;

  OnlyLineRefresh = FALSE;
  if (Line->Link.ForwardLink == HMainEditor.BufferImage->ListHead && Line->Size + Count < 0x10) {
    //
    // is at last line, and after paste will not exceed
    // so only this line need to be refreshed
    //
    // if after add, the line is 0x10, then will append a new line
    // so the whole page will need be refreshed
    //
    OnlyLineRefresh = TRUE;

  }

  FPos = 0x10 * (HMainEditor.BufferImage->BufferPosition.Row - 1) + HMainEditor.BufferImage->BufferPosition.Column - 1;

  HBufferImageAddCharacterToBuffer (FPos, Count, Buffer);

  if (OnlyLineRefresh) {
    HBufferImageNeedRefresh         = FALSE;
    HBufferImageOnlyLineNeedRefresh = TRUE;
  } else {
    HBufferImageNeedRefresh         = TRUE;
    HBufferImageOnlyLineNeedRefresh = FALSE;
  }

  if (!HMainEditor.BufferImage->Modified) {
    HMainEditor.BufferImage->Modified = TRUE;
  }

  return EFI_SUCCESS;

}

/**
  Exit editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandExit (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // Below is the scenario of Exit command:
  // 1. IF currently opened file is not modified, exit the editor and
  //       Exit command ends.
  //    IF currently opened file is modified, do Step 2
  //
  // 2. An Input Bar will be prompted:
  //       "File modified. Save ( Yes/No/Cancel )?"
  //      IF user press 'y' or 'Y', currently opened file will be saved and
  //         Editor exits
  //      IF user press 'n' or 'N', currently opened file will not be saved
  //         and Editor exits.
  //      IF user press 'c' or 'C' or ESC, Exit command ends.
  //
  //
  // if file has been modified, so will prompt user
  //       whether to save the changes
  //
  if (HMainEditor.BufferImage->Modified) {

    Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }

    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    while (1) {
      Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString()[0]) {
      case L'y':
      case L'Y':
        //
        // write file back to disk
        //
        Status = HBufferImageSave (
                  HMainEditor.BufferImage->FileImage->FileName,
                  HMainEditor.BufferImage->DiskImage->Name,
                  HMainEditor.BufferImage->DiskImage->Offset,
                  HMainEditor.BufferImage->DiskImage->Size,
                  HMainEditor.BufferImage->MemImage->Offset,
                  HMainEditor.BufferImage->MemImage->Size,
                  HMainEditor.BufferImage->BufferType
                  );
        if (!EFI_ERROR (Status)) {
          HEditorExit = TRUE;
        }

        return Status;

      case L'n':
      case L'N':
        HEditorExit = TRUE;
        return EFI_SUCCESS;

      case L'c':
      case L'C':
        return EFI_SUCCESS;

      }
    }
  }

  HEditorExit = TRUE;
  return EFI_SUCCESS;

}

/**
  Load a file from disk to editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainCommandOpenFile (
  VOID
  )
{
  BOOLEAN                         Done;
  EFI_STATUS                      Status;
  EDIT_FILE_TYPE                  BufferType;

  BufferType = HMainEditor.BufferImage->BufferType;

  //
  //  This command will open a file from current working directory.
  //  Read-only file can also be opened. But it can not be modified.
  // Below is the scenario of Open File command:
  // 1. IF currently opened file has not been modified, directly go to step .
  //  IF currently opened file has been modified, an Input Bar will be
  //     prompted as :
  //      "File Modified. Save ( Yes/No/Cancel) ?"
  //          IF user press 'y' or 'Y', currently opened file will be saved.
  //          IF user press 'n' or 'N', currently opened file will
  //             not be saved.
  //          IF user press 'c' or 'C' or ESC, Open File command ends and
  //             currently opened file is still opened.
  //
  // 2. An Input Bar will be prompted as :  "File Name to Open: "
  //      IF user press ESC, Open File command ends and
  //         currently opened file is still opened.
  //      Any other inputs with a Return will cause
  //          currently opened file close.
  //
  // 3. IF user input file name is an existing file ,
  //       this file will be read and opened.
  //    IF user input file name is a new file, this file will be created
  //       and opened. This file's type ( UNICODE or ASCII ) is the same with
  //       the old file.
  //
  //
  // if current file is modified, so you need to choose whether to
  //    save it first.
  //
  if (HMainEditor.BufferImage->Modified) {

    Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // the answer is just one character
    //
    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // loop for user's answer
    // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
    //
    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString()[0]) {
      case L'y':
      case L'Y':
        //
        // want to save this buffer first
        //
        Status = HBufferImageSave (
                  HMainEditor.BufferImage->FileImage->FileName,
                  HMainEditor.BufferImage->DiskImage->Name,
                  HMainEditor.BufferImage->DiskImage->Offset,
                  HMainEditor.BufferImage->DiskImage->Size,
                  HMainEditor.BufferImage->MemImage->Offset,
                  HMainEditor.BufferImage->MemImage->Size,
                  HMainEditor.BufferImage->BufferType
                  );
        if (EFI_ERROR (Status)) {
          return Status;
        }

        MainTitleBarRefresh (
          HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
          HMainEditor.BufferImage->BufferType,
          HMainEditor.BufferImage->FileImage->ReadOnly,
          FALSE,
          HMainEditor.ScreenSize.Column,
          HMainEditor.ScreenSize.Row,
          HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
          HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size  :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size  :0
          );
        Done = TRUE;
        break;

      case L'n':
      case L'N':
        //
        // the file won't be saved
        //
        Done = TRUE;
        break;

      case L'c':
      case L'C':
        return EFI_SUCCESS;
      }
    }
  }
  //
  // TO get the open file name
  //
  Status = InputBarSetPrompt (L"File Name to Open: ");
  if (EFI_ERROR (Status)) {
    HBufferImageRead (
      HMainEditor.BufferImage->FileImage->FileName,
      HMainEditor.BufferImage->DiskImage->Name,
      HMainEditor.BufferImage->DiskImage->Offset,
      HMainEditor.BufferImage->DiskImage->Size,
      HMainEditor.BufferImage->MemImage->Offset,
      HMainEditor.BufferImage->MemImage->Size,
      BufferType,
      TRUE
      );
    return Status;
  }

  Status = InputBarSetStringSize (100);
  if (EFI_ERROR (Status)) {
    Status = HBufferImageRead (
              HMainEditor.BufferImage->FileImage->FileName,
              HMainEditor.BufferImage->DiskImage->Name,
              HMainEditor.BufferImage->DiskImage->Offset,
              HMainEditor.BufferImage->DiskImage->Size,
              HMainEditor.BufferImage->MemImage->Offset,
              HMainEditor.BufferImage->MemImage->Size,
              BufferType,
              TRUE
              );
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {
      Status = HBufferImageRead (
                HMainEditor.BufferImage->FileImage->FileName,
                HMainEditor.BufferImage->DiskImage->Name,
                HMainEditor.BufferImage->DiskImage->Offset,
                HMainEditor.BufferImage->DiskImage->Size,
                HMainEditor.BufferImage->MemImage->Offset,
                HMainEditor.BufferImage->MemImage->Size,
                BufferType,
                TRUE
                );

      return Status;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      //
      // CHECK if filename's valid
      //
      if (!IsValidFileName (InputBarGetString())) {
        HBufferImageRead (
          HMainEditor.BufferImage->FileImage->FileName,
          HMainEditor.BufferImage->DiskImage->Name,
          HMainEditor.BufferImage->DiskImage->Offset,
          HMainEditor.BufferImage->DiskImage->Size,
          HMainEditor.BufferImage->MemImage->Offset,
          HMainEditor.BufferImage->MemImage->Size,
          BufferType,
          TRUE
          );

        StatusBarSetStatusString (L"Invalid File Name");
        return EFI_SUCCESS;
      }

      break;
    }
  }
  //
  // read from disk
  //
  Status = HBufferImageRead (
            InputBarGetString(),
            HMainEditor.BufferImage->DiskImage->Name,
            HMainEditor.BufferImage->DiskImage->Offset,
            HMainEditor.BufferImage->DiskImage->Size,
            HMainEditor.BufferImage->MemImage->Offset,
            HMainEditor.BufferImage->MemImage->Size,
            FileTypeFileBuffer,
            FALSE
            );

  if (EFI_ERROR (Status)) {
    HBufferImageRead (
      HMainEditor.BufferImage->FileImage->FileName,
      HMainEditor.BufferImage->DiskImage->Name,
      HMainEditor.BufferImage->DiskImage->Offset,
      HMainEditor.BufferImage->DiskImage->Size,
      HMainEditor.BufferImage->MemImage->Offset,
      HMainEditor.BufferImage->MemImage->Size,
      BufferType,
      TRUE
      );

    return EFI_LOAD_ERROR;
  }

  return EFI_SUCCESS;
}

/**
  Load a disk buffer editor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
  @retval EFI_NOT_FOUND           The disk was not found.
**/
EFI_STATUS
HMainCommandOpenDisk (
  VOID
  )
{
  UINT64                          Size;
  UINT64                          Offset;
  CHAR16                          *DeviceName;
  EFI_STATUS                      Status;
  BOOLEAN                         Done;

  EDIT_FILE_TYPE                  BufferType;

  //
  // variable initialization
  //
  Size        = 0;
  Offset      = 0;
  BufferType  = HMainEditor.BufferImage->BufferType;

  //
  // if current file is modified, so you need to choose
  // whether to save it first.
  //
  if (HMainEditor.BufferImage->Modified) {

    Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // the answer is just one character
    //
    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // loop for user's answer
    // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
    //
    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString()[0]) {
      case L'y':
      case L'Y':
        //
        // want to save this buffer first
        //
        Status = HBufferImageSave (
                  HMainEditor.BufferImage->FileImage->FileName,
                  HMainEditor.BufferImage->DiskImage->Name,
                  HMainEditor.BufferImage->DiskImage->Offset,
                  HMainEditor.BufferImage->DiskImage->Size,
                  HMainEditor.BufferImage->MemImage->Offset,
                  HMainEditor.BufferImage->MemImage->Size,
                  BufferType
                  );
        if (EFI_ERROR (Status)) {
          return Status;
        }

        MainTitleBarRefresh (
          HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
          HMainEditor.BufferImage->BufferType,
          HMainEditor.BufferImage->FileImage->ReadOnly,
          FALSE,
          HMainEditor.ScreenSize.Column,
          HMainEditor.ScreenSize.Row,
          HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
          HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size  :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size  :0
          );
        Done = TRUE;
        break;

      case L'n':
      case L'N':
        //
        // the file won't be saved
        //
        Done = TRUE;
        break;

      case L'c':
      case L'C':
        return EFI_SUCCESS;
      }
    }
  }
  //
  // get disk block device name
  //
  Status = InputBarSetPrompt (L"Block Device to Open: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (100);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {

      return EFI_SUCCESS;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      break;
    }
  }

  DeviceName = CatSPrint(NULL, L"%s", InputBarGetString());
  if (DeviceName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  //
  // get starting offset
  //
  Status = InputBarSetPrompt (L"First Block No.: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (16);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {

      return EFI_SUCCESS;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
      if (EFI_ERROR (Status)) {
        continue;
      }

      break;
    }
  }
  //
  // get Number of Blocks:
  //
  Status = InputBarSetPrompt (L"Number of Blocks: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (8);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {

      return EFI_SUCCESS;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
      if (EFI_ERROR (Status)) {
        continue;
      }

      if (Size == 0) {
        continue;
      }

      break;
    }
  }

  Status = HBufferImageRead (
            NULL,
            DeviceName,
            (UINTN)Offset,
            (UINTN)Size,
            0,
            0,
            FileTypeDiskBuffer,
            FALSE
            );

  if (EFI_ERROR (Status)) {

    HBufferImageRead (
      HMainEditor.BufferImage->FileImage->FileName,
      HMainEditor.BufferImage->DiskImage->Name,
      HMainEditor.BufferImage->DiskImage->Offset,
      HMainEditor.BufferImage->DiskImage->Size,
      HMainEditor.BufferImage->MemImage->Offset,
      HMainEditor.BufferImage->MemImage->Size,
      BufferType,
      TRUE
      );
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

/**
  Load memory content to editor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
  @retval EFI_NOT_FOUND           The disk was not found.
**/
EFI_STATUS
HMainCommandOpenMemory (
  VOID
  )
{
  UINT64                          Size;
  UINT64                          Offset;
  EFI_STATUS                      Status;
  BOOLEAN                         Done;
  EDIT_FILE_TYPE                  BufferType;

  //
  // variable initialization
  //
  Size        = 0;
  Offset      = 0;
  BufferType  = HMainEditor.BufferImage->BufferType;

  //
  // if current buffer is modified, so you need to choose
  // whether to save it first.
  //
  if (HMainEditor.BufferImage->Modified) {

    Status = InputBarSetPrompt (L"Buffer modified. Save (Yes/No/Cancel) ? ");
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // the answer is just one character
    //
    Status = InputBarSetStringSize (1);
    if (EFI_ERROR (Status)) {
      return Status;
    }
    //
    // loop for user's answer
    // valid answer is just 'y' 'Y', 'n' 'N', 'c' 'C'
    //
    Done = FALSE;
    while (!Done) {
      Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

      //
      // ESC pressed
      //
      if (Status == EFI_NOT_READY) {
        return EFI_SUCCESS;
      }

      switch (InputBarGetString()[0]) {
      case L'y':
      case L'Y':
        //
        // want to save this buffer first
        //
        Status = HBufferImageSave (
                  HMainEditor.BufferImage->FileImage->FileName,
                  HMainEditor.BufferImage->DiskImage->Name,
                  HMainEditor.BufferImage->DiskImage->Offset,
                  HMainEditor.BufferImage->DiskImage->Size,
                  HMainEditor.BufferImage->MemImage->Offset,
                  HMainEditor.BufferImage->MemImage->Size,
                  BufferType
                  );
        if (EFI_ERROR (Status)) {
          return Status;
        }

        MainTitleBarRefresh (
          HMainEditor.BufferImage->BufferType == FileTypeFileBuffer?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Name:NULL,
          HMainEditor.BufferImage->BufferType,
          HMainEditor.BufferImage->FileImage->ReadOnly,
          FALSE,
          HMainEditor.ScreenSize.Column,
          HMainEditor.ScreenSize.Row,
          HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Offset:0,
          HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer?HMainEditor.BufferImage->DiskImage->Size  :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer?HMainEditor.BufferImage->MemImage->Size  :0
          );
        Done = TRUE;
        break;

      case L'n':
      case L'N':
        //
        // the file won't be saved
        //
        Done = TRUE;
        break;

      case L'c':
      case L'C':
        return EFI_SUCCESS;
      }
    }
  }
  //
  // get starting offset
  //
  Status = InputBarSetPrompt (L"Starting Offset: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (8);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {

      return EFI_SUCCESS;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      Status = ShellConvertStringToUint64 (InputBarGetString(), &Offset, TRUE, FALSE);
      if (EFI_ERROR (Status)) {
        continue;
      }

      break;
    }
  }
  //
  // get Number of Blocks:
  //
  Status = InputBarSetPrompt (L"Buffer Size: ");
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = InputBarSetStringSize (8);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  while (1) {
    Status = InputBarRefresh (HMainEditor.ScreenSize.Row, HMainEditor.ScreenSize.Column);

    //
    // ESC pressed
    //
    if (Status == EFI_NOT_READY) {

      return EFI_SUCCESS;
    }
    //
    // THE input string length should > 0
    //
    if (StrLen (InputBarGetString()) > 0) {
      Status = ShellConvertStringToUint64 (InputBarGetString(), &Size, TRUE, FALSE);
      if (EFI_ERROR (Status)) {
        continue;
      }

      if (Size == 0) {
        continue;
      }

      break;
    }
  }

  if ((Offset + Size - 1)> 0xffffffff) {
    StatusBarSetStatusString (L"Invalid parameter");
    return EFI_LOAD_ERROR;
  }

  Status = HBufferImageRead (
            NULL,
            NULL,
            0,
            0,
            (UINTN)Offset,
            (UINTN)Size,
            FileTypeMemBuffer,
            FALSE
            );

  if (EFI_ERROR (Status)) {
    StatusBarSetStatusString (L"Read Device Error!");
    HBufferImageRead (
      HMainEditor.BufferImage->FileImage->FileName,
      HMainEditor.BufferImage->DiskImage->Name,
      HMainEditor.BufferImage->DiskImage->Offset,
      HMainEditor.BufferImage->DiskImage->Size,
      HMainEditor.BufferImage->MemImage->Offset,
      HMainEditor.BufferImage->MemImage->Size,
      BufferType,
      TRUE
      );
    return EFI_NOT_FOUND;
  }
  return EFI_SUCCESS;

}

MENU_ITEM_FUNCTION HexMainControlBasedMenuFunctions[] = {
  NULL,
  NULL,                      /* Ctrl - A */
  NULL,                      /* Ctrl - B */
  NULL,                      /* Ctrl - C */
  HMainCommandSelectEnd,     /* Ctrl - D */
  HMainCommandDisplayHelp,   /* Ctrl - E */
  NULL,                      /* Ctrl - F */
  HMainCommandGoToOffset,    /* Ctrl - G */
  NULL,                      /* Ctrl - H */
  HMainCommandOpenDisk,      /* Ctrl - I */
  NULL,                      /* Ctrl - J */
  NULL,                      /* Ctrl - K */
  NULL,                      /* Ctrl - L */
  HMainCommandOpenMemory,    /* Ctrl - M */
  NULL,                      /* Ctrl - N */
  HMainCommandOpenFile,      /* Ctrl - O */
  NULL,                      /* Ctrl - P */
  HMainCommandExit,          /* Ctrl - Q */
  NULL,                      /* Ctrl - R */
  HMainCommandSaveBuffer,    /* Ctrl - S */
  HMainCommandSelectStart,   /* Ctrl - T */
  NULL,                      /* Ctrl - U */
  HMainCommandPaste,         /* Ctrl - V */
  NULL,                      /* Ctrl - W */
  HMainCommandCut,           /* Ctrl - X */
  NULL,                      /* Ctrl - Y */
  NULL,                      /* Ctrl - Z */
};

CONST EDITOR_MENU_ITEM HexEditorMenuItems[] = {
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_GO_TO_OFFSET),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F1),
    HMainCommandGoToOffset
  },
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SAVE_BUFFER),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F2),
    HMainCommandSaveBuffer
  },
  {
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_EXIT),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F3),
    HMainCommandExit
  },

  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_START),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F4),
    HMainCommandSelectStart
  },
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_SELECT_END),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F5),
    HMainCommandSelectEnd
  },
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_CUT),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F6),
    HMainCommandCut
  },
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_PASTE),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F7),
    HMainCommandPaste
  },

  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_FILE),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F8),
    HMainCommandOpenFile
  },
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_DISK),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F9),
    HMainCommandOpenDisk
  },
  {
    STRING_TOKEN(STR_HEXEDIT_LIBMENUBAR_OPEN_MEMORY),
    STRING_TOKEN(STR_EDIT_LIBMENUBAR_F10),
    HMainCommandOpenMemory
  },

  {
    0,
    0,
    NULL
  }
};

/**
  Init function for MainEditor

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainEditorInit (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  *HandleBuffer;
  UINTN       HandleCount;
  UINTN       Index;

  //
  // basic initialization
  //
  CopyMem (&HMainEditor, &HMainEditorConst, sizeof (HMainEditor));

  //
  // set screen attributes
  //
  HMainEditor.ColorAttributes.Colors.Foreground = gST->ConOut->Mode->Attribute & 0x000000ff;

  HMainEditor.ColorAttributes.Colors.Background = (UINT8) (gST->ConOut->Mode->Attribute >> 4);

  HOriginalColors = HMainEditor.ColorAttributes.Colors;

  HOriginalMode = gST->ConOut->Mode->Mode;

  //
  // query screen size
  //
  gST->ConOut->QueryMode (
        gST->ConOut,
        gST->ConOut->Mode->Mode,
        &(HMainEditor.ScreenSize.Column),
        &(HMainEditor.ScreenSize.Row)
        );

  //
  // Find mouse in System Table ConsoleInHandle
  //
  Status = gBS->HandleProtocol (
                gST->ConIn,
                &gEfiSimplePointerProtocolGuid,
                (VOID**)&HMainEditor.MouseInterface
                );
  if (EFI_ERROR (Status)) {
    //
    // If there is no Simple Pointer Protocol on System Table
    //
    HandleBuffer = NULL;
    HMainEditor.MouseInterface = NULL;
    Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiSimplePointerProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
    if (!EFI_ERROR (Status) && HandleCount > 0) {
      //
      // Try to find the first available mouse device
      //
      for (Index = 0; Index < HandleCount; Index++) {
        Status = gBS->HandleProtocol (
                      HandleBuffer[Index],
                      &gEfiSimplePointerProtocolGuid,
                      (VOID**)&HMainEditor.MouseInterface
                      );
        if (!EFI_ERROR (Status)) {
          break;
        }
      }
    }
    if (HandleBuffer != NULL) {
      FreePool (HandleBuffer);
    }
  }

  if (!EFI_ERROR (Status) && HMainEditor.MouseInterface != NULL) {
    HMainEditor.MouseAccumulatorX  = 0;
    HMainEditor.MouseAccumulatorY  = 0;
    HMainEditor.MouseSupported     = TRUE;
  }

  //
  // below will call the five components' init function
  //
  Status = MainTitleBarInit (L"UEFI HEXEDIT");
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_TITLE), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  Status = ControlHotKeyInit (HexMainControlBasedMenuFunctions);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }
  Status = MenuBarInit (HexEditorMenuItems);
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_MAINMENU), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  Status = StatusBarInit ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_STATUS), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  InputBarInit ();

  Status = HBufferImageInit ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_BUFFERIMAGE), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }

  Status = HClipBoardInit ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_MAINEDITOR_CLIPBOARD), gShellDebug1HiiHandle);
    return EFI_LOAD_ERROR;
  }
  //
  // clear whole screen and enable cursor
  //
  gST->ConOut->ClearScreen (gST->ConOut);
  gST->ConOut->EnableCursor (gST->ConOut, TRUE);

  //
  // initialize EditorFirst and EditorExit
  //
  HEditorFirst        = TRUE;
  HEditorExit         = FALSE;
  HEditorMouseAction  = FALSE;

  return EFI_SUCCESS;
}

/**
  Cleanup function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainEditorCleanup (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // call the five components' cleanup function
  //
  MainTitleBarCleanup ();

  MenuBarCleanup ();

  StatusBarCleanup ();
  
  InputBarCleanup ();
  
  Status = HBufferImageCleanup ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_BUFFERIMAGE_CLEAN), gShellDebug1HiiHandle);
  }

  Status = HClipBoardCleanup ();
  if (EFI_ERROR (Status)) {
    ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_LIBEDITOR_CLIPBOARD_CLEAN), gShellDebug1HiiHandle);
  }
  //
  // restore old mode
  //
  if (HOriginalMode != gST->ConOut->Mode->Mode) {
    gST->ConOut->SetMode (gST->ConOut, HOriginalMode);
  }

  gST->ConOut->SetAttribute (
        gST->ConOut,
        EFI_TEXT_ATTR (HOriginalColors.Foreground, HOriginalColors.Background)
        );
  gST->ConOut->ClearScreen (gST->ConOut);

  return EFI_SUCCESS;
}

/**
  Refresh function for MainEditor.

  @retval EFI_SUCCESS             The operation was successful.
**/
EFI_STATUS
HMainEditorRefresh (
  VOID
  )
{
  BOOLEAN NameChange;
  BOOLEAN ReadChange;

  NameChange = FALSE;
  ReadChange = FALSE;

  if (HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer) {
    if (HMainEditor.BufferImage->DiskImage != NULL &&
        HBufferImageBackupVar.DiskImage != NULL &&
        (HMainEditor.BufferImage->DiskImage->Offset != HBufferImageBackupVar.DiskImage->Offset || 
           HMainEditor.BufferImage->DiskImage->Size != HBufferImageBackupVar.DiskImage->Size) ){
      NameChange = TRUE;
    }
  } else if (HMainEditor.BufferImage->BufferType == FileTypeMemBuffer) {
    if (HMainEditor.BufferImage->MemImage != NULL &&
        HBufferImageBackupVar.MemImage != NULL &&
        (HMainEditor.BufferImage->MemImage->Offset != HBufferImageBackupVar.MemImage->Offset || 
           HMainEditor.BufferImage->MemImage->Size != HBufferImageBackupVar.MemImage->Size) ){
      NameChange = TRUE;
    }
  } else if (HMainEditor.BufferImage->BufferType == FileTypeFileBuffer) {
    if ( HMainEditor.BufferImage->FileImage != NULL && 
         HMainEditor.BufferImage->FileImage->FileName != NULL && 
         HBufferImageBackupVar.FileImage != NULL && 
         HBufferImageBackupVar.FileImage->FileName != NULL && 
         StrCmp (HMainEditor.BufferImage->FileImage->FileName, HBufferImageBackupVar.FileImage->FileName) != 0 ) {
      NameChange = TRUE;
    }
  }
  if ( HMainEditor.BufferImage->FileImage != NULL && 
       HBufferImageBackupVar.FileImage != NULL && 
       HMainEditor.BufferImage->FileImage->ReadOnly != HBufferImageBackupVar.FileImage->ReadOnly ) {
    ReadChange = TRUE;
  }

  //
  // to aVOID screen flicker
  // the stall value is from experience
  //
  gBS->Stall (50);

  //
  // call the components refresh function
  //
  if (HEditorFirst 
    || NameChange
    || HMainEditor.BufferImage->BufferType != HBufferImageBackupVar.BufferType 
    || HBufferImageBackupVar.Modified != HMainEditor.BufferImage->Modified 
    || ReadChange ) {

    MainTitleBarRefresh (
      HMainEditor.BufferImage->BufferType == FileTypeFileBuffer&&HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->FileName:HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Name:NULL,
      HMainEditor.BufferImage->BufferType,
      (BOOLEAN)(HMainEditor.BufferImage->FileImage!=NULL?HMainEditor.BufferImage->FileImage->ReadOnly:FALSE),
      HMainEditor.BufferImage->Modified,
      HMainEditor.ScreenSize.Column,
      HMainEditor.ScreenSize.Row,
      HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Offset:HMainEditor.BufferImage->BufferType == FileTypeMemBuffer&&HMainEditor.BufferImage->MemImage!=NULL?HMainEditor.BufferImage->MemImage->Offset:0,
      HMainEditor.BufferImage->BufferType == FileTypeDiskBuffer&&HMainEditor.BufferImage->DiskImage!=NULL?HMainEditor.BufferImage->DiskImage->Size  :HMainEditor.BufferImage->BufferType == FileTypeMemBuffer&&HMainEditor.BufferImage->MemImage!=NULL?HMainEditor.BufferImage->MemImage->Size  :0
      );
    HBufferImageRefresh ();
  }
  if (HEditorFirst
    || HBufferImageBackupVar.DisplayPosition.Row != HMainEditor.BufferImage->DisplayPosition.Row 
    || HBufferImageBackupVar.DisplayPosition.Column != HMainEditor.BufferImage->DisplayPosition.Column 
    || StatusBarGetRefresh()) {

    StatusBarRefresh (
      HEditorFirst,
      HMainEditor.ScreenSize.Row,
      HMainEditor.ScreenSize.Column,
      (UINTN)(-1),
      (UINTN)(-1),
      FALSE
      );
    HBufferImageRefresh ();
  }

  if (HEditorFirst) {
    HBufferImageRefresh ();
  }

  //
  // EditorFirst is now set to FALSE
  //
  HEditorFirst = FALSE;

  return EFI_SUCCESS;
}

/**
  Handle the mouse input.

  @param[in] MouseState             The current mouse state.
  @param[out] BeforeLeftButtonDown  helps with selections.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
  @retval EFI_NOT_FOUND           The disk was not found.
**/
EFI_STATUS
HMainEditorHandleMouseInput (
  IN  EFI_SIMPLE_POINTER_STATE       MouseState,
  OUT BOOLEAN                        *BeforeLeftButtonDown
  )
{

  INT32             TextX;
  INT32             TextY;
  UINTN             FRow;
  UINTN             FCol;
  BOOLEAN           HighBits;
  LIST_ENTRY    *Link;
  HEFI_EDITOR_LINE  *Line;
  UINTN             Index;
  BOOLEAN           Action;

  Action = FALSE;

  //
  // have mouse movement
  //
  if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
    //
    // handle
    //
    TextX = HGetTextX (MouseState.RelativeMovementX);
    TextY = HGetTextY (MouseState.RelativeMovementY);

    HBufferImageAdjustMousePosition (TextX, TextY);

    Action = TRUE;

  }

  if (MouseState.LeftButton) {
    HighBits = HBufferImageIsAtHighBits (
                HMainEditor.BufferImage->MousePosition.Column,
                &FCol
                );

    //
    // not at an movable place
    //
    if (FCol == 0) {
      //
      // now just move mouse pointer to legal position
      //
      //
      // move mouse position to legal position
      //
      HMainEditor.BufferImage->MousePosition.Column -= 10;
      if (HMainEditor.BufferImage->MousePosition.Column > 24) {
        HMainEditor.BufferImage->MousePosition.Column--;
        FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
      } else {
        if (HMainEditor.BufferImage->MousePosition.Column < 24) {
          FCol = HMainEditor.BufferImage->MousePosition.Column / 3 + 1 + 1;
        } else {
          //
          // == 24
          //
          FCol = 9;
        }
      }

      HighBits = TRUE;

    }

    FRow = HMainEditor.BufferImage->BufferPosition.Row +
      HMainEditor.BufferImage->MousePosition.Row -
      HMainEditor.BufferImage->DisplayPosition.Row;

    if (HMainEditor.BufferImage->NumLines < FRow) {
      //
      // dragging
      //
      //
      // now just move mouse pointer to legal position
      //
      FRow      = HMainEditor.BufferImage->NumLines;
      HighBits  = TRUE;
    }

    Link = HMainEditor.BufferImage->ListHead->ForwardLink;
    for (Index = 0; Index < FRow - 1; Index++) {
      Link = Link->ForwardLink;
    }

    Line = CR (Link, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST);

    //
    // dragging
    //
    //
    // now just move mouse pointer to legal position
    //
    if (FCol > Line->Size) {
      if (*BeforeLeftButtonDown) {
        HighBits = FALSE;

        if (Line->Size == 0) {
          if (FRow > 1) {
            FRow--;
            FCol = 16;
          } else {
            FRow  = 1;
            FCol  = 1;
          }

        } else {
          FCol = Line->Size;
        }
      } else {
        FCol      = Line->Size + 1;
        HighBits  = TRUE;
      }
    }

    HBufferImageMovePosition (FRow, FCol, HighBits);

    HMainEditor.BufferImage->MousePosition.Row    = HMainEditor.BufferImage->DisplayPosition.Row;

    HMainEditor.BufferImage->MousePosition.Column = HMainEditor.BufferImage->DisplayPosition.Column;

    *BeforeLeftButtonDown                         = TRUE;

    Action = TRUE;
  } else {
    //
    // else of if LButton
    //
    // release LButton
    //
    if (*BeforeLeftButtonDown) {
      Action = TRUE;
    }
    //
    // mouse up
    //
    *BeforeLeftButtonDown = FALSE;
  }

  if (Action) {
    return EFI_SUCCESS;
  }

  return EFI_NOT_FOUND;
}

/**
  Handle user key input. will route it to other components handle function.

  @retval EFI_SUCCESS             The operation was successful.
  @retval EFI_OUT_OF_RESOURCES    A memory allocation occured.
  @retval EFI_LOAD_ERROR          A load error occured.
**/
EFI_STATUS
HMainEditorKeyInput (
  VOID
  )
{
  EFI_INPUT_KEY             Key;
  EFI_STATUS                Status;
  EFI_SIMPLE_POINTER_STATE  MouseState;
  BOOLEAN                   LengthChange;
  UINTN                     Size;
  UINTN                     OldSize;
  BOOLEAN                   BeforeMouseIsDown;
  BOOLEAN                   MouseIsDown;
  BOOLEAN                   FirstDown;
  BOOLEAN                   MouseDrag;
  UINTN                     FRow;
  UINTN                     FCol;
  UINTN                     SelectStartBackup;
  UINTN                     SelectEndBackup;

  //
  // variable initialization
  //
  OldSize       = 0;
  FRow          = 0;
  FCol          = 0;
  LengthChange  = FALSE;

  MouseIsDown   = FALSE;
  FirstDown     = FALSE;
  MouseDrag     = FALSE;

  do {

    Status              = EFI_SUCCESS;

    HEditorMouseAction  = FALSE;

    //
    // backup some key elements, so that can aVOID some refresh work
    //
    HMainEditorBackup ();

    //
    // wait for user key input
    //
    //
    // change priority of checking mouse/keyboard activity dynamically
    // so prevent starvation of keyboard.
    // if last time, mouse moves then this time check keyboard
    //
    if (HMainEditor.MouseSupported) {
      Status = HMainEditor.MouseInterface->GetState (
                                            HMainEditor.MouseInterface,
                                            &MouseState
                                            );
      if (!EFI_ERROR (Status)) {

        BeforeMouseIsDown = MouseIsDown;

        Status            = HMainEditorHandleMouseInput (MouseState, &MouseIsDown);

        if (!EFI_ERROR (Status)) {
          if (!BeforeMouseIsDown) {
            //
            // mouse down
            //
            if (MouseIsDown) {
              FRow              = HBufferImage.BufferPosition.Row;
              FCol              = HBufferImage.BufferPosition.Column;
              SelectStartBackup = HMainEditor.SelectStart;
              SelectEndBackup   = HMainEditor.SelectEnd;

              FirstDown         = TRUE;
            }
          } else {

            SelectStartBackup = HMainEditor.SelectStart;
            SelectEndBackup   = HMainEditor.SelectEnd;

            //
            // begin to drag
            //
            if (MouseIsDown) {
              if (FirstDown) {
                if (MouseState.RelativeMovementX || MouseState.RelativeMovementY) {
                  HMainEditor.SelectStart = 0;
                  HMainEditor.SelectEnd   = 0;
                  HMainEditor.SelectStart = (FRow - 1) * 0x10 + FCol;

                  MouseDrag               = TRUE;
                  FirstDown               = FALSE;
                }
              } else {
                if ((
                      (HBufferImage.BufferPosition.Row - 1) *
                    0x10 +
                    HBufferImage.BufferPosition.Column
                      ) >= HMainEditor.SelectStart
                        ) {
                  HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
                    0x10 +
                    HBufferImage.BufferPosition.Column;
                } else {
                  HMainEditor.SelectEnd = 0;
                }
              }
              //
              // end of if RelativeX/Y
              //
            } else {
              //
              // mouse is up
              //
              if (MouseDrag) {
                if (HBufferImageGetTotalSize () == 0) {
                  HMainEditor.SelectStart = 0;
                  HMainEditor.SelectEnd   = 0;
                  FirstDown               = FALSE;
                  MouseDrag               = FALSE;
                }

                if ((
                      (HBufferImage.BufferPosition.Row - 1) *
                    0x10 +
                    HBufferImage.BufferPosition.Column
                      ) >= HMainEditor.SelectStart
                        ) {
                  HMainEditor.SelectEnd = (HBufferImage.BufferPosition.Row - 1) *
                    0x10 +
                    HBufferImage.BufferPosition.Column;
                } else {
                  HMainEditor.SelectEnd = 0;
                }

                if (HMainEditor.SelectEnd == 0) {
                  HMainEditor.SelectStart = 0;
                }
              }

              FirstDown = FALSE;
              MouseDrag = FALSE;
            }

            if (SelectStartBackup != HMainEditor.SelectStart || SelectEndBackup != HMainEditor.SelectEnd) {
              if ((SelectStartBackup - 1) / 0x10 != (HMainEditor.SelectStart - 1) / 0x10) {
                HBufferImageNeedRefresh = TRUE;
              } else {
                if ((SelectEndBackup - 1) / 0x10 != (HMainEditor.SelectEnd - 1) / 0x10) {
                  HBufferImageNeedRefresh = TRUE;
                } else {
                  HBufferImageOnlyLineNeedRefresh = TRUE;
                }
              }
            }
          }

          HEditorMouseAction            = TRUE;
          HBufferImageMouseNeedRefresh  = TRUE;

        } else if (Status == EFI_LOAD_ERROR) {
          StatusBarSetStatusString (L"Invalid Mouse Movement ");
        }
      }
    }

    Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
    if (!EFI_ERROR (Status)) {
      //
      // dispatch to different components' key handling function
      // so not everywhere has to set this variable
      //
      HBufferImageMouseNeedRefresh = TRUE;

      //
      // clear previous status string
      //
      StatusBarSetRefresh();
      if (EFI_SUCCESS == MenuBarDispatchControlHotKey(&Key)) {
        Status = EFI_SUCCESS;
      } else if (Key.ScanCode == SCAN_NULL) {
        Status = HBufferImageHandleInput (&Key);
      } else if (((Key.ScanCode >= SCAN_UP) && (Key.ScanCode <= SCAN_PAGE_DOWN))) {
        Status = HBufferImageHandleInput (&Key);
      } else if (((Key.ScanCode >= SCAN_F1) && Key.ScanCode <= (SCAN_F12))) {
        Status = MenuBarDispatchFunctionKey (&Key);
      } else {
        StatusBarSetStatusString (L"Unknown Command");

        HBufferImageMouseNeedRefresh = FALSE;
      }

      if (Status != EFI_SUCCESS && Status != EFI_OUT_OF_RESOURCES) {
        //
        // not already has some error status
        //
        if (StrCmp (L"", StatusBarGetString()) == 0) {
          StatusBarSetStatusString (L"Disk Error. Try Again");
        }
      }
    }
    //
    // decide if has to set length warning
    //
    if (HBufferImage.BufferType != HBufferImageBackupVar.BufferType) {
      LengthChange = FALSE;
    } else {
      //
      // still the old buffer
      //
      if (HBufferImage.BufferType != FileTypeFileBuffer) {
        Size = HBufferImageGetTotalSize ();

        switch (HBufferImage.BufferType) {
        case FileTypeDiskBuffer:
          OldSize = HBufferImage.DiskImage->Size * HBufferImage.DiskImage->BlockSize;
          break;

        case FileTypeMemBuffer:
          OldSize = HBufferImage.MemImage->Size;
          break;
        
        default:
          OldSize = 0;
          break;
        }

        if (!LengthChange) {
          if (OldSize != Size) {
            StatusBarSetStatusString (L"Disk/Mem Buffer Length should not be changed");
          }
        }

        if (OldSize != Size) {
          LengthChange = TRUE;
        } else {
          LengthChange = FALSE;
        }
      }
    }
    //
    // after handling, refresh editor
    //
    HMainEditorRefresh ();

  } while (Status != EFI_OUT_OF_RESOURCES && !HEditorExit);

  return Status;
}

/**
  Backup function for MainEditor.
**/
VOID
HMainEditorBackup (
  VOID
  )
{
  HMainEditorBackupVar.SelectStart  = HMainEditor.SelectStart;
  HMainEditorBackupVar.SelectEnd    = HMainEditor.SelectEnd;
  HBufferImageBackup ();
}
