#include "unitConvertor.h"

#include <sstream>

std::wstring formatDistance(const unsigned long long kilometers, int orders) {
	
	std::wstringstream formatted;

	int ordersLeft = orders;

	unsigned long long kilometersLeft = kilometers;

	if (ordersLeft > 0 && kilometersLeft >= LIGHT_YEAR_IN_KM) {		
		unsigned long lightYears = (kilometersLeft / LIGHT_YEAR_IN_KM);
		kilometersLeft = kilometersLeft - (lightYears * LIGHT_YEAR_IN_KM);
		formatted << " " << lightYears << " ly";
		ordersLeft--;
	}

	/*

	Do not use conversion to light months

	if (ordersLeft > 0 && kilometersLeft >= LIGHT_MONTH_IN_KM) {
		unsigned long long lightMonths = (kilometersLeft / LIGHT_MONTH_IN_KM);
		kilometersLeft = kilometersLeft - (lightMonths * LIGHT_MONTH_IN_KM);
		formatted << " " << lightMonths << " lM";
		ordersLeft--;
	}
	*/
	
	if (ordersLeft > 0 && kilometersLeft >= LIGHT_DAY_IN_KM) {
		unsigned long long lightDays = (kilometersLeft / LIGHT_DAY_IN_KM);
		kilometersLeft = kilometersLeft - (lightDays * LIGHT_DAY_IN_KM);
		formatted << " " << lightDays << " ld";
		ordersLeft--;
	}

	if (ordersLeft > 0 && kilometersLeft >= LIGHT_HOUR_IN_KM) {
		unsigned long long lightHours = (kilometersLeft / LIGHT_HOUR_IN_KM);
		kilometersLeft = kilometersLeft - (lightHours * LIGHT_HOUR_IN_KM);
		formatted << " " << lightHours << " lh";
		ordersLeft--;
	}

	if (ordersLeft > 0 && kilometersLeft >= LIGHT_MINUTE_IN_KM) {
		unsigned long long lightMinutes = (kilometersLeft / LIGHT_MINUTE_IN_KM);
		kilometersLeft = kilometersLeft - (lightMinutes * LIGHT_MINUTE_IN_KM);
		formatted << " " << lightMinutes << " lm";
		ordersLeft--;
	}

	if (ordersLeft > 0 && kilometersLeft >= LIGHT_SECOND_IN_KM) {
		unsigned long long lightSeconds = (kilometersLeft / LIGHT_SECOND_IN_KM);
		kilometersLeft = kilometersLeft - (lightSeconds * LIGHT_SECOND_IN_KM);
		formatted << " " << lightSeconds << " ls";
		ordersLeft--;
	}

	if (ordersLeft > 0) {
		formatted << " " << kilometersLeft << " km";
	}

	return formatted.str();
}

std::wstring formatTime(const unsigned long long seconds) {
	std::wstringstream formatted;

	unsigned long long secondsLeft = seconds;

	unsigned long long hours = 0;
	unsigned long long minutes = 0;

	if (secondsLeft >= HOUR_IN_SECONDS) {		
		hours = (secondsLeft / HOUR_IN_SECONDS);
		secondsLeft = secondsLeft % HOUR_IN_SECONDS;		
	}

	if (secondsLeft >= MINUTE_IN_SECONDS) {		
		minutes = (secondsLeft / MINUTE_IN_SECONDS);
		secondsLeft = secondsLeft % MINUTE_IN_SECONDS;		
	}

	formatted << hours << ":" << minutes << ":" << secondsLeft;

	return formatted.str();
}

std::wstring formatSpeed(const unsigned long long metersPerSecond) {
	std::wstringstream formatted;

	unsigned long long metersLeft = metersPerSecond;

	if (metersLeft / 100 >= LIGHT_YEAR_IN_METERS) {		
		unsigned long long lightYears = (metersLeft / LIGHT_YEAR_IN_METERS);
		metersLeft = metersLeft - (lightYears * LIGHT_YEAR_IN_METERS);
		formatted << lightYears << " ly / s";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_DAY_IN_METERS) {
		unsigned long long lightDays = (metersLeft / LIGHT_DAY_IN_METERS);
		metersLeft = metersLeft - (lightDays * LIGHT_DAY_IN_METERS);
		formatted << lightDays << " ld / s";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_HOUR_IN_METERS) {
		unsigned long long lightHours = (metersLeft / LIGHT_HOUR_IN_METERS);
		metersLeft = metersLeft - (lightHours * LIGHT_HOUR_IN_METERS);
		formatted << lightHours << " lh / s";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_MINUTE_IN_METERS) {
		unsigned long long lightMinutes = (metersLeft / LIGHT_MINUTE_IN_METERS);
		metersLeft = metersLeft - (lightMinutes * LIGHT_MINUTE_IN_METERS);
		formatted << lightMinutes << " lm / s";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_SECOND_IN_METERS) {
		unsigned long long lightSeconds = (metersLeft / LIGHT_SECOND_IN_METERS);
		metersLeft = metersLeft - (lightSeconds * LIGHT_SECOND_IN_METERS);
		formatted << lightSeconds << " ls / s";
		return formatted.str();
	}

	if (metersLeft / 1000 >= KILOMETER_IN_METERS) {
		unsigned long long kilometers = (metersLeft / KILOMETER_IN_METERS);
		metersLeft = metersLeft - (kilometers * KILOMETER_IN_METERS);
		formatted << kilometers << " km / s";
		return formatted.str();
	}

	formatted << metersLeft << " m / s";
	return formatted.str();
}

std::wstring formatAccelerance(const unsigned long long metersPerSecond) {
	std::wstringstream formatted;

	unsigned long long metersLeft = metersPerSecond;

	if (metersLeft / 100 >= LIGHT_YEAR_IN_METERS) {		
		unsigned long long lightYears = (metersLeft / LIGHT_YEAR_IN_METERS);
		metersLeft = metersLeft - (lightYears * LIGHT_YEAR_IN_METERS);
		formatted << lightYears << " l. years / s^2";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_DAY_IN_METERS) {
		unsigned long long lightDays = (metersLeft / LIGHT_DAY_IN_METERS);
		metersLeft = metersLeft - (lightDays * LIGHT_DAY_IN_METERS);
		formatted << lightDays << " l. days / s^2";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_HOUR_IN_METERS) {
		unsigned long long lightHours = (metersLeft / LIGHT_HOUR_IN_METERS);
		metersLeft = metersLeft - (lightHours * LIGHT_HOUR_IN_METERS);
		formatted << lightHours << " l. hours / s^2";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_MINUTE_IN_METERS) {
		unsigned long long lightMinutes = (metersLeft / LIGHT_MINUTE_IN_METERS);
		metersLeft = metersLeft - (lightMinutes * LIGHT_MINUTE_IN_METERS);
		formatted << lightMinutes << " l. months / s^2";
		return formatted.str();
	}

	if (metersLeft / 100 >= LIGHT_SECOND_IN_METERS) {
		unsigned long long lightSeconds = (metersLeft / LIGHT_SECOND_IN_METERS);
		metersLeft = metersLeft - (lightSeconds * LIGHT_SECOND_IN_METERS);
		formatted << lightSeconds << " l.seconds / s^2";
		return formatted.str();
	}

	if (metersLeft / 1000 >= KILOMETER_IN_METERS) {
		unsigned long long kilometers = (metersLeft / KILOMETER_IN_METERS);
		metersLeft = metersLeft - (kilometers * KILOMETER_IN_METERS);
		formatted << kilometers << " km / s^2";
		return formatted.str();
	}

	formatted << metersLeft << " m / s^2";
	return formatted.str();
}