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

namespace U.StringOperations
{
    public class Str
    {
        // Enum
        public enum Delimiter { Comma, Semicolon, Tab, Space, Plus, Dash, Colon, NewLine, Slash }
        public enum ParenthesisTypes { Regular, Square, Braces }
        public static string getOpenParenthesis(ParenthesisTypes parenthesis)
        {
            switch (parenthesis)
            {
                case ParenthesisTypes.Regular: return "(";
                case ParenthesisTypes.Square: return "[";
                case ParenthesisTypes.Braces: return "{";
            }
            return String.Empty;
        }
        public static string getCloseParenthesis(ParenthesisTypes parenthesis)
        {
            switch (parenthesis)
            {
                case ParenthesisTypes.Regular: return ")";
                case ParenthesisTypes.Square: return "]";
                case ParenthesisTypes.Braces: return "}";
            }
            return String.Empty;
        }


        // Type
        public static bool isNumeric(string str) { return TypeOp.isNumeric(str); }
        public static bool isInteger(string str) { return TypeOp.isInteger(str); }
        public static double toDouble(string str) { return TypeOp.toDouble(str); }
        public static int toInt(string str) { return Convert.ToInt32(str); }
        public static string toString(double dbl, string format) { return TypeOp.toString(dbl, format); }
        public static List<string> toString(List<double> lstDbl, string format) { return TypeOp.toString(lstDbl, format); }
        public static string[] toString(double[] arrDbl, string format) { return TypeOp.toString(arrDbl, format); }
        

        // Time
        public static string getDateTimeString(DateTime dateTime) { return Time.getDateTimeString(dateTime); }
        public static string getDateTimeString(DateTime dateTime, bool year, bool month, bool day, bool hour, bool minute, bool second) { return Time.getDateTimeString(dateTime, year, month, day, hour, minute, second); }

        // Delimit
        public static List<string> split(string str, Str.Delimiter delimiter) { return Delimit.split(delimiter, str); }
        public static List<string> split(string str, Str.Delimiter delimiter1, Str.Delimiter delimiter2) { return Delimit.split(delimiter1, delimiter2, str); }

        public static string combine(string str1, string str2, Str.Delimiter delimiter) { return Delimit.combine(str1, str2, delimiter); }
        public static string combine(string str1, string str2, string delimiter) { return str1 + delimiter + str2; }
        public static string combine(List<string> listStr, Str.Delimiter delimiter) { return Delimit.combine(listStr, delimiter); }
        public static string combine(List<double> listDbl, Str.Delimiter delimiter) { return Delimit.combine(listDbl, delimiter); }
        public static string combine(List<double> listDbl, string format, Str.Delimiter delimiter) { return Delimit.combine(listDbl, format, delimiter); }
        public static string combine(string[] arrStr, Str.Delimiter delimiter) { return Delimit.combine(arrStr, delimiter); }
        public static string combine(double[] arrDbl, Str.Delimiter delimiter) { return Delimit.combine(arrDbl, delimiter); }
        public static string combine(int[] arrInt, Str.Delimiter delimiter) { return Delimit.combine(arrInt, delimiter); }
        public static string combine(double[] arrDbl, string format, Str.Delimiter delimiter) { return Delimit.combine(arrDbl, format, delimiter); }

        public static string combine<T>(List<T> list, Str.Delimiter delimiter) { return combine(toString<T>(list), delimiter); }
        public static string combine(List<string> listStr, string delimiter) { string combined = listStr[0]; for (int i = 1; i < listStr.Count; i++) { combined = Str.combine(combined, listStr[i], delimiter); } return combined; }
        public static List<string> combine(List<List<double>> tableDbl, Str.Delimiter delimiter) { return Delimit.combine(tableDbl, delimiter); }
        public static List<string> combine(List<List<string>> tableDbl, Str.Delimiter delimiter) { return Delimit.combine(tableDbl, delimiter); }

        // D0
        public static int len(string str) { return str.Length; }
        public static string toUpper(string str) { return str.ToUpper(); }
        public static string toLower(string str) { return str.ToLower(); }
        public static string left(string str, int nbChars) { return D0.left(str,nbChars); }
        public static string right(string str, int nbChars) { return D0.right(str, nbChars); }
        public static string mid(string str, int start) { return str.Substring(start); }
        public static string mid(string str, int start, int length) { return str.Substring(start, length); }
        public static bool startsWith(string str, string startsWith) { return D0.startsWith(str, startsWith); }
        public static string readAfter(string str, string after) { return D0.readAfter(str, after); }
        public static string readUntil(string str, string until) { return D0.readUntil(str, until); }
        public static bool contains(string str, string contains) { return D0.contains(str, contains); }
        public static string trim(string str) { return D0.trim(str); }
        public static string getFuncName(string str) { return D0.getFuncName(str, ParenthesisTypes.Regular); }
        public static string getFuncName(string str, ParenthesisTypes parenthesisType) { return D0.getFuncName(str, parenthesisType); }
        public static string getInsideParenthesis(string str, ParenthesisTypes parenthesisType) { return D0.getInsideParenthesis(str, parenthesisType); }
        public static List<string> getArguments(string str, ParenthesisTypes parenthesisType, Delimiter delimiter) { return D0.getArguments(str, parenthesisType, delimiter); }

        // inParenthesis
        public static string inParenthesis(string str, ParenthesisTypes type) { return getOpenParenthesis(type) + str + getCloseParenthesis(type); }
        public static string inParenthesis(List<string> lst, ParenthesisTypes type, Delimiter delimiter) { return inParenthesis(combine(lst, delimiter), type); }
        public static string inParenthesis<T>(T obj, ParenthesisTypes type) { return inParenthesis(obj.ToString(), type); }
        public static string inParenthesis<T>(List<T> lst, ParenthesisTypes type, Delimiter delimiter) { return inParenthesis(combine(lst, delimiter), type); }
        //public static string inParenthesis(object obj, ParenthesisTypes type) { return inParenthesis(obj.ToString(), type); }

        

        public static string inApostrophe(string str) { return "'" + str + "'"; }
        public static int findLastIndex(string str, string find) { return D0.findLastIndex(str, find); }
        public static string readUntilLast(string str, string until) { return D0.readUntilLast(str, until); }
        public static string removeQuotation(string str) { if (str.Length == 0) { return str; } if (str.Length == 1 && str == "\"") { return String.Empty; } string clear = str; if (left(clear, 1) == "\"") { clear = right(clear, clear.Length - 1); } if (right(clear, 1) == "\"") { clear = left(clear, clear.Length - 1); } return clear; }

        // D1
        public static List<string> toUpper(List<string> strD1) { List<string> arr = new List<string>(); foreach (string str in strD1) { arr.Add(Str.toUpper(str)); } return arr; }
        public static List<string> toLower(List<string> strD1) { List<string> arr = new List<string>(); foreach (string str in strD1) { arr.Add(Str.toLower(str)); } return arr; }
        public static bool isNumeric(List<string> strD1) { return D1.isNumeric(strD1); }
        public static bool isInteger(List<string> strD1) { return D1.isInteger(strD1); }
        public static List<double> toDouble(List<string> strD1) { return D1.toDouble(strD1); }
        public static List<int> toInt(List<string> strD1) { List<int> l = new List<int>(); foreach (string s in strD1) { l.Add(toInt(s)); } return l; }
        public static List<string> trim(List<string> strD1) { return D1.trim(strD1); }
        public static List<List<string>> split(List<string> strD1, Str.Delimiter delimiter) { return D1.split(strD1, delimiter); }
        public static List<string> toString<T>(List<T> list) { List<string> strList = new List<string>(); foreach (T obj in list) { strList.Add(obj.ToString()); } return strList; }
        public static List<string> removeQuotation(List<string> list) { List<string> clear = new List<string>(); foreach (string str in list) { clear.Add(removeQuotation(str)); } return clear; }
        

        // D2
        public static List<List<string>> toUpper(List<List<string>> strD2) { List<List<string>> arr = new List<List<string>>(); foreach (List<string> strD1 in strD2) { arr.Add(Str.toUpper(strD1)); } return arr; }
        public static List<List<string>> toLower(List<List<string>> strD2) { List<List<string>> arr = new List<List<string>>(); foreach (List<string> strD1 in strD2) { arr.Add(Str.toLower(strD1)); } return arr; }
        public static List<List<double>> toDouble(List<List<string>> strTable) { return D2.toDouble(strTable); }
        public static List<List<int>> toInt(List<List<string>> strTable) { List<List<int>> t = new List<List<int>>(); foreach (List<string> l in strTable) { t.Add(toInt(l)); } return t; }
        public static bool isProper(List<List<string>> table) { return D2.isProper(table); }
        public static bool isNumeric(List<List<string>> table) { return D2.isNumeric(table); }
        public static bool isInteger(List<List<string>> table) { return D2.isInteger(table); }
        public static List<List<string>> trim(List<List<string>> table) { return D2.trim(table); }
        public static List<List<string>> toList(string[,] matrix) { return D2.toList(matrix); }
        public static string[,] toArray(List<List<string>> table) { return D2.toArray(table); }
        public static string[,] transpose(string[,] matrix) { return D2.transpose(matrix); }
        public static List<List<string>> transpose(List<List<string>> table) { return D2.transpose(table); }
        public static List<List<string>> removeQuotation(List<List<string>> table) { List<List<string>> clear = new List<List<string>>(); foreach (List<string> list in table) { clear.Add(removeQuotation(list)); } return clear; }

        // DATETIME
        //public static string getStandardDateStr(DateTime date) { return date.ToString("yyyy-mm-dd"); }
        public static string getStandardDateStr(DateTime date) { return date.Year + "-" + date.Month.ToString("00") + "-" + date.Day.ToString("00"); }
        
        // JSON
        public static string toJson<T>(T obj) { return Json.toJson(obj); }
        public static T fromJson<T>(string strJson) { return Json.fromJson<T>(strJson); }

    }
}
