/**
 *
 * @author Bastiaan Welmers
 *
 *
 */

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "str_replace.h"

/**
 *
 * Replace occurences of search in subject by replace.
 *
 * This function creates a new string for the result,even if no ocurrences 
 * of search are found in subject.
 * This string should be freed at the end of the program.
 *
 * @return pointer to new malloc'ed result string
 * @param const char* search - pointer to string where to search for
 * @param const char* replace - pointer to string with replacement of search
 * @param const char* subject - pointer to original string where to replace items 
 *
 */

char* str_replace(const char* search, const char* replace, const char* subject)
{
	
	unsigned int occurances = str_count(search, subject);
	if (occurances > 0)
	{
		unsigned int i;
		unsigned int newLen = strlen(subject) + occurances * (strlen(replace) - strlen(search));
		char* newString = malloc(sizeof(char) * (newLen  /* for teminating \0 byte */ + 1 ));
		
		char* newStringPos = newString;
		
		const char* strPlace = subject;
		const char* strPlacePrevious = subject;
		
		int searchLen = strlen(search);
		int replaceLen = strlen(replace);
		
		while (strPlace = strstr(strPlace, search))
		{
			// copy part to new string position until found search
			strncpy(newStringPos, strPlacePrevious, strPlace - strPlacePrevious);
			// move pointer
			newStringPos += strPlace - strPlacePrevious;
			//copy replacement
			strncpy(newStringPos, replace, replaceLen);
			// move pointer
			newStringPos += replaceLen;
			
			strPlace += searchLen;
			// keep track of privous pointer for next cycle
			
			strPlacePrevious = strPlace;
		}
		// copy last part of string
		strcpy(newStringPos, strPlacePrevious);
		
		// add string terminator
		++newStringPos;
		*newStringPos = 0;
		return newString;
	}
	char* newString = malloc(sizeof(char) * (strlen(subject) + 1));
	strcpy(newString, subject);
	return newString;
}

/**
 *
 * Count occurences of search in subject
 * @return unsigned int ammount of occurences
 * @param const char* search - pointer to string where to search for
 * @param const char* subject - pointer to string where to search in
 */

unsigned int str_count(const char* search, const char* subject)
{
	int count = 0;
	int len = strlen(search);
	const char* strPlace = subject;
	
	//find amount of indeces
	while (strPlace = strstr(strPlace, search))
	{
		strPlace += len;
		count++;
	}
	return count;
}

