/** @file
  Implements titlebar interface functions.

  (C) Copyright 2013 Hewlett-Packard Development Company, L.P.<BR>
  Copyright (c) 2005 - 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 "EditTitleBar.h"
#include "UefiShellDebug1CommandsLib.h"

CHAR16  *Title = NULL;

/**
  Initialize a title bar.

  @param[in] Prompt             The prompt to print in the title bar.

  @retval EFI_SUCCESS           The initialization was successful.
  @retval EFI_OUT_OF_RESOURCES  A memory allocation failed.
**/
EFI_STATUS
EFIAPI
MainTitleBarInit (
  CONST CHAR16 *Prompt
  )
{
  SHELL_FREE_NON_NULL (Title);
  if (Prompt == NULL) {
    Title = CatSPrint (NULL, L"");
  } else {
    //
    // set Title
    //
    Title = CatSPrint (NULL, L"%s", Prompt);
  }
  if (Title == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Clean up the memory used.
**/
VOID
EFIAPI
MainTitleBarCleanup (
  VOID
  )
{
  SHELL_FREE_NON_NULL (Title);
  Title = NULL;
}

typedef struct {
  UINT32  Foreground : 4;
  UINT32  Background : 4;
} TITLE_BAR_COLOR_ATTRIBUTES;

typedef union {
  TITLE_BAR_COLOR_ATTRIBUTES  Colors;
  UINTN                       Data;
} TITLE_BAR_COLOR_UNION;

/**
  Refresh function for MainTitleBar

  @param[in] FileName           The open file's name (or NULL).
  @param[in] FileType           The type fo the file.
  @param[in] ReadOnly           TRUE if the file is read only.  FALSE otherwise.
  @param[in] Modified           TRUE if the file was modified.  FALSE otherwise.
  @param[in] LastCol            The last printable column.
  @param[in] LastRow            The last printable row.
  @param[in] Offset             The offset into the file. (only for mem/disk)
  @param[in] Size               The file's size. (only for mem/disk)

  @retval EFI_SUCCESS           The operation was successful.
**/
EFI_STATUS
EFIAPI
MainTitleBarRefresh (
  IN CONST CHAR16                 *FileName OPTIONAL,
  IN CONST EDIT_FILE_TYPE         FileType,
  IN CONST BOOLEAN                ReadOnly,
  IN CONST BOOLEAN                Modified,
  IN CONST UINTN                  LastCol,
  IN CONST UINTN                  LastRow,
  IN CONST UINTN                  Offset,
  IN CONST UINTN                  Size
  )
{
  TITLE_BAR_COLOR_UNION   Orig;
  TITLE_BAR_COLOR_UNION   New;
  CONST CHAR16            *FileNameTmp;
  INTN                    TempInteger;


  //
  // backup the old screen attributes
  //
  Orig.Data             = gST->ConOut->Mode->Attribute;
  New.Data              = 0;
  New.Colors.Foreground = Orig.Colors.Background & 0xF;
  New.Colors.Background = Orig.Colors.Foreground & 0x7;

  gST->ConOut->SetAttribute (gST->ConOut, New.Data & 0x7F);

  //
  // clear the title line
  //
  EditorClearLine (1, LastCol, LastRow);

  if (Title != NULL) {
    //
    // print the new title bar prefix
    //
    ShellPrintEx (
      0,
      0,
      L"%s ",
      Title
      );
  }
  if (FileName == NULL) {
    gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);
    return EFI_SUCCESS;
  }
  //
  // First Extract the FileName from fullpath
  //
  FileNameTmp = FileName;
  for (TempInteger = StrLen (FileNameTmp) - 1; TempInteger >= 0; TempInteger--) {
    if (FileNameTmp[TempInteger] == L'\\') {
      break;
    }
  }

  FileNameTmp = FileNameTmp + TempInteger + 1;

  //
  // the space for file name is 20 characters
  //
  if (StrLen (FileNameTmp) <= 20) {
    ShellPrintEx (-1,-1, L"%s   ", FileNameTmp);
    for (TempInteger = StrLen (FileNameTmp); TempInteger < 20; TempInteger++) {
      ShellPrintEx (-1,-1, L" ");
    }

  } else {
    for (TempInteger = 0; TempInteger < 17; TempInteger++) {
      ShellPrintEx (-1,-1, L"%c", FileNameTmp[TempInteger]);
    }
    //
    // print "..."
    //
    ShellPrintEx (-1,-1, L"...   ");
  }
  //
  // print file type field
  //
  switch (FileType){
    case FileTypeAscii:
    case FileTypeUnicode:
      if (FileType == FileTypeAscii){
        ShellPrintEx (-1,-1, L"     ASCII     ");
      } else {
        ShellPrintEx (-1,-1, L"     UNICODE   ");
      }
      //
      // print read-only field for text files
      //
      if (ReadOnly) {
        ShellPrintEx (-1,-1, L"ReadOnly   ");
      } else {
        ShellPrintEx (-1,-1, L"           ");
      }
    break;
    case FileTypeDiskBuffer:
    case FileTypeMemBuffer:
      //
      // Print the offset.
      //
      ShellPrintEx (-1,-1, L"Offset %X | Size %X", Offset, Size);
    case FileTypeFileBuffer:
      break;
    default:
      break;
  }
  //
  // print modified field
  //
  if (Modified) {
    ShellPrintEx (-1,-1, L"Modified");
  }
  //
  // restore the old attribute
  //
  gST->ConOut->SetAttribute (gST->ConOut, Orig.Data);

  return EFI_SUCCESS;
}
