//
#include "SDCard.h"
//
//----------------------
//  Global
//----------------------
extern char Buffer[];
extern char Line[];
//
const char* CardTypeText(ECardType cardtype)
{
  switch (cardtype)
  {
    case ctNone:
      return "None";
    case ctMMC:
      return "MMC"; 
    case ctSD:
      return "SD";
    case ctSDHC:
      return "SDHC";
    default: // ctUnknown    
      return "Unknown";
  }
}
//
//----------------------
//  Constructor
//----------------------
CSDCard::CSDCard(int pinss)
{
    FPinSS = pinss;
}
//
bool CSDCard::Initialise(void)
{
  if (!SD.begin(FPinSS))
  {
    Error("Failed mounting SDCard");
    return false;
  }
  return true;
}
//
//----------------------
//  Property
//----------------------
bool CSDCard::IsEndOfFile(void)
{
  return !FFile.available();
}
//
ECardType CSDCard::GetCardType(void)
{
  uint8_t CT = SD.cardType();
  if (CARD_NONE == CT)
  {
    return ctNone;
  }
  if (CARD_MMC == CT)
  {
    return ctMMC;
  } 
  if (CARD_SD == CT)
  {
    return ctSD;
  } 
  if (CARD_SDHC == CT)
  {
    return ctSDHC;
  } 
  return ctUnknown;
}
// 
uint64_t CSDCard::GetCardSizeMB(void)
{
  uint64_t CS = SD.cardSize() / (1024 * 1024);
  return CS;
}
//
//----------------------
//  WriteFile
//----------------------
bool CSDCard::OpenWrite(const char* fileentry)
{
  FFile = SD.open(fileentry, "w");
  if (!FFile)
  {
    return false;
  }
  return true;
}
bool CSDCard::OpenAppend(const char* fileentry)
{
  FFile = SD.open(fileentry, "a");
  if (!FFile)
  {
    return false;
  }
  return true;
}
//
bool CSDCard::WriteCharacter(const char character)
{
  if (!FFile)
  {
    return false;
  }
  FFile.write(character);
  return true;
}
bool CSDCard::WriteText(const char* text)
{
  if (!FFile)
  {
    return false;
  }
  int S = strlen(text);
  for (int CI = 0; CI < S; CI++)
  {
    FFile.write(text[CI]);
  }
  return true;
}
bool CSDCard::WriteLine(const char* line)
{
  if (!FFile)
  {
    return false;
  }
  int S = strlen(line);
  for (int CI = 0; CI < S; CI++)
  {
    FFile.write(line[CI]);
  }
  FFile.write(0x0D);
  FFile.write(0x0A);
  return true;
}
//
bool CSDCard::CloseWrite(void)
{
  if (FFile)
  {
    FFile.close();
    return true;
  }
  return false;
}
//
//----------------------
//  ReadFile
//----------------------
bool CSDCard::OpenRead(const char* fileentry)
{
  FFile = SD.open(fileentry, "r");
  if (!FFile)
  {
    return false;
  }
  return true;
}
//
bool CSDCard::ReadCharacter(char &character)
{
  if (!FFile)
  {
    return false;
  }
  if (!FFile.available())
  {
    return false;
  }
  character = FFile.read();    
  return true;
}
bool CSDCard::ReadText(char* text, unsigned &size)
{
  if (!FFile)
  {
    return false;
  }
  for (int CI = 0; CI < size; CI++)
  {
    if (!FFile.available())
    {
      size = CI;
      return false;
    }
    text[CI] = FFile.read();
  }
  return true;
}
bool CSDCard::ReadLine(char* line)
{
  if (!FFile)
  {
    return false;
  }
  int CI = 0;
  line[CI] = 0x00;
  bool Loop = true;
  while (Loop)
  {
    char C = FFile.read();
    if ((0x0A == C) || (0x0D == C))
    {
      line[CI] = 0x00;
      if (0 < CI)
      {
        Loop = false;
        return true;
      }
    } 
    else
    {
      line[CI] = C;
      CI++;
      line[CI] = 0x00;
      Loop = Loop && FFile.available();
    }
  }
  return false;
}
//
bool CSDCard::CloseRead(void)
{
  if (FFile)
  {
    FFile.close();
    return true;
  }
  return false;
}
//
//----------------------
//  File
//----------------------
bool CSDCard::RenameFile(const char* entrysource, const char* entrytarget)
{
  if (SD.rename(entrysource, entrytarget)) 
  {
    return true;
  }
  return false;
}
bool CSDCard::RemoveFile(const char* entry)
{
  if (SD.remove(entry)) 
  {
    return true;
  }
  return false;
}
//
//----------------------
//  Directory
//----------------------
bool CSDCard::ListDirectory(const char* entry)
{
  Term("Directory[");
  Term(entry);
  Message("]:");
  File FD = SD.open(entry);
  if (!FD)
  {
    Error("Open Directory failed");
    return false;
  }
  if (!FD.isDirectory())
  {
    Error("Entry not a Directory");
    return false;    
  }
  File FE = FD.openNextFile();
  while (FE)
  {
    if (FE.isDirectory())
    {
      Term("SubDirectory[");
      Term(FE.name());
      Message("]");
    }
    else
    {
      sprintf(Buffer, "File: %s [%lukB]", FE.name(), (long unsigned)(1 + FE.size() / 1024));
      Message(Buffer);
    }
    FE = FD.openNextFile();
  }
  return true;
}
bool CSDCard::CreateDirectory(const char* entry)
{
  if (SD.mkdir(entry))
  {    
    return true;
  }
  return false;
}
bool CSDCard::RemoveDirectory(const char* entry)
{
  if (SD.rmdir(entry))
  {
    return true;
  }
  return false;
}
//
