package io.domisum.lib.auxiliumlib.util;

import io.domisum.lib.auxiliumlib.PHR;
import io.domisum.lib.auxiliumlib.annotations.API;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

@API
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class StringListUtil
{
	
	// HORIZONTALLY
	@API
	public static String listHorizontally(List<?> list, String delimiter)
	{
		var combined = new StringBuilder();
		for(int i = 0; i < list.size(); i++)
		{
			var element = list.get(i);
			boolean isLastElement = (i+1) == list.size();
			
			combined.append(element);
			combined.append(isLastElement ? "" : delimiter);
		}
		
		return combined.toString();
	}
	
	@API
	public static String listHorizontally(List<?> list)
	{
		return listHorizontally(list, ", ");
	}
	
	
	@API
	public static String listHorizontally(Collection<?> collection, String delimiter)
	{
		return listHorizontally(new ArrayList<>(collection), delimiter);
	}
	
	@API
	public static String listHorizontally(Collection<?> collection)
	{
		return listHorizontally(collection, ", ");
	}
	
	
	@API
	public static <T> String listHorizontally(Map<?, T> map, String delimiter, Function<T, Object> valueFunction)
	{
		var mappings = new ArrayList<String>();
		for(var entry : map.entrySet())
		{
			String mapping = PHR.r("'{}'->'{}'", entry.getKey(), valueFunction.apply(entry.getValue()));
			mappings.add(mapping);
		}
		mappings.sort(Comparator.naturalOrder());
		
		return listHorizontally(mappings, delimiter);
	}
	
	@API
	public static <T> String listHorizontally(Map<?, T> map, Function<T, Object> valueFunction)
	{
		return listHorizontally(map, ", ", valueFunction);
	}
	
	
	@API
	public static String listHorizontally(Map<?, ?> map, String delimiter)
	{
		return listHorizontally(map, delimiter, v->v);
	}
	
	@API
	public static String listHorizontally(Map<?, ?> map)
	{
		return listHorizontally(map, ", ");
	}
	
	
	// VERTICALLY
	@API
	public static String listVertically(List<?> list)
	{
		var itemDisplays = new ArrayList<String>();
		for(var item : list)
			itemDisplays.add(PHR.r(" - {}", item.toString()));
		
		return listHorizontally(itemDisplays, "\n");
	}
	
	@API
	public static String listVertically(Collection<?> collection)
	{
		return listVertically(new ArrayList<>(collection));
	}
	
	@API
	public static String listVertically(Map<?, ?> map)
	{
		var entryStrings = new ArrayList<String>();
		for(var entry : map.entrySet())
		{
			String entryString = "'"+entry.getKey()+"' -> '"+entry.getValue()+"'";
			entryStrings.add(entryString);
		}
		
		Collections.sort(entryStrings);
		return listVertically(entryStrings);
	}
	
}

@@ -476,16 +476,75 @@
 til%0A%7B%0A%09%0A
+%09private static final String DEFAULT_DELIMITER = %22, %22;%0A%09%0A%09%0A
 %09// HORI
@@ -564,32 +564,36 @@
 I%0A%09public static
+ %3CT%3E
  String listHori
@@ -610,16 +610,46 @@
 ist%3C
-?
+T
 %3E list,
+ Function%3CT, Object%3E function,
  Str
@@ -784,58 +784,83 @@
 %0A%09%09%09
-boolean isLastElement = (i+1) == list.size(
+var elementDisplay = function == null ? element : function.apply(element
 );%0A
-%09%09%09%0A
 %09%09%09c
@@ -873,32 +873,92 @@
 d.append(element
+Display);%0A%09%09%09%0A%09%09%09boolean isLastElement = (i+1) == list.size(
 );%0A%09%09%09combined.a
@@ -1063,85 +1063,396 @@
 tic 
-String listHorizontally(List%3C?%3E list)%0A%09%7B%0A%09%09return listHorizontally(list, %22, %22
+%3CT%3E String listHorizontally(List%3CT%3E list, Function%3CT, Object%3E function)%0A%09%7B%0A%09%09return listHorizontally(list, function, DEFAULT_DELIMITER);%0A%09%7D%0A%09%0A%09@API%0A%09public static String listHorizontally(List%3C?%3E list)%0A%09%7B%0A%09%09return listHorizontally(list, DEFAULT_DELIMITER);%0A%09%7D%0A%09%0A%09@API%0A%09public static String listHorizontally(List%3C?%3E list, String delimiter)%0A%09%7B%0A%09%09return listHorizontally(list, null, delimiter
 );%0A%09
@@ -1733,20 +1733,33 @@
 ection, 
-%22, %22
+DEFAULT_DELIMITER
 );%0A%09%7D%0A%09%0A
@@ -2319,20 +2319,33 @@
 ly(map, 
-%22, %22
+DEFAULT_DELIMITER
 , valueF
@@ -2590,20 +2590,33 @@
 ly(map, 
-%22, %22
+DEFAULT_DELIMITER
 );%0A%09%7D%0A%09%0A

Add function for StringListUtil list functions