// str-split function
// --------------------------
/// Split a string by a given string into a list.
/// @access public
/// @group string utilities
/// @type String
/// @output List
/// @parameter String String

@function str-split($str, $separator) {
	// empty array/list
	$split-arr: ();
	// // first index of separator in str
	$index: str-index($str, $separator);
	// @debug $index;
	// loop through str
	@while $index != null {
		// get the substr from the first character to the separator
		$item: str-slice($str, 1, $index - 1);
		// push item to array
		$split-arr: append($split-arr, $item);
		// remove item and separator from str
		$str: str-slice($str, $index + 1);
		// find new index of separator
		$index: str-index($str, $separator);
	}
	// add the remaining str to list (the last item)
	$split-arr: append($split-arr, $str);

	@return $split-arr;
}

// str-splice function
// --------------------------
/// Split a string by a given string into a list.
/// @access public
/// @group string utilities
/// @alias str-split

@function str-splice($str, $separator) {
	@return str-split($str, $separator);
}

// str-replace function
// --------------------------
/// Split a string by a given string into a list.
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String String

// Make str replace accept lists.
@function str-replace($haystack, $needles, $replacers: "") {
	// Check if the $needle argument is a list and based of that
	// go through the list replace all instances.
	// Also check if both needle and haystack are lists. If the list are the same length,
	// All items in the haystack will be replaced with all items in the needles.

	@if length($needles) == 1 {
		$needles: list-to-str($needles);
	}
	@if length($replacers) == 1 {
		$replacers: list-to-str($replacers);
	}

	@if type-of($needles) == "list" and type-of($replacers) == "list" {
		@if length($needles) == length($replacers) {
			// Check if the $needle argument is a string or a list and based of that
			// go through the list or string to replace all instances.
			@for $i from 1 through length($needles) {
				@if str-contains($haystack, nth($needles, $i)) {
					$haystack: str-replace-func(
						$haystack,
						nth($needles, $i),
						nth($replacers, $i)
					);
				}
			}
		} @else {
			@if type-of($replacers) == "list" {
				$replacers: list-to-str($replacers);
			}
			@for $i from 1 through length($needles) {
				@if str-contains($haystack, nth($needles, $i)) {
					$haystack: str-replace-func($haystack, nth($needles, $i), $replacers);
				}
			}
			@return $haystack;
		}
		@return $haystack;
	}
	// If only the needle is a list, just replace all instance of the
	// strings in this list with the default replacer.
	@else if type-of($needles) == "list" {
		@each $needles in $needles {
			@if type-of($replacers) == "list" {
				$replacers: list-to-str($replacers);
			}
			$haystack: str-replace-func($haystack, $needles, $replacers);
		}
		@return $haystack;
	}
	// If $needle and haystack are normal strings, just find the needles
	// and replace those.
	@else {
		@return str-replace-func($haystack, $needles, $replacers);
	}
}

// str-replace-func function
// --------------------------
/// The actual replacing function used in str-replace
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

// The str replace function
@function str-replace-func($haystack, $needle, $replace: "") {
	// First make sure needle nor haystack are empty values;
	@if $needle == " " {
		$index: str-index($haystack, $needle);
		@if $index {
			@return str-slice($haystack, 1, $index - 1) + $replace +
				str-replace(
					str-slice($haystack, $index + str-length($needle)),
					$needle,
					$replace
				);
		}
	}

	@if type-of($haystack) == null or type-of($needle) == null {
		@return $haystack;
	} @else {
		// And check if the needle and haystack are actually strs, otherwise warn.
		@if type-of($haystack) == "string" and type-of($needle) == "string" {
			$index: str-index($haystack, $needle);
			@if $index {
				@return str-slice($haystack, 1, $index - 1) + $replace +
					str-replace(
						str-slice($haystack, $index + str-length($needle)),
						$needle,
						$replace
					);
			}
		}
		@if type-of($haystack) != "string" {
			@warn '#{$haystack}(#{type-of($haystack)}) is not a str.';
		}
		@if type-of($needle) != "string" {
			@warn '#{$needle}(#{type-of($needle)}) is not a str.';
		}
	}
	@return $haystack;
}

// to-strg function
// --------------------------
/// Convert a value to a string.
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

@function to-str($str) {
	// Check if the value is already a string, if so just return the value
	@if type-of($str) == "string" {
		@return $str;
	}
	// Check if the value will become a string, if you put it in quotes.
	@else if type-of("#{$str}") == "string" {
		@return "#{$str}";
	} @else if $str == false {
		@return "false";
	} @else if $str == true {
		@return "false";
	}
	// If it still won't be a string, just try to throw it back.
	@else {
		@return "#{$str}";
	}
}

@function str-contains($haystack, $needle) {
	@if str-index($haystack, $needle) !=
		null and
		str-index($haystack, $needle) !=
		"" and
		type-of(str-index($haystack, $needle)) !=
		null
	{
		@return true;
	} @else {
		@return false;
	}
}

// dasherize function
// --------------------------
/// Convert a string which can be used as slug
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

@function dasherize($str) {
	$str: str-replace($str, " ", "-");
	$str: str-replace($str, " ", "-");
	$str: allowed-characters(
		to-lower-case(safe-characters($str)),
		("a-z", "0-9", "-")
	);
	@return $str;
}

// dasherize function
// --------------------------
/// Convert a string and remove special characters. Replace spaces with underscores.
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

@function underscore($str) {
	@return str-replace-func(dasherize($str), "-", "_");
}

// letter-uppercase function
// --------------------------
/// Uppercase one letter in a string, by default the first one.
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

@function letter-uppercase($str, $letter: 1) {
	$new-str: ();
	@if $letter > 1 {
		$new-str: append($new-str, str-slice($str, 1, $letter));
		$new-str: append($new-str, to-upper-case(str-slice($str, $letter, 1)));
		$new-str: append($new-str), str-slice($str, $letter + 1, str-length($str));
	} @else {
		$new-str: append($new-str, to-upper-case(str-slice($str, 1, 1)));
		$new-str: append($new-str, str-slice($str, 2, str-length($str)));
	}
	@return list-to-str($new-str, null);
}

// letter-uppercase function
// --------------------------
/// Uppercase one letter in a string, by default the first one.
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

@function letter-lowercase($str, $letter: 1) {
	$new-str: ();
	@if $letter > 1 {
		$new-str: append($new-str, str-slice($str, 1, $letter));
		$new-str: append($new-str, to-lower-case(str-slice($str, $letter, 1)));
		$new-str: append($new-str), str-slice($str, $letter + 1, str-length($str));
	} @else {
		$new-str: append($new-str, to-lower-case(str-slice($str, 1, 1)));
		$new-str: append($new-str, str-slice($str, 2, str-length($str)));
	}
	@return list-to-str($new-str, null);
}

// str-remove-whitespace function
// --------------------------
/// Removes all whitespaces from string
/// @access public
/// @group string utilities
/// @type String
/// @output String
/// @parameter String

@function str-remove-whitespace($str) {
  @while (str-index($str, ' ') != null) {
    $index: str-index($str, ' ');
    $str: "#{str-slice($str, 0, $index - 1)}#{str-slice($str, $index + 1)}";
  }
  @return $str;
}
