/// String to List function
// --------------------------
/// Converts a string into a list breaking it apart by the `separator`
///
/// @access public
/// @group list utilities
///
/// @param {string} $string
/// @param {string} $separator
/// @param {number} $startAt
///
/// @return {list}
///

@function str-to-list($string, $separator: ".", $startAt: 1) {
	$string: str-replace($string, "__", "."); //
	$string: str-replace($string, "--", "."); //
	$string: str-replace($string, "_", "."); //

	$workStr: str-slice($string, $startAt);
	$list: ();
	$indexOfFirstSpace: str-index($workStr, $separator);
	@if $indexOfFirstSpace == null {
		$list: ($workStr);
	} @else {
		$list: (str-slice($workStr, 1, $indexOfFirstSpace - 1)); //
		$list: join(
			$list,
			str-to-list($workStr, $separator, $startAt: $indexOfFirstSpace + 1)
		);
	}
	@return $list;
}

/// Prepend function
// --------------------------
/// Add a string value to a list.
///
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {string} $value
/// @param {string} $separator
///
/// @return {list}
///

@function prepend($list, $value, $seperator: space) {
	@return join($value, $list, $seperator);
}

/// To String function
// --------------------------
/// Converts a list to a string.
///
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {string} $glue
/// @param {boolean} $is-nested
///
/// @return {string}
///

@function simple-to-string($list, $glue) {
	$str: null;
	@for $i from 1 through length($list) {
		@if $i == 1 {
			$str: nth($list, $i);
		} @else {
			$str: unquote("#{$str}#{$glue}#{nth($list,$i)}");
		}
	}
	@return $str;
}

@function to-string($list, $glue: "", $is-nested: false) {
	$result: null;

	@for $i from 1 through length($list) {
		$e: nth($list, $i);

		@if type-of($e) == list {
			$result: $result#{to-string($e, $glue, true)};
		} @else {
			$result: if(
				$i != length($list) or $is-nested,
				$result#{$e}#{$glue},
				$result#{$e}
			);
		}
	}

	@return $result;
}

/// To List function
// --------------------------
/// Simple function to convert a value into a list.
///
/// @access public
/// @group list utilities
/// @param {string} $value
/// @return {string}
///
@function to-list($value) {
	@return if(type-of($value) != list, ($value), $value);
}

/// List length function
// --------------------------
/// Get the length of a list
///
/// @access public
/// @group list utilities
/// @param {list} $list
/// @return {number}
///
@function list-length($list) {
	$length: 0;
	@each $item in $list {
		$length: $length + 1;
	}
	@return $length;
}

// List to String function
// --------------------------
/// Converts a (multi dimensional) list to a string.
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {string} $separator
/// @param {boolean} $last
/// @output list
///

@function list-to-str($list, $separator: ", ", $last: true) {
	$string: nth($list, 1);
	@if list-length($list) > 1 {
		@for $i from 2 through list-length($list) {
			$item: nth($list, $i);
			@if $i == list-length($list) + 1 {
				$string: #{$string}#{$item};
			} @else {
				$string: #{$string}#{$separator}#{$item};
			}
		}
	}
	@return $string;
}

// To Letter List function
// --------------------------
/// Returns a list with all letters of a string.
/// @access public
/// @group list utilities
///
/// @param {string} $string
/// @output list
///

@function to-letter-list($string) {
	$letters: ();
	@for $i from 1 through str-length($string) {
		$letters: append($letters, str-slice($string, $i, $i));
	}
	@return $letters;
}

// Shortests
// --------------------------
/// Returns the shortest list or string
/// @access public
/// @group list utilities
///
/// @param {list / string} $v1
/// @param {list / string}  $v2
/// @output list / string
///

@function shortest($v1, $v2) {
	@if type-of($v1) == type-of($v2) {
		@if type-of($v1) == "list" {
			@if length($v1) < length($v2) {
				@return $v1;
			} @else if length($v1) > length($v2) {
				@return $v2;
			} @else {
				@warn '#{$v1} (length #{length($v2)}) has the same length as #{$v2} (length #{length($v2)}), returned #{$v1}';
				@return $v1;
			}
		} @else if type-of($v1) == "string" {
			@if str-length($v1) < str-length($v2) {
				@return $v1;
			} @else if str-length($v1) > str-length($v2) {
				@return $v2;
			} @else {
				@warn '#{$v1} (length #{str-length($v2)}) has the same length as #{$v2} (length #{str-length($v2)}), returned #{$v1}';
				@return $v1;
			}
		}
	} @else {
		@warn 'Values do not have the same type.';
	}
}

// Remove Nth function
// --------------------------
/// Remove an item from a list at a certain index
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {number} $index
/// @output list
///

@function remove-nth($list, $index) {
	$result: null;

	@if type-of($index) != number {
		@warn "$index: #{quote($index)} is not a number for `remove-nth`.";
	} @else if $index == 0 {
		@warn "List index 0 must be a non-zero integer for `remove-nth`.";
	} @else if abs($index) > length($list) {
		@warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`.";
	} @else {
		$result: ();
		$index: if($index < 0, length($list) + $index + 1, $index);

		@for $i from 1 through length($list) {
			@if $i != $index {
				$result: append($result, nth($list, $i));
			}
		}
	}

	@return $result;
}

// Insert Nth function
// --------------------------
/// Inserts an item into a string at a certain index
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {number} $index
/// @param {string} $value
/// @output list
///

@function insert-nth($list, $index, $value) {
	$result: null;

	@if type-of($index) != number {
		@warn "$index: #{quote($index)} is not a number for `insert-nth`.";
	} @else if $index < 1 {
		@warn "List index 0 must be a non-zero integer for `insert-nth`";
	} @else if $index > length($list) {
		@warn "List index is #{$index} but list is only #{length($list)} item long for `insert-nth'.";
	} @else {
		$result: ();

		@for $i from 1 through length($list) {
			@if $i == $index {
				$result: append($result, $value);
			}

			$result: append($result, nth($list, $i));
		}
	}
	@return $result;
}

// Key Index function
// --------------------------
/// Returns the index of a item in a list
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {string} $item
/// @output Boolean
///

@function key-index($list, $item) {
	$i: 0;
	@each $key, $value in $list {
		@if $key == $item {
			@return $i;
		}
		$i: $i + 1;
	}
	@return -1;
}

// List contains function
// --------------------------
/// Check if a list contains a value
/// @access public
/// @group list utilities
///
/// @param {list} $list
/// @param {string} $string
/// @output Boolean
///

@function list-contains($list, $string) {
	@each $value in $list {
		@if $value == $string {
			@return true;
		}
	}
	@return false;
}
