using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace U.StringOperations
{
    class Delimit
    {
        public static string combine(string str1, string str2, Str.Delimiter delimiter) { if (delimiter == Str.Delimiter.NewLine) { return str1 + Environment.NewLine + str2; } return str1 + getStrDelimiter(delimiter) + str2; }

        // D1
        public static string combine(List<string> listStr, Str.Delimiter delimiter)
        {
            if (listStr.Count == 0) { return String.Empty; }
            if (listStr.Count == 1) { return listStr[0]; }
            string combined = listStr[0];
            for (int i = 1; i < listStr.Count; i++)
            {
                combined = Str.combine(combined, listStr[i], delimiter);
            }
            return combined;
        }
        public static string combine(List<double> listDbl, Str.Delimiter delimiter)
        {
            if (listDbl.Count < 1) { return String.Empty; }
            string combined = TypeOp.toString(listDbl[0]);
            if (listDbl.Count == 1) { return combined; }
            for (int i = 1; i < listDbl.Count; i++)
            {
                combined = Str.combine(combined, TypeOp.toString(listDbl[i]), delimiter);
            }
            return combined;
        }
        public static string combine(List<double> listDbl, string format, Str.Delimiter delimiter)
        {
            if (listDbl.Count < 1) { return String.Empty; }
            string combined = TypeOp.toString(listDbl[0], format);
            if (listDbl.Count == 1) { return combined; }
            for (int i = 1; i < listDbl.Count; i++)
            {
                combined = Str.combine(combined, TypeOp.toString(listDbl[i], format), delimiter);
            }
            return combined;
        }
        public static string combine(string[] arrDbl, Str.Delimiter delimiter)
        {
            if (arrDbl.Length == 0) { return String.Empty; }
            if (arrDbl.Length == 1) { return arrDbl[0]; }
            string combined = arrDbl[0];
            for (int i = 1; i < arrDbl.Length; i++)
            {
                combined = Str.combine(combined, arrDbl[i], delimiter);
            }
            return combined;
        }
        public static string combine(int[] arrInt, Str.Delimiter delimiter)
        {
            if (arrInt.Length < 1) { return String.Empty; }
            string combined = TypeOp.toString(arrInt[0]);
            if (arrInt.Length == 1) { return combined; }
            for (int i = 1; i < arrInt.Length; i++)
            {
                combined = Str.combine(combined, TypeOp.toString(arrInt[i]), delimiter);
            }
            return combined;
        }
        public static string combine(double[] arrDbl, Str.Delimiter delimiter)
        {
            if (arrDbl.Length < 1) { return String.Empty; }
            string combined = TypeOp.toString(arrDbl[0]);
            if (arrDbl.Length == 1) { return combined; }
            for (int i = 1; i < arrDbl.Length; i++)
            {
                combined = Str.combine(combined, TypeOp.toString(arrDbl[i]), delimiter);
            }
            return combined;
        }
        public static string combine(double[] arrDbl, string format, Str.Delimiter delimiter)
        {
            if (arrDbl.Length < 1) { return String.Empty; }
            string combined = TypeOp.toString(arrDbl[0], format);
            if (arrDbl.Length == 1) { return combined; }
            for (int i = 1; i < arrDbl.Length; i++)
            {
                combined = Str.combine(combined, TypeOp.toString(arrDbl[i], format), delimiter);
            }
            return combined;
        }


        // D2
        public static List<string> combine(List<List<double>> table, Str.Delimiter delimiter)
        {
            List<string> list = new List<string>();
            foreach (List<double> listDbl in table)
            {
                list.Add(Str.combine(listDbl, delimiter));
            }
            return list;
        }
        public static List<string> combine(List<List<string>> table, Str.Delimiter delimiter)
        {
            List<string> list = new List<string>();
            foreach (List<string> listDbl in table)
            {
                list.Add(Str.combine(listDbl, delimiter));
            }
            return list;
        }

        
        public static List<string> split(Str.Delimiter delimiter, string str)
        {
            List<string> list = str.Split(getStrDelimiter(delimiter)).ToList();
            list = Str.trim(list);
            for (int i = 0; i < list.Count; i++)
            {
                if (list[i].Equals(String.Empty))
                {
                    list.RemoveAt(i); i = i - 1;
                }
            }
            return Str.trim(list);
        }
        public static List<string> split(Str.Delimiter delimiter1, Str.Delimiter delimiter2, string str)
        {
            List<string> list = new List<string>();
            List<string> list1 = Str.split(str, delimiter1);
            foreach (string str1 in list1)
            {
                List<string> list2 = Str.split(str1, delimiter2);
                list.AddRange(list2);
            }
            return list;
        }

        public static char getStrDelimiter(Str.Delimiter delimiter)
        {
            switch (delimiter)
            {
                case Str.Delimiter.Comma: return ',';
                case Str.Delimiter.Semicolon: return ';';
                case Str.Delimiter.Tab: return '\t';
                case Str.Delimiter.Space: return ' ';
                case Str.Delimiter.Dash: return '-';
                case Str.Delimiter.Plus: return '+';
                case Str.Delimiter.Colon: return ':';
                case Str.Delimiter.NewLine: return '\n';
                case Str.Delimiter.Slash: return '/';
                default: return 'z';
            }
        }
    }
}
