/// <summary>
        /// Takes a 6-character string gridsquare and processes it using LookupTablesHelper and GridsquareHelper to return a DDMCoordinate object.
        /// If solution cannot be found a null DDMCoordinate type is returned.
        /// </summary>
        /// <param name="gridsquare"></param>
        /// <returns></returns>
        public DDMCoordinate ConvertGridsquareToDDM(string gridsquare)
        {
            DDMCoordinate DdmResult = null;

            if (!string.IsNullOrEmpty(gridsquare) && !string.IsNullOrWhiteSpace(gridsquare))
            {
                if (LookuptablesHelper.GenerateTableLookups() && GridsquareHelper.ValidateGridsquareInput(gridsquare, out string validGridsquare))
                {
                    decimal tempLatDegrees          = ConversionHelper.GetLatDegrees(LookuptablesHelper, validGridsquare, out short latDirection);
                    decimal latDegreesWithRemainder = ConversionHelper.AddLatDegreesRemainder(tempLatDegrees, latDirection, validGridsquare);
                    decimal DDMlatMinutes           = ConversionHelper.GetLatMinutes(
                        LookuptablesHelper, latDegreesWithRemainder, latDirection, validGridsquare, out decimal adjustedLatDegrees);

                    decimal tempLonDegrees          = ConversionHelper.GetLonDegrees(LookuptablesHelper, validGridsquare, out short lonDirection);
                    decimal lonDegreesWithRemainder = ConversionHelper.AddLonDegreesRemainder(tempLonDegrees, lonDirection, validGridsquare);
                    decimal DDMlonMinutes           = ConversionHelper.GetLonMinutes(
                        LookuptablesHelper, lonDegreesWithRemainder, lonDirection, validGridsquare, out decimal adjustedLonDegrees);

                    DdmResult = new DDMCoordinate(
                        adjustedLatDegrees, DDMlatMinutes,
                        adjustedLonDegrees, DDMlonMinutes);
                }
            }

            return(DdmResult);
        }
        public void DmsToDDM_SW_Test()
        {
            var mvcm = new MontevideoCoordinateModel();
            var ddm  = new DDMCoordinate(
                mvcm.ShortDegreesLattitude(), mvcm.DdmMinsLat, mvcm.DmsSecondsLat,
                mvcm.ShortDegreesLongitude(), mvcm.DdmMinsLon, mvcm.DmsSecondsLon
                );
            string expectedResult = MontevideoCoordinateModel.StrDDM();
            int    expectedLength = expectedResult.Length;

            string actualResult = ddm.ToString();
            int    actualLength = actualResult.Length;

            decimal latDiff = Math.Abs(ddm.GetShortDegreesLat() - Math.Truncate(mvcm.DegreesLat));
            decimal lonDiff = Math.Abs(ddm.GetShortDegreesLon() - Math.Truncate(mvcm.DegreesLon));

            decimal latMinsDiff = Math.Abs(ddm.GetMinsLat() - mvcm.DdmMinsLat);
            decimal lonMinsDiff = Math.Abs(ddm.GetMinsLon() - mvcm.DdmMinsLon);

            var dict = new Dictionary <string, decimal>
            {
                { "latDiff", latDiff },
                { "lonDiff", lonDiff },
                { "latMinsDiff", latMinsDiff },
                { "lonMinsDiff", lonMinsDiff }
            };

            DisplayOutput(expectedResult, actualResult, dict);

            Assert.AreEqual(expectedLength, actualLength);
            Assert.IsTrue(latDiff >= 0 && latDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(latMinsDiff >= 0 && latMinsDiff <= LatMinsAccuracyThreshold);
            Assert.IsTrue(lonDiff >= 0 && lonDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(lonMinsDiff >= 0 && lonMinsDiff <= LonMinsAccuracyThreshold);
        }
        public void CTOR_DDM_Test()
        {
            var     mvcm       = new MontevideoCoordinateModel();
            decimal latDegrees = mvcm.DegreesLat;
            decimal latMins    = mvcm.DdmMinsLat;
            decimal lonDegrees = mvcm.DegreesLon;
            decimal lonMins    = mvcm.DdmMinsLon;

            var ddm = new DDMCoordinate(latDegrees, latMins, lonDegrees, lonMins);

            string expectedResult = MontevideoCoordinateModel.StrDDM();
            string actualResult   = ddm.ToString();

            decimal latDiff = Math.Abs(ddm.GetShortDegreesLat() - Math.Truncate(mvcm.DegreesLat));
            decimal lonDiff = Math.Abs(ddm.GetShortDegreesLon() - Math.Truncate(mvcm.DegreesLon));

            decimal latMinsDiff = Math.Abs(ddm.GetMinsLat() - mvcm.DdmMinsLat);
            decimal lonMinsDiff = Math.Abs(ddm.GetMinsLon() - mvcm.DdmMinsLon);

            var dict = new Dictionary <string, decimal>
            {
                { "latDiff", latDiff },
                { "lonDiff", lonDiff },
                { "latMinsDiff", latMinsDiff },
                { "lonMinsDiff", lonMinsDiff }
            };

            DisplayOutput(expectedResult, actualResult, dict);

            Assert.IsTrue(latDiff >= 0 && latDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(latMinsDiff >= 0 && latMinsDiff <= LatMinsAccuracyThreshold);

            Assert.IsTrue(lonDiff >= 0 && lonDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(lonMinsDiff >= 0 && lonMinsDiff <= LonMinsAccuracyThreshold);
        }
        public void DdToDDM_NW_Test()
        {
            var sccm = new SanClementeCoordinatesModel();
            var ddm  = new DDMCoordinate(
                sccm.DegreesLat, sccm.DegreesLon
                );
            string expectedResult = SanClementeCoordinatesModel.StrDDM();
            int    expectedLength = expectedResult.Length;

            string actualResult = ddm.ToString();
            int    actualLength = actualResult.Length;

            decimal latDiff = Math.Abs(ddm.GetShortDegreesLat() - Math.Truncate(sccm.DegreesLat));
            decimal lonDiff = Math.Abs(ddm.GetShortDegreesLon() - Math.Truncate(sccm.DegreesLon));

            decimal latMinsDiff = Math.Abs(ddm.GetMinsLat() - sccm.DdmMinsLat);
            decimal lonMinsDiff = Math.Abs(ddm.GetMinsLon() - sccm.DdmMinsLon);

            var dict = new Dictionary <string, decimal>
            {
                { "latDiff", latDiff },
                { "lonDiff", lonDiff },
                { "latMinsDiff", latMinsDiff },
                { "lonMinsDiff", lonMinsDiff }
            };

            DisplayOutput(expectedResult, actualResult, dict);

            Assert.AreEqual(expectedLength, actualLength);
            Assert.IsTrue(latDiff >= 0 && latDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(latMinsDiff >= 0 && latMinsDiff <= LatMinsAccuracyThreshold);
            Assert.IsTrue(lonDiff >= 0 && lonDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(lonMinsDiff >= 0 && lonMinsDiff <= LonMinsAccuracyThreshold);
        }
        public void ConvertGridsquareToDDMTestSW()
        {
            var    cc         = new GridDdmExpert();
            string gridsquare = WellingtonCoordinateModel.StrGridsquare();

            var           expectedResult = new DDMCoordinate(WellingtonCoordinateModel.StrAttainableDDM());
            DDMCoordinate actualResult   = cc.ConvertGridsquareToDDM(gridsquare);

            decimal latDiff = Math.Abs(expectedResult.GetShortDegreesLat() - actualResult.GetShortDegreesLat());
            decimal lonDiff = Math.Abs(expectedResult.GetShortDegreesLon() - actualResult.GetShortDegreesLon());

            decimal latMinsDiff = Math.Abs(expectedResult.GetMinsLat() - actualResult.GetMinsLat());
            decimal lonMinsDiff = Math.Abs(expectedResult.GetMinsLon() - actualResult.GetMinsLon());

            var dict = new Dictionary <string, decimal>
            {
                { "latDiff", latDiff },
                { "lonDiff", lonDiff },
                { "latMinsDiff", latMinsDiff },
                { "lonMinsDiff", lonMinsDiff }
            };

            DisplayOutput(expectedResult.ToString(), actualResult.ToString(), dict);

            Assert.IsTrue(latDiff >= 0 && latDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(latMinsDiff >= 0 && latMinsDiff <= LatMinsAccuracyThreshold);

            Assert.IsTrue(lonDiff >= 0 && lonDiff <= DegreeAccuracyThreshold);
            Assert.IsTrue(lonMinsDiff >= 0 && lonMinsDiff <= LonMinsAccuracyThreshold);
        }
        public void DefaultCTOR_Test()
        {
            var ddmCoord = new DDMCoordinate();

            bool expectedResult = true;
            bool actualResult   = ddmCoord.GetType().FullName == "CoordinateConversionLibrary.Models.DDMCoordinate";

            Assert.IsTrue(expectedResult == actualResult);
        }
        public void IsValid_InvalidLon_Test()
        {
            decimal lattitude      = 90.0m;
            decimal longitude      = -181.0m;
            bool    expectedResult = false;

            var  ddm          = new DDMCoordinate(lattitude, longitude);
            bool actualResult = ddm.IsValid;

            Assert.AreEqual(expectedResult, actualResult);
        }
        public void IsValid_90_180_Passes_Test()
        {
            decimal lattitude      = 90.0m;
            decimal longitude      = 180.0m;
            bool    expectedResult = true;

            var  ddm          = new DDMCoordinate(lattitude, longitude);
            bool actualResult = ddm.IsValid;

            Assert.AreEqual(expectedResult, actualResult);
        }
        public void ValidateMinutes()
        {
            bool    expectedResultMins = true;
            decimal expectedOutputMins = 45.55m;

            string strMinutes = "45.55";

            bool actualresultMins = DDMCoordinate.ValidateIsMinutes(strMinutes, out decimal actualMinsOutput);

            Assert.AreEqual(expectedResultMins, actualresultMins);
            Assert.AreEqual(expectedOutputMins, actualMinsOutput);
        }
        public void DefaultCtorCreatesInvalidDMSCoordinate_Test()
        {
            var ddm                = new DDMCoordinate();
            var expectedResult     = false;
            var expectedLatDegrees = 0m;
            var expectedLonDegrees = 0m;

            var actualResult     = ddm.IsValid;
            var actualLatDegrees = ddm.GetShortDegreesLat();
            var actualLonDegrees = ddm.GetShortDegreesLon();

            Assert.AreEqual(expectedLatDegrees, actualLatDegrees);
            Assert.AreEqual(expectedLonDegrees, actualLonDegrees);
            Assert.AreEqual(expectedResult, actualResult);
        }
        public void ConvertDDMtoGridsquareTest_SW()
        {
            var     mcm        = new MontevideoCoordinateModel();
            decimal degreesLat = Math.Truncate(mcm.DegreesLat);
            decimal degreesLon = Math.Truncate(mcm.DegreesLon);
            decimal minutesLat = mcm.DdmMinsLat;
            decimal minutesLon = mcm.DdmMinsLon;
            var     ddm        = new DDMCoordinate(degreesLat, minutesLat, degreesLon, minutesLon);
            var     cc         = new GridDdmExpert();

            string expectedResult = MontevideoCoordinateModel.StrGridsquare();
            string actualResult   = cc.ConvertDDMtoGridsquare(ddm);

            Assert.AreEqual(expectedResult, actualResult);
        }
        /// <summary>
        /// Takes a DDMCoordinate objects and processes it using ConversionHelper an GridSquareHelper to return a Gridsquare string.
        /// If solution cannot be found a string with encoded error condition is returned and should be handled by the caller.
        /// </summary>
        /// <param name="ddmCoordinates"></param>
        /// <returns></returns>
        public string ConvertDDMtoGridsquare(DDMCoordinate ddmCoordinates)
        {
            if (ddmCoordinates == null)
            {
                return("BadInp");
            }

            if (false == LookuptablesHelper.GenerateTableLookups())
            {
                return("NoTbls");
            }

            var GridsquareResult = new StringBuilder();

            decimal DDMlatDegrees = ddmCoordinates.GetShortDegreesLat();
            decimal DDMlonDegrees = ddmCoordinates.GetShortDegreesLon();
            decimal DDMlatMinutes = ddmCoordinates.MinutesLattitude;
            decimal DDMlonMinutes = ddmCoordinates.MinutesLongitude;

            short LatDirection = ConversionHelper.ExtractPolarityNS(ddmCoordinates.ToString());
            short LonDirection = ConversionHelper.ExtractPolarityEW(ddmCoordinates.ToString());

            GridsquareResult.Append(GridsquareHelper.GetFirstGridsquareCharacter(DDMlonDegrees, LonDirection, out decimal remainderLon));
            GridsquareResult.Append(GridsquareHelper.GetSecondGridsquareCharacter(DDMlatDegrees, LatDirection, out decimal remainderLat));

            GridsquareResult.Append(GridSquareHelper.GetThirdGridsquareCharacter(remainderLon, LonDirection, out decimal minsRemainderLon));
            GridsquareResult.Append(GridSquareHelper.GetFourthGridsquareCharacter(remainderLat, LatDirection));

            decimal ddmLonMinsWithRemainder = LonDirection * (minsRemainderLon + DDMlonMinutes);
            decimal nearestEvenMultipleLon  = ConversionHelper.GetNearestEvenMultiple(ddmLonMinsWithRemainder, 2);

            GridsquareResult.Append(GridsquareHelper.GetFifthGridsquareCharacter(LonDirection, nearestEvenMultipleLon));

            decimal ddmLatMinsWithRemainder = LatDirection * DDMlatMinutes;
            decimal nearestEvenMultipleLat  = ConversionHelper.GetNearestEvenMultiple(ddmLatMinsWithRemainder, 1);

            GridsquareResult.Append(GridsquareHelper.GetSixthGridsquareCharacter(LatDirection, nearestEvenMultipleLat));

            if (GridsquareResult.Length != 6)
            {
                return("NoCalc");
            }

            return(GridsquareResult.ToString());
        }
        private static void Main(string[] args)
        {
            if (args == null || args.Length == 0)
            {
                PrintUsageInstructions();
                return;
            }

            string errorMessage = "Invalid input.";

            if (args.Length == 1)
            {
                string currentArg = args[0].Trim().ToUpper();

                if (currentArg.Contains("-H") || currentArg.Contains("--HELP"))
                {
                    PrintUsageInstructions();
                }

                else if (currentArg.Length == 6)
                {
                    if (InputHelper.IsGridsquare(currentArg, out string argGridsquare))
                    {
                        var ccu = new GridDdmExpert();
                        PrintResult(ccu.ConvertGridsquareToDDM(argGridsquare).ToString());
                    }
                    else
                    {
                        PrintResult(errorMessage);
                    }
                }

                else if (currentArg.Length > 6)
                {
                    if (InputHelper.ParseAsDDMCoordinate(currentArg, false, out string validDDM))
                    {
                        PrintResult(validDDM);
                    }
                    else
                    {
                        PrintResult(errorMessage);
                    }
                }
                else
                {
                    PrintResult(errorMessage);
                }
            }

            else if (args.Length > 1)
            {
                var argsQueue = new Queue <string>(args);

                while (argsQueue.Count > 1)
                {
                    string inputCommand  = InputHelper.GetCommand(argsQueue.Dequeue().Trim().ToUpper());
                    string currentInput  = argsQueue.Dequeue().Trim().ToUpper();
                    string outputCommand = string.Empty;
                    string result        = string.Empty;

                    if (argsQueue.Count > 0)
                    {
                        outputCommand = InputHelper.GetCommand(argsQueue.Dequeue().Trim().ToUpper());
                    }

                    switch (inputCommand)
                    {
                    case "-direwolf":
                    {
                        if (InputHelper.ParseAsDDMCoordinate(currentInput, true, out string validDWDDM))
                        {
                            if (outputCommand.Length > 0)
                            {
                                result = InputHelper.OutputCommandProcessor(inputCommand, validDWDDM, outputCommand);
                            }
                            else
                            {
                                result = validDWDDM;
                            }
                        }
                        else
                        {
                            result = errorMessage;
                        }
                        break;
                    }

                    case "-grid":
                    {
                        if (InputHelper.IsGridsquare(currentInput, out string validGrid))
                        {
                            if (outputCommand.Length > 0)
                            {
                                result = InputHelper.OutputCommandProcessor(inputCommand, validGrid, outputCommand);
                            }
                            else
                            {
                                var           cc  = new GridDdmExpert();
                                DDMCoordinate ddm = cc.ConvertGridsquareToDDM(validGrid);
                                result = ddm.ToString();
                            }
                        }
                        else
                        {
                            result = errorMessage;
                        }
                        break;
                    }

                    case "-dms":
                    {
                        if (InputHelper.ParseAsDMSCoordinate(currentInput, out string validDMS))
                        {
                            if (outputCommand.Length > 0)
                            {
                                result = InputHelper.OutputCommandProcessor(inputCommand, validDMS, outputCommand);
                            }
                            else
                            {
                                result = validDMS;
                            }
                        }
                        else
                        {
                            result = errorMessage;
                        }
                        break;
                    }

                    case "-ddm":
                    {
                        if (InputHelper.ParseAsDDMCoordinate(currentInput, false, out string validDDM))
                        {
                            if (outputCommand.Length > 0)
                            {
                                result = InputHelper.OutputCommandProcessor(inputCommand, validDDM, outputCommand);
                            }
                            else
                            {
                                result = validDDM;
                            }
                        }
                        else
                        {
                            result = errorMessage;
                        }
                        break;
                    }

                    case "-dd":
                    {
                        if (InputHelper.ParseAsDDCoordinate(currentInput, out string validDD))
                        {
                            if (outputCommand.Length > 0)
                            {
                                result = InputHelper.OutputCommandProcessor(inputCommand, validDD, outputCommand);
                            }
                            else
                            {
                                result = validDD;
                            }
                        }
                        else
                        {
                            result = errorMessage;
                        }
                        break;
                    }

                    default:
                    {
                        PrintResult(errorMessage);
                        break;
                    }
                    }

                    PrintResult(result);
                }
            }
            else
            {
                PrintResult(errorMessage);
            }
        }