/**
 * NUM2STR - Functions to handle the conversion of numeric vales to strings.
 *
 * @created	2014-12-18
 * @author	Neven Boyanov
 * @version	2016-04-17 (last modified)
 *
 * This is part of the Tinusaur/TinyAVRLib project.
 *
 * Copyright (c) 2016 Neven Boyanov, Tinusaur Team. All Rights Reserved.
 * Distributed as open source software under MIT License, see LICENSE.txt file.
 * Please, as a favor, retain the link http://tinusaur.org to The Tinusaur Project.
 *
 * Source code available at: https://bitbucket.org/tinusaur/tinyavrlib
 *
 */

// ============================================================================

#include "num2str.h"

// ----------------------------------------------------------------------------

// NOTE: This implementation is borrowed from the LCDDDD library.
// Original source code at: https://bitbucket.org/boyanov/avr/src/default/lcdddd/src/lcdddd/lcdddd.h

uint8_t usint2decascii(uint16_t num, char *buffer)
{
	const unsigned short powers[] = { 10000u, 1000u, 100u, 10u, 1u }; // The "const unsigned short" combination gives shortest code.
	char digit; // "digit" is stored in a char array, so it should be of type char.
	uint8_t digits = USINT2DECASCII_MAX_DIGITS - 1;
	for (uint8_t pos = 0; pos < 5; pos++) // "pos" is index in array, so should be of type int.
	{
		digit = 0;
		while (num >= powers[pos])
		{
			digit++;
			num -= powers[pos];
		}

		// ---- CHOOSE (1), (2) or (3) ----

		// CHOICE (1) Fixed width, zero padded result.
		/*
		buffer[pos] = digit + '0';	// Convert to ASCII
		*/

		// CHOICE (2) Fixed width, zero padded result, digits offset.
		/*
		buffer[pos] = digit + '0';	// Convert to ASCII
		// Note: Determines the offset of the first significant digit.
		if (digits == -1 && digit != 0) digits = pos;
		// Note: Could be used for variable width, not padded, left aligned result.
		*/

		// CHOICE (3) Fixed width, space (or anything else) padded result, digits offset.
		// Note: Determines the offset of the first significant digit.
		// Note: Could be used for variable width, not padded, left aligned result.
		if (digits == USINT2DECASCII_MAX_DIGITS - 1)
		{
			if (digit == 0)
			{
				if (pos < USINT2DECASCII_MAX_DIGITS - 1)	// Check position, so single "0" will be handled properly.
					digit = -16;	// Use: "-16" for space (' '), "-3" for dash/minus ('-'), "0" for zero ('0'), etc. ...
			}
			else
			{
				digits = pos;
			}
		}
		buffer[pos] = digit + '0';	// Convert to ASCII

	}

	// NOTE: The resulting ascii text should not be terminated with '\0' here.
	//       The provided buffer maybe part of a larger text in both directions.

	return digits;
}

// ----------------------------------------------------------------------------

// NOTE: The buffer should be always at least MAX_DIGITS in length - the function works with 16-bit numbers.

uint8_t usint2binascii(uint16_t num, char *buffer) {
	uint16_t power = 0x8000;	// This is the 1000 0000 0000 0000 binary number.
	char digit; // "digit" is stored in a char array, so it should be of type char.
	uint8_t digits = USINT2BINASCII_MAX_DIGITS - 1;
	for (uint8_t pos = 0; pos < USINT2BINASCII_MAX_DIGITS; pos++) { // "pos" is index in an array.
		digit = 0;
		if (num >= power) {
			digit++;
			num -= power;
		}
		// Fixed width, space ('0', or anything else) padded result, digits offset.
		// Note: Determines the offset of the first significant digit.
		// Note: Could be used for variable width, not padded, left aligned result.
		if (digits == USINT2BINASCII_MAX_DIGITS - 1) {
			if (digit == 0) {
				if (pos < USINT2BINASCII_MAX_DIGITS - 1) // Check position, so single "0" will be handled properly.
					digit = 0; // Use: "-16" for space (' '), "-3" for dash/minus ('-'), "0" for zero ('0'), etc.
			} else {
				digits = pos;
			}
		}
		buffer[pos] = digit + '0';	// Convert to ASCII
		power = power >> 1;
	}
	// NOTE: The resulting ascii text should not be terminated with '\0' here.
	//       The provided buffer maybe part of a larger text in both directions.
	return digits;
}

// ============================================================================
