/*
    CaPriCe Forever - Amstrad CPC 464/664/6128 emulator
    Copyright (C) 2014-2018 by Frédéric Coste

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#include "strings.h"


#define MAX_LENGTH      255


tChar* StringAddString(tChar* bufferP, const tChar* stringP)
{
  // Until end of null terminated string
  while (*stringP != '\0')
  {
    *(bufferP++) = *(stringP++);
  }

  // Terminate string
  *bufferP = '\0';

  return bufferP;
}
//---------------------------------------------------------------------------


tUChar StringLength(const tChar* stringP)
{
tUChar Length = 0;

  // Until end of null terminated string
  while ( (*(stringP++) != '\0') && (Length < MAX_LENGTH) )
  {
    Length++;
  }

  // Incorrect string ?
  if (Length == MAX_LENGTH)
  {
    Length = 0;
  }

  return Length;
}
//---------------------------------------------------------------------------


tChar StringCompare(const tChar* string1P, const tChar* string2P)
{
  // Compare sizes
  if (StringLength(string1P) != StringLength(string2P))
    return 1;

  // Until end of null terminated string
  while ( (*string1P != '\0') && (*string2P != '\0') )
  {
    if (*(string1P++) != *(string2P++))
    {
      return 1;
    }
  }

  return 0;
}
//---------------------------------------------------------------------------


tChar* StringAddChar(tChar* bufferP, tChar character)
{
  *(bufferP++) = character;

  // Terminate string
  *bufferP = '\0';

  return bufferP;
}
//---------------------------------------------------------------------------


tChar* StringAddSpace(tChar* bufferP)
{
  *(bufferP++) = ' ';

  // Terminate string
  *bufferP = '\0';

  return bufferP;
}
//---------------------------------------------------------------------------


tChar* StringAddDecByte(tChar* bufferP, tUChar Value)
{
tUChar Temp;
tUChar Divisor;
tBool FirstZero;

  Divisor = 100U;
  FirstZero = cTrue;
  
  while (Divisor >= 10U)
  {
    Temp = Value / Divisor;
    Value -= (tUChar)(Temp * Divisor);
    // Prevent leading zero.
    if ( (Temp > 0U) || (FirstZero == cFalse) )
    {
      *(bufferP++) = (tUChar)'0' + Temp;
      FirstZero = cFalse;
    }
    
    Divisor /= 10U;
  }
  
  // Add Unity
  *(bufferP++) = (tUChar)'0' + Value;

  // Terminate string
  *bufferP = '\0';

  return bufferP;
}
//---------------------------------------------------------------------------


tChar* StringAddHexByte(tChar* bufferP, tUChar Byte)
{
tUChar Nibble;

  // Most significant Nibble
  Nibble = (Byte >> 4) & 0x0F;
  *(bufferP++) = (Nibble >= 0x0A) ? 'A' + (Nibble - 0x0A) : '0' + Nibble;
  
  // Least Significant Nibble
  Nibble = Byte & 0x0F;
  *(bufferP++) = (Nibble >= 0x0A) ? 'A' + (Nibble - 0x0A) : '0' + Nibble;
  
  // Terminate string
  *bufferP = '\0';

  return bufferP;
}
//---------------------------------------------------------------------------


tChar* StringAddHexShort(tChar* bufferP, tUShort Short)
{
tUShort Nibble;

  // Most significant Nibble
  Nibble = (Short >> 12) & 0x000F;
  *(bufferP++) = (Nibble >= 0x000A) ? 'A' + (Nibble - 0x000A) : '0' + Nibble;

  Nibble = (Short >> 8) & 0x000F;
  *(bufferP++) = (Nibble >= 0x000A) ? 'A' + (Nibble - 0x000A) : '0' + Nibble;
  
  Nibble = (Short >> 4) & 0x000F;
  *(bufferP++) = (Nibble >= 0x000A) ? 'A' + (Nibble - 0x000A) : '0' + Nibble;
  
  // Least Significant Nibble
  Nibble = Short & 0x000F;
  *(bufferP++) = (Nibble >= 0x000A) ? 'A' + (Nibble - 0x000A) : '0' + Nibble;

  // Terminate string
  *bufferP = '\0';

  return bufferP;
}
//---------------------------------------------------------------------------


// Reverses a string 'str' of length 'len'
void StringReverse(tChar* str, tUChar len)
{
  tUChar i = 0, j = len - 1;

  while (i < j)
  {
    tChar temp = str[i];
    str[i] = str[j];
    str[j] = temp;

    i++;
    j--;
  }
}
//---------------------------------------------------------------------------


// Converts a given integer x to string str[].
tUChar StringIntToStr(tLong x, tChar* str)
{
  tUChar i = 0;

  if (!x)
  {
    str[i++] = '0';
  }
  else while (x)
  {
    str[i++] = (x % 10) + '0';
    x = x / 10;
  }

  StringReverse(str, i);

  str[i] = '\0';

  return i;
}
//---------------------------------------------------------------------------


#ifdef __cplusplus
}  /* End of the 'extern "C"' block */
#endif

