Utils
using Autodesk.DesignScript.Runtime;
using System;
using System.Globalization;
using System.Text.RegularExpressions;
namespace DynamoUnits
{
    [SupressImportIntoVM]
    [Obsolete("This class will be removed in Dynamo 3.0 - - please use the Unit.Utilities class and associated methods")]
    public class Utils
    {
        private const int ROUND_DIGITS = 5;
        private const double EPSILON = 1E-05;
        public static string ParseWholeInchesToString(double value)
        {
            double double = (value < 0) ? Math.Abs(Math.Ceiling(value)) : Math.Abs(Math.Floor(value));
            if (double.AlmostEquals(0, 1E-05))
                return "";
            return double.ToString();
        }
        public static string ParsePartialInchesToString(double value, double precision)
        {
            return (value < 0) ? CreateFraction(Math.Abs(value - Math.Ceiling(value)), 0.015625) : CreateFraction(Math.Abs(value - Math.Floor(value)), 0.015625);
        }
        public static string CreateFraction(double value, double precision)
        {
            double num = 0;
            num = Math.Round(value / precision);
            double num2 = 1 / precision;
            if (num.AlmostEquals(num2, 1E-05))
                return "1";
            if (num != 0) {
                while (num % 2 == 0) {
                    num /= 2;
                    num2 /= 2;
                }
                return $"{num}""{num2}";
            }
            return "";
        }
        private static double RoundToSignificantDigits(double d, int digits)
        {
            if (d == 0)
                return 0;
            double num = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(d))) + 1);
            return num * Math.Round(d / num, digits);
        }
        public static double ParseUnit(string value, string unitSymbol)
        {
            if (value.ToLower().Contains(unitSymbol))
                value = value.Replace(unitSymbol, "");
            if (!double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out double result))
                return 0;
            return result;
        }
        public static double FromFeetAndFractionalInches(string value)
        {
            double num = 0;
            ParseLengthFromString(value.ToString(), out double feet, out double inch, out double _, out double _, out double _, out double numerator, out double denominator);
            if (denominator != 0)
                num = numerator / denominator;
            double num2 = 1;
            if (value.StartsWith("-"))
                num2 *= -1;
            if (feet < 0)
                return feet - inch / 12 - num / 12;
            return feet + inch / 12 + num / 12;
        }
        public static string ToFeetAndFractionalInches(double decimalFeet)
        {
            double num = 0;
            double num2 = 0;
            if (decimalFeet < 0) {
                num = Math.Ceiling(decimalFeet);
                num2 = ((num != 0) ? (num - decimalFeet) : decimalFeet);
            } else {
                num = Math.Floor(decimalFeet);
                num2 = decimalFeet - num;
            }
            string text = ToFractionalInches(Math.Round(num2 * 12, 5));
            switch (text) {
            case "11 1\"":
            case "12\"":
                num += 1;
                text = "0\"";
                break;
            case "-11 1\"":
            case "-12\"":
                num -= 1;
                text = "0\"";
                break;
            }
            string arg = "";
            if (num != 0)
                arg = $"{num}""";
            if (num.AlmostEquals(0, 1E-05) && (num2 * 12).AlmostEquals(0, 1E-05))
                arg = "0'";
            return $"{arg}""{text}".Trim();
        }
        public static string ToFractionalInches(double decimalInches)
        {
            decimalInches = RoundToSignificantDigits(decimalInches, 5);
            string text = ParseWholeInchesToString(decimalInches);
            string text2 = ParsePartialInchesToString(decimalInches, 0.015625);
            string arg = (decimalInches < 0) ? "-" : "";
            if (string.IsNullOrEmpty(text) && string.IsNullOrEmpty(text2))
                return "0\"";
            if (string.IsNullOrEmpty(text2))
                return $"{arg}{text}""".Trim();
            if (string.IsNullOrEmpty(text))
                return $"{arg}{text2}""".Trim();
            if (text2 == "1") {
                text2 = "";
                text = (double.Parse(text) + 1).ToString(CultureInfo.InvariantCulture);
                return $"{arg}{text}""".Trim();
            }
            return $"{arg}{text}""{text2}""".Trim();
        }
        public static string ToFeetAndDecimalInches(double decimalFeet)
        {
            double num = 0;
            double num2 = 0;
            if (decimalFeet < 0) {
                num = Math.Ceiling(decimalFeet);
                num2 = ((num != 0) ? (num - decimalFeet) : decimalFeet);
            } else {
                num = Math.Floor(decimalFeet);
                num2 = decimalFeet - num;
            }
            string str = Math.Round(num2 * 12, 5).ToString(BaseUnit.GeneralNumberFormat, CultureInfo.InvariantCulture);
            if (num2.AlmostEquals(1, 1E-05)) {
                num += 1;
                str = "0";
            } else if (num2.AlmostEquals(-1, 1E-05)) {
                num -= 1;
                str = "0";
            }
            string arg = "";
            if (num != 0)
                arg = $"{num}""";
            if (num.AlmostEquals(0, 1E-05) && (num2 * 12).AlmostEquals(0, 1E-05))
                arg = "0'";
            str += "\"";
            return $"{arg}""{str}".Trim();
        }
        public static bool ParseLengthInFeetFromString(string value, out double feet, out double numerator, out double denominator)
        {
            string pattern = "(\\A((?<ft>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?))\\Z)|(\\A(?<ft>(?<num>(\\+|-)?\\d+)/(?<den>\\d+)*( ?)('|ft)?)\\Z)";
            feet = 0;
            numerator = 0;
            denominator = 0;
            Regex regex = new Regex(pattern, RegexOptions.None);
            Match match = regex.Match(value.Trim().ToLower());
            if (match.Success) {
                double.TryParse(match.Groups["ft"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out feet);
                double.TryParse(match.Groups["num"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out numerator);
                double.TryParse(match.Groups["den"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out denominator);
                return true;
            }
            return false;
        }
        public static void ParseLengthFromString(string value, out double feet, out double inch, out double m, out double cm, out double mm, out double numerator, out double denominator)
        {
            string pattern = "(((?<ft>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)('|ft))*\\s*((?<in>(?<num>(\\+|-)?\\d+)/(?<den>\\d+)*( ?)(\"|in))|(?<in>(?<wholeInch>(\\+|-)?\\d{1,}?)(\\s|-)*(?<num>(\\+|-)?\\d+)/(?<den>\\d+)*( ?)(\"|in))|(?<in>(?<wholeInch>(\\+|-)?\\d+([.,]\\d{1,})?)( ?)(\"|in)))?)*((?<m>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)m($|\\s))*((?<cm>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)cm($|\\s))*((?<mm>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)mm($|\\s))*";
            feet = 0;
            inch = 0;
            m = 0;
            cm = 0;
            mm = 0;
            numerator = 0;
            denominator = 0;
            Regex regex = new Regex(pattern, RegexOptions.None);
            Match match = regex.Match(value.Trim().ToLower());
            if (match.Success) {
                double.TryParse(match.Groups["ft"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out feet);
                double.TryParse(match.Groups["wholeInch"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out inch);
                double.TryParse(match.Groups["num"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out numerator);
                double.TryParse(match.Groups["den"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out denominator);
                double.TryParse(match.Groups["m"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out m);
                double.TryParse(match.Groups["cm"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cm);
                double.TryParse(match.Groups["mm"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out mm);
            }
        }
        public static void ParseAreaFromString(string value, out double square_inch, out double square_foot, out double square_millimeter, out double square_centimeter, out double square_meter)
        {
            square_inch = 0;
            square_foot = 0;
            square_millimeter = 0;
            square_centimeter = 0;
            square_meter = 0;
            Regex regex = new Regex("((?<square_inches>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(in2|sqin|in²))*\\s*((?<square_feet>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(ft2|sqft|ft²))*\\s*((?<square_millimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(mm2|sqmm|mm²))*\\s*((?<square_centimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(cm2|sqcm|cm²))*\\s*((?<square_meters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(m2|sqm|m²))*\\s*", RegexOptions.None);
            Match match = regex.Match(value.Trim().ToLower());
            if (match.Success) {
                double.TryParse(match.Groups["square_inches"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_inch);
                double.TryParse(match.Groups["square_feet"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_foot);
                double.TryParse(match.Groups["square_millimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_millimeter);
                double.TryParse(match.Groups["square_centimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_centimeter);
                double.TryParse(match.Groups["square_meters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out square_meter);
            }
        }
        public static void ParseVolumeFromString(string value, out double cubic_inch, out double cubic_foot, out double cubic_millimeter, out double cubic_centimeter, out double cubic_meter)
        {
            cubic_inch = 0;
            cubic_foot = 0;
            cubic_millimeter = 0;
            cubic_centimeter = 0;
            cubic_meter = 0;
            Regex regex = new Regex("((?<cubic_inches>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(in3|cuin|in³))*\\s*((?<cubic_feet>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(ft3|cuft|ft³))*\\s*((?<cubic_millimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(mm3|cumm|mm³))*\\s*((?<cubic_centimeters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(cm3|cucm|cm³))*\\s*((?<cubic_meters>((\\+|-)?\\d{0,}([.,]\\d{1,})?))( ?)(m3|cum|m³))*\\s*", RegexOptions.None);
            Match match = regex.Match(value.Trim().ToLower());
            if (match.Success) {
                double.TryParse(match.Groups["cubic_inches"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_inch);
                double.TryParse(match.Groups["cubic_feet"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_foot);
                double.TryParse(match.Groups["cubic_millimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_millimeter);
                double.TryParse(match.Groups["cubic_centimeters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_centimeter);
                double.TryParse(match.Groups["cubic_meters"].Value, NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out cubic_meter);
            }
        }
    }
}