using NcProgramManager;

namespace NcProgramManager.Cnc.Fanuc
{
    internal static class FanucDialectDetector
    {
        public static FanucCapabilities Detect(ushort hndl)
        {
            var sys = new Focas1.ODBSYS();
            short ret = Focas1.cnc_sysinfo(hndl, sys);
            if (ret != Focas1.EW_OK)
            {
                return new FanucCapabilities
                {
                    CncType = "??",
                    ModelLetter = '?',
                    Dialect = FanucDialect.Unknown
                };
            }

            string cncType = new string(sys.cnc_type ?? new char[] { '?', '?' });
            char modelLetter = ModelLetterFrom(sys.addinfo);
            bool isI = (sys.addinfo & 0x02) != 0;
            FanucDialect dialect = DialectFor(cncType, modelLetter);

            bool modern = dialect == FanucDialect.Modern;
            return new FanucCapabilities
            {
                CncType = cncType,
                ModelLetter = modelLetter,
                IsISeries = isI,
                Series = sys.series != null ? new string(sys.series) : "",
                Version = sys.version != null ? new string(sys.version) : "",
                MtType = sys.mt_type != null ? new string(sys.mt_type) : "",
                MaxAxis = sys.max_axis,
                Dialect = dialect,
                SupportsUpDownload4 = modern,
                SupportsAlmMsg2 = modern,
                SupportsPathBasedPrograms = modern,
                SupportsPdfProgramApi = modern
            };
        }

        private static char ModelLetterFrom(short addinfo)
        {
            int model = (addinfo >> 8) & 0xFF;
            switch (model)
            {
                case 1: return 'A';
                case 2: return 'B';
                case 3: return 'C';
                case 4: return 'D';
                case 6: return 'F';
                default: return ' ';
            }
        }

        private static FanucDialect DialectFor(string cncType, char modelLetter)
        {
            if (string.IsNullOrEmpty(cncType)) return FanucDialect.Unknown;

            string t = cncType;
            string trimmed = cncType.Trim();

            if (trimmed == "30" || trimmed == "31" || trimmed == "32" || trimmed == "35")
                return FanucDialect.Modern;

            if (trimmed == "PM")
                return FanucDialect.Modern;

            if (trimmed == "0" || t == " 0")
            {
                if (modelLetter == 'D' || modelLetter == 'F') return FanucDialect.Modern;
                return FanucDialect.Legacy;
            }

            if (trimmed == "15" || trimmed == "16" || trimmed == "18" || trimmed == "21")
                return FanucDialect.Legacy;

            if (trimmed == "PD" || trimmed == "PH")
                return FanucDialect.Legacy;

            return FanucDialect.Unknown;
        }
    }
}
