/// <summary>
        /// Returns the ranged properties.
        /// </summary>
        /// <returns></returns>
        public List<MapCSSRuleProperties> GetRanges()
        {
            var rules = new List<MapCSSRuleProperties>();
            MapCSSRuleProperties currentRule = null;
            string previousRuleString = string.Empty;
            int minZoom = 0, maxZoom = 25;
            for (int zoomLevel = 0; zoomLevel < 25; zoomLevel++)
            {
                // get the current rule string.
                string currentRuleString = this.GetRuleStringForZoom(zoomLevel);

                if (previousRuleString != currentRuleString)
                { // there is a new rule.
                    // store the previous rule.
                    if (currentRule != null)
                    { // the current rule exists; store it.
                        currentRule.MinZoom = minZoom;
                        currentRule.MaxZoom = maxZoom + 1;

                        rules.Add(currentRule);
                        currentRule = null;
                    }

                    if (!string.IsNullOrWhiteSpace(currentRuleString))
                    { // only do this part when string is not empty.
                        minZoom = zoomLevel; // set the min zoom.
                        MapCSSRuleProperties props = this.GetRulesForZoom(zoomLevel);
                        if (props != null)
                        {
                            currentRule = new MapCSSRuleProperties(minZoom, 25);
                            currentRule = currentRule.Merge(props);
                        }
                    }
                    previousRuleString = currentRuleString;
                }
                maxZoom = zoomLevel; // set the max zoom.
            }

            // store the previous rule.
            if (currentRule != null)
            { // the current rule exists; store it.
                currentRule.MinZoom = minZoom;
                currentRule.MaxZoom = maxZoom + 1;

                rules.Add(currentRule);
            }

            return rules;
        }
 /// <summary>
 /// Returns the rules for the given zoom.
 /// </summary>
 /// <param name="zoom"></param>
 /// <returns></returns>
 public MapCSSRuleProperties GetRulesForZoom(int zoom)
 {
     MapCSSRuleProperties rule = null;
     for (int idx = 0; idx < _properties.Count; idx++)
     {
         if (_properties[idx].IsForZoom(zoom))
         {
             if (rule == null)
             {
                 rule = new MapCSSRuleProperties(_properties[idx].MinZoom, 
                     _properties[idx].MaxZoom);
                 rule = rule.Merge(_properties[idx]);
             }
             else
             {
                 rule = rule.Merge(_properties[idx]);
             }
         }
     }
     return rule;
 }
        /// <summary>
        /// Build the property collection.
        /// </summary>
        /// <param name="mapCSSObject"></param>
        /// <returns></returns>
        private List<MapCSSRuleProperties> BuildRules(MapCSSObject mapCSSObject)
        {
            var rulesCollection = new MapCSSRulePropertiesCollection();

            // check for a file/rules.
            if (_mapCSSFile == null ||
                _mapCSSFile.Rules == null)
            { // no rules exist.
                return new List<MapCSSRuleProperties>();
            }

            // interpret all rules on-by-one.
            foreach (var rule in _mapCSSFile.Rules)
            {
                List<SelectorZoom> zooms;
                if (rule.HasToBeAppliedTo(mapCSSObject, out zooms))
                { // the selector was ok.
                    // loop over all declarations.
                    var properties = new MapCSSRuleProperties();
                    foreach (var declaration in rule.Declarations)
                    {
                        if (declaration is DeclarationInt)
                        {
                            var declarationInt = (declaration as DeclarationInt);
                            switch (declarationInt.Qualifier)
                            {
                                case DeclarationIntEnum.FillColor:
                                    properties.AddProperty("fillColor", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.ZIndex:
                                    properties.AddProperty("zIndex", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.Color:
                                    properties.AddProperty("color", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.CasingColor:
                                    properties.AddProperty("casingColor", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.Extrude:
                                    properties.AddProperty("extrude", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.ExtrudeEdgeColor:
                                    properties.AddProperty("extrudeEdgeColor", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.ExtrudeFaceColor:
                                    properties.AddProperty("extrudeFaceColor", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.IconWidth:
                                    properties.AddProperty("iconWidth", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.IconHeight:
                                    properties.AddProperty("iconHeight", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.FontSize:
                                    properties.AddProperty("fontSize", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.TextColor:
                                    properties.AddProperty("textColor", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.TextOffset:
                                    properties.AddProperty("textOffset", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.MaxWidth:
                                    properties.AddProperty("maxWidth", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.TextHaloColor:
                                    properties.AddProperty("textHaloColor", declarationInt.Eval(mapCSSObject));
                                    break;
                                case DeclarationIntEnum.TextHaloRadius:
                                    properties.AddProperty("textHaloRadius", declarationInt.Eval(mapCSSObject));
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationFloat)
                        {
                            var declarationFloat = (declaration as DeclarationFloat);
                            switch (declarationFloat.Qualifier)
                            {
                                case DeclarationFloatEnum.Width:
                                    properties.AddProperty("width", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.FillOpacity:
                                    properties.AddProperty("fillOpacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.Opacity:
                                    properties.AddProperty("opacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.CasingOpacity:
                                    properties.AddProperty("casingOpacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.ExtrudeEdgeOpacity:
                                    properties.AddProperty("extrudeEdgeOpacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.ExtrudeFaceOpacity:
                                    properties.AddProperty("extrudeFaceOpacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.ExtrudeEdgeWidth:
                                    properties.AddProperty("extrudeEdgeWidth", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.IconOpacity:
                                    properties.AddProperty("iconOpacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.TextOpacity:
                                    properties.AddProperty("textOpacity", declarationFloat.Eval(mapCSSObject));
                                    break;
                                case DeclarationFloatEnum.CasingWidth:
                                    properties.AddProperty("casingWidth", declarationFloat.Eval(mapCSSObject));
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationString)
                        {
                            var declarationString = declaration as DeclarationString;
                            switch (declarationString.Qualifier)
                            {
                                case DeclarationStringEnum.FontFamily:
                                    properties.AddProperty("fontFamily", declarationString.Eval(mapCSSObject));
                                    break;
                                case DeclarationStringEnum.Text:
                                    properties.AddProperty("text", declarationString.Eval(mapCSSObject));
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationURL)
                        {
                            byte[] image;
                            var declarationURL = declaration as DeclarationURL;
                            switch (declarationURL.Qualifier)
                            {
                                case DeclarationURLEnum.Image:
                                    if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                    {
                                        properties.AddProperty("image", image);
                                    }
                                    break;
                                case DeclarationURLEnum.FillImage:
                                    if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                    {
                                        properties.AddProperty("fillImage", image);
                                    }
                                    break;
                                case DeclarationURLEnum.IconImage:
                                    if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                    {
                                        properties.AddProperty("iconImage", image);
                                    }
                                    break;
                                case DeclarationURLEnum.ShieldImage:
                                    if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                    {
                                        properties.AddProperty("shieldImage", image);
                                    }
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationLineJoin)
                        {
                            var declarationLineJoin = (declaration as DeclarationLineJoin);
                            properties.AddProperty("lineJoin", declarationLineJoin.Eval(
                                mapCSSObject));
                        }
                        else if (declaration is DeclarationDashes)
                        {
                            var declarationDashes = (declaration as DeclarationDashes);
                            properties.AddProperty("dashes", declarationDashes.Eval(
                                mapCSSObject));
                        }
                    }

                    // loop over all zoom levels.
                    foreach (var zoom in zooms)
                    {
                        int minZoom = 0;
                        int maxZoom = 25;
                        if (zoom != null)
                        { // there is a zoom object.
                            if (zoom.ZoomMin.HasValue)
                            {
                                minZoom = zoom.ZoomMin.Value;
                            }
                            if (zoom.ZoomMax.HasValue)
                            {
                                maxZoom = zoom.ZoomMax.Value;
                            }
                        }

                        // zoom properties;
                        var zoomRule = new MapCSSRuleProperties(
                            minZoom, maxZoom);
                        zoomRule = zoomRule.Merge(properties);

                        // add the properties.
                        rulesCollection.AddProperties(zoomRule);
                    }
                }
            }
            return rulesCollection.GetRanges();
        }
        /// <summary>
        /// Build the property collection.
        /// </summary>
        /// <param name="mapCSSObject"></param>
        /// <returns></returns>
        private List <MapCSSRuleProperties> BuildRules(MapCSSObject mapCSSObject)
        {
            var rulesCollection = new MapCSSRulePropertiesCollection();

            // check for a file/rules.
            if (_mapCSSFile == null ||
                _mapCSSFile.Rules == null)
            { // no rules exist.
                return(new List <MapCSSRuleProperties>());
            }

            // interpret all rules on-by-one.
            foreach (var rule in _mapCSSFile.Rules)
            {
                List <KeyValuePair <int?, int?> > zooms;
                if (rule.HasToBeAppliedTo(mapCSSObject, out zooms))
                { // the selector was ok.
                    // loop over all declarations.
                    var properties = new MapCSSRuleProperties();
                    foreach (var declaration in rule.Declarations)
                    {
                        if (declaration is DeclarationInt)
                        {
                            var declarationInt = (declaration as DeclarationInt);
                            switch (declarationInt.Qualifier)
                            {
                            case DeclarationIntEnum.FillColor:
                                properties.AddProperty("fillColor", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.ZIndex:
                                properties.AddProperty("zIndex", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.Color:
                                properties.AddProperty("color", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.CasingColor:
                                properties.AddProperty("casingColor", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.Extrude:
                                properties.AddProperty("extrude", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.ExtrudeEdgeColor:
                                properties.AddProperty("extrudeEdgeColor", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.ExtrudeFaceColor:
                                properties.AddProperty("extrudeFaceColor", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.IconWidth:
                                properties.AddProperty("iconWidth", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.IconHeight:
                                properties.AddProperty("iconHeight", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.FontSize:
                                properties.AddProperty("fontSize", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.TextColor:
                                properties.AddProperty("textColor", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.TextOffset:
                                properties.AddProperty("textOffset", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.MaxWidth:
                                properties.AddProperty("maxWidth", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.TextHaloColor:
                                properties.AddProperty("textHaloColor", declarationInt.Eval(mapCSSObject));
                                break;

                            case DeclarationIntEnum.TextHaloRadius:
                                properties.AddProperty("textHaloRadius", declarationInt.Eval(mapCSSObject));
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationFloat)
                        {
                            var declarationFloat = (declaration as DeclarationFloat);
                            switch (declarationFloat.Qualifier)
                            {
                            case DeclarationFloatEnum.Width:
                                properties.AddProperty("width", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.FillOpacity:
                                properties.AddProperty("fillOpacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.Opacity:
                                properties.AddProperty("opacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.CasingOpacity:
                                properties.AddProperty("casingOpacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.ExtrudeEdgeOpacity:
                                properties.AddProperty("extrudeEdgeOpacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.ExtrudeFaceOpacity:
                                properties.AddProperty("extrudeFaceOpacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.ExtrudeEdgeWidth:
                                properties.AddProperty("extrudeEdgeWidth", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.IconOpacity:
                                properties.AddProperty("iconOpacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.TextOpacity:
                                properties.AddProperty("textOpacity", declarationFloat.Eval(mapCSSObject));
                                break;

                            case DeclarationFloatEnum.CasingWidth:
                                properties.AddProperty("casingWidth", declarationFloat.Eval(mapCSSObject));
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationString)
                        {
                            var declarationString = declaration as DeclarationString;
                            switch (declarationString.Qualifier)
                            {
                            case DeclarationStringEnum.FontFamily:
                                properties.AddProperty("fontFamily", declarationString.Eval(mapCSSObject));
                                break;

                            case DeclarationStringEnum.Text:
                                properties.AddProperty("text", declarationString.Eval(mapCSSObject));
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationURL)
                        {
                            byte[] image;
                            var    declarationURL = declaration as DeclarationURL;
                            switch (declarationURL.Qualifier)
                            {
                            case DeclarationURLEnum.Image:
                                if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                {
                                    properties.AddProperty("image", image);
                                }
                                break;

                            case DeclarationURLEnum.FillImage:
                                if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                {
                                    properties.AddProperty("fillImage", image);
                                }
                                break;

                            case DeclarationURLEnum.IconImage:
                                if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                {
                                    properties.AddProperty("iconImage", image);
                                }
                                break;

                            case DeclarationURLEnum.ShieldImage:
                                if (_mapCSSImageSource.TryGet(declarationURL.Eval(mapCSSObject), out image))
                                {
                                    properties.AddProperty("shieldImage", image);
                                }
                                break;

                            default:
                                throw new ArgumentOutOfRangeException();
                            }
                        }
                        else if (declaration is DeclarationLineJoin)
                        {
                            var declarationLineJoin = (declaration as DeclarationLineJoin);
                            properties.AddProperty("lineJoin", declarationLineJoin.Eval(
                                                       mapCSSObject));
                        }
                        else if (declaration is DeclarationDashes)
                        {
                            var declarationDashes = (declaration as DeclarationDashes);
                            properties.AddProperty("dashes", declarationDashes.Eval(
                                                       mapCSSObject));
                        }
                    }

                    // loop over all zoom levels.
                    foreach (var keyValuePair in zooms)
                    {
                        int minZoom = 0;
                        if (keyValuePair.Key.HasValue)
                        {
                            minZoom = keyValuePair.Key.Value;
                        }
                        int maxZoom = 25;
                        if (keyValuePair.Value.HasValue)
                        {
                            maxZoom = keyValuePair.Value.Value;
                        }

                        // zoom properties;
                        var zoomRule = new MapCSSRuleProperties(
                            minZoom, maxZoom);
                        zoomRule = zoomRule.Merge(properties);

                        // add the properties.
                        rulesCollection.AddProperties(zoomRule);
                    }
                }
            }
            return(rulesCollection.GetRanges());
        }
 /// <summary>
 /// Adds the given properties to the ones already here.
 /// </summary>
 /// <param name="properties"></param>
 public void AddProperties(MapCSSRuleProperties properties)
 {
     _properties.Add(properties);
 }