#ifndef __DPKDEPS_H__
#define __DPKDEPS_H__

#include <locale>
#include "string/string.h"

// Comparaison function for version numbers
// Implementation is based on dpkg's version comparison code (verrevcmp() and order())
// http://anonscm.debian.org/gitweb/?p=dpkg/dpkg.git;a=blob;f=lib/dpkg/version.c;hb=74946af470550a3295e00cf57eca1747215b9311
inline int char_weight(char c){
	if (std::isdigit(c))
		return 0;
	else if (std::isalpha(c))
		return c;
	else if (c == '~')
		return -1;
	else if (c)
		return c + 256;
	else
		return 0;
}

inline int DpkPakVersionCmp(const char* a, const char* b){
	while (*a || *b) {
		int firstDiff = 0;

		while ((*a && !std::isdigit(*a)) || (*b && !std::isdigit(*b))) {
			int ac = char_weight(*a);
			int bc = char_weight(*b);

			if (ac != bc)
				return ac - bc;

			a++;
			b++;
		}

		while (*a == '0')
			a++;
		while (*b == '0')
			b++;

		while (std::isdigit(*a) && std::isdigit(*b)) {
			if (firstDiff == 0)
				firstDiff = *a - *b;
			a++;
			b++;
		}

		if (std::isdigit(*a))
			return 1;
		if (std::isdigit(*b))
			return -1;
		if (firstDiff)
			return firstDiff;
	}

	return false;
}

// release strings after using
inline bool DpkReadDepsLine( const char *line, char **pakname, char **pakversion ){
	const char* c = line;
	const char* p_name;
	const char* p_name_end;
	const char* p_version;
	const char* p_version_end;

	*pakname = 0;
	*pakversion = 0;

	while ( std::isspace( *c ) && *c != '\0' ) ++c;
	p_name = c;
	while ( !std::isspace( *c ) && *c != '\0' ) ++c;
	p_name_end = c;
	while ( std::isspace( *c ) && *c != '\0' ) ++c;
	p_version = c;
	while ( !std::isspace( *c ) && *c != '\0' ) ++c;
	p_version_end = c;

	if ( p_name_end - p_name > 0 ){
		*pakname = string_clone_range( StringRange( p_name, p_name_end ) );
	} else return false;

	if ( p_version_end - p_version > 0 ) {
		*pakversion = string_clone_range( StringRange( p_version, p_version_end ) );
	}
	return true;
}

#endif
