private void addSubHits(PrefixEntry prefixEntry, int parentId, string callsign)
 {
     for (int i = 0; i < prefixEntry.Children.Count; i++)
     {
         PrefixEntry child = prefixList.Entries[prefixEntry.Children[i]];
         if (tryMask(child, false, callsign))
         {
             PrefixEntry hit = addHit(child, parentId);
             addSubHits(child, parentId, callsign);
         }
     }
 }
        private bool tryMask(PrefixEntry entry, bool topLevel, string callsign)
        {
            bool result = false;

            if (usPossesions.Contains(Convert.ToInt32(entry.Data.ADIF)) & topLevel == true)
            {
                result = true;
            }
            //check entry kind
            else if (topLevel)
            {
                if (!AllowedForTop.Contains(entry.Kind))
                {
                    return(result);
                }
            }
            else
            {
                if (!AllowedForSub.Contains(entry.Kind))
                {
                    return(result);
                }
            }
            // mobile, portable, beacon, rover
            if (callsign.EndsWith("/M") || callsign.EndsWith("/P") || callsign.EndsWith("/B") || callsign.EndsWith("/R"))
            {
                callsign = callsign.Substring(0, callsign.Length - 2);
            }
            string[] maskParts = entry.Mask.Split(',');
            for (int i = 0; i < maskParts.Length; i++)
            {
                PrefixMatch prefixMatch = comparePrefix(maskParts[i], callsign);
                EndingMatch endingMatch = compareEnding(maskParts[i], callsign);
                if (topLevel)
                {
                    result = ResultForTop[(int)prefixMatch, (int)endingMatch];
                }
                else
                {
                    result = ResultForChild[(int)prefixMatch, (int)endingMatch];
                }
                if (result)
                {
                    break;
                }
            }
            return(result);
        }
        private PrefixEntry addHit(PrefixEntry prefixEntry, int parentId)
        {
            PrefixEntry hitEntry = new PrefixEntry();

            hitEntry.Data = prefixEntry.Data;
            hitEntry.Kind = prefixEntry.Kind;
            ////ordinal number of the hit
            hitEntry.Id = hitTree.Count;
            ////remember your parent
            hitEntry.Parent = parentId;
            hitTree.Add(hitEntry);
            ////tell the parent about its child
            if (parentId > 0)
            {
                PrefixEntry parent = hitTree[parentId];
                parent.Children.Add(hitEntry.Id);
            }
            return(hitEntry);
        }
        private void resolveCallsign(string callsign)
        {
            if (callsign.StartsWith(ADIF_MARKER))
            {
                int adif = Convert.ToInt32(callsign.Substring(ADIF_MARKER.Length));
                if (adif > 0)
                {
                    PrefixData prefixData = getAdifItem(adif);
                    if (prefixData != null)
                    {
                        hitList.Add(prefixData);
                    }
                }
            }
            else
            {
                int x = AfreetConstants.Chars.IndexOf(callsign[0]);
                int y = AfreetConstants.Chars.IndexOf(callsign[1]);
                List <PrefixEntry> arr = prefixList.Index[x, y];

                for (int i = 0; i < arr.Count; i++)
                {
                    try
                    {
                        if (tryMask(arr[i], true, callsign))
                        {
                            PrefixEntry hitEntry = addHit(arr[i], -1);
                            addSubHits(arr[i], hitEntry.Id, callsign);
                        }
                    }
                    catch
                    {
                    }
                }
                packHits();
            }

            // order hist list by prefix
            hitList = hitList.OrderBy(e => e.Prefix).ToList <PrefixData>();
        }
        private PrefixData mergePrefixData(PrefixData destination, PrefixEntry source)
        {
            source.Id = -1;
            switch (source.Kind)
            {
            case PrefixKind.DXCC:
            {
                destination.Territory = source.Data.Territory;
                break;
            }

            case PrefixKind.Province:
            {
                destination.Province = (String.IsNullOrEmpty(destination.Province)) ?
                                       source.Data.Territory :
                                       String.Format("{0}, {1}", source.Data.Territory, destination.Province);
                break;
            }

            case PrefixKind.City:
            {
                destination.City = source.Data.Territory;
                break;
            }

            case PrefixKind.Station:
            {
                if (source.Data.Location.X != Int32.MaxValue)
                {
                    destination.City = source.Data.Territory;
                }
                break;
            }
            }
            ////set location if it was not set by the child
            if (destination.Location.X == Int32.MaxValue)
            {
                destination.Location = source.Data.Location;
            }
            ////copy fields from Src to Dst
            if (source.Data.Location.X != Int32.MaxValue)
            {
                if (String.IsNullOrEmpty(destination.Prefix))
                {
                    destination.Prefix = source.Data.Prefix;
                }
                if (String.IsNullOrEmpty(destination.CQ))
                {
                    destination.CQ = source.Data.CQ;
                }
                if (String.IsNullOrEmpty(destination.ITU))
                {
                    destination.ITU = source.Data.ITU;
                }
                if (String.IsNullOrEmpty(destination.Continent))
                {
                    destination.Continent = source.Data.Continent;
                }
                if (String.IsNullOrEmpty(destination.TZ))
                {
                    destination.TZ = source.Data.TZ;
                }
                if (String.IsNullOrEmpty(destination.ADIF))
                {
                    destination.ADIF = source.Data.ADIF;
                }
                if (String.IsNullOrEmpty(destination.ProvinceCode))
                {
                    destination.ProvinceCode = source.Data.ProvinceCode;
                }
            }
            ////copy attributes
            destination.Attributes.AddRange(source.Data.Attributes);
            ////add missing data from Src's parents
            if (source.Parent > -1)
            {
                mergePrefixData(destination, hitTree[source.Parent]);
            }
            return(destination);
        }