/// <summary>
        /// Adds a new sub-condition to the current condition using OR as a link.
        /// </summary>
        /// <param name="cond">The new sub-condition</param>
        public void AddOr(CBHelperSearchCondition cond)
        {
            if (this.conditions == null)
                this.conditions = new List<CBHelperSearchCondition>();

            cond.ConditionLink = CBConditionLink.CBConditionLinkOr;
            this.conditions.Add(cond);
        }
        /// <summary>
        /// Serializes the given condition and sub-conditions to a nested set of Dictionaries which can
        /// then be serialised to JSON to be sent to the cloudbase.io APIs
        /// </summary>
        /// <returns>The Dictionary representation of the current set of conditions</returns>
        public static Dictionary<string, object> SerializeConditions(CBHelperSearchCondition cond)
        {
            Dictionary<string, object> output = new Dictionary<string,object>();

            if (cond.field == null)
            {
                if (cond.conditions != null && cond.conditions.Count > 1)
                {
                    List<object> curObject = new List<object>();

                    int prevLink = -1;
                    int count = 0;
                    foreach (CBHelperSearchCondition curGroup in cond.conditions)
                    {
                        if (prevLink != -1 && prevLink != (int)curGroup.ConditionLink) {
                            output.Add(CBConditionLink_ToString[prevLink], curObject);
                            curObject = new List<object>();
                        }
                        curObject.Add(CBHelperSearchCondition.SerializeConditions(curGroup));
                        prevLink = (int)curGroup.ConditionLink;
                        count++;
                        if (count == cond.conditions.Count) {
                            output.Add(CBConditionLink_ToString[prevLink], curObject);
                        }
                    }
                }
                else if (cond.conditions != null && cond.conditions.Count == 1)
                {
                    output = CBHelperSearchCondition.SerializeConditions(cond.conditions[0]);
                }
            }
            else
            {
                List<object> modArray = new List<object>();
                Dictionary<string, object> newCond = new Dictionary<string, object>();

                switch (cond.conditionOperator) {
                    case CBConditionOperator.CBOperatorEqual:
                        output.Add(cond.field, cond.value);
                        break;
                    case CBConditionOperator.CBOperatorAll:
                    case CBConditionOperator.CBOperatorExists:
                    case CBConditionOperator.CBOperatorNe:
                    case CBConditionOperator.CBOperatorBigger:
                    case CBConditionOperator.CBOperatorBiggerOrEqual:
                    case CBConditionOperator.CBOperatorLess:
                    case CBConditionOperator.CBOperatorLessOrEqual:
                    case CBConditionOperator.CBOperatorIn:
                    case CBConditionOperator.CBOperatorNin:
                    case CBConditionOperator.CBOperatorSize:
                    case CBConditionOperator.CBOperatorType:
                        newCond.Add(CBConditionOperator_ToString[(int)cond.conditionOperator], cond.value);
                        output.Add(cond.field, newCond);
                        break;
                    case CBConditionOperator.CBOperatorMod:
                        modArray.Add(cond.value);
                        modArray.Add(1);
                        newCond.Add(CBConditionOperator_ToString[(int)cond.conditionOperator], modArray);
                        output.Add(cond.field, newCond);
                        break;
                    default:
                        break;
                }
            }

            return output;
        }
        private void updateObjects(Object sender, EventArgs args)
        {
            GeoCoordinate currentLocation = this.GetLatestPosition(this.streamName);

            if (this.previousPosition != null)
            {
                double distance = currentLocation.GetDistanceTo(previousPosition);

                if (distance < this.queryRadius / CBGEODATASTREAM_RADIUS_RATIO)
                {
                    if (this.helper.DebugMode)
                    {
                        System.Diagnostics.Debug.WriteLine("Not enough distance between the two points. returning without fetching data");
                    }
                    return;
                }

                double speed = distance / CBGEODATASTREAM_UPDATE_SPEED;
                double ratio = 1.0;

                if (this.helper.DebugMode)
                {
                    System.Diagnostics.Debug.WriteLine("Computed speed " + speed + " meters per second");
                }

                if (this.previousSpeed != 0.0)
                {
                    ratio = speed / previousSpeed;
                }
                if (this.queryRadius * ratio < this.SearchRadius)
                {
                    this.queryRadius = this.SearchRadius;
                }
                else
                {
                    this.queryRadius = this.queryRadius * ratio;
                }

                this.previousSpeed = speed;
            }
            this.previousPosition = currentLocation;

            CBHelperSearchCondition condition = new CBHelperSearchCondition(currentLocation, this.queryRadius);

            this.helper.SearchDocument(this.CollectionName, condition, delegate(CBResponseInfo resp)
            {
                if (resp.Status && resp.Data != null)
                {
                    List<object> data = ((JArray)resp.Data).ToObject<List<object>>();
                    foreach (JObject curPointObject in data)
                    {
                        Dictionary<string, object> curPoint = curPointObject.ToObject<Dictionary<string, object>>();
                        Dictionary<string, double> locationData = ((JObject)curPoint["cb_location"]).ToObject<Dictionary<string, double>>();
                        CBGeoLocatedObject newObj = new CBGeoLocatedObject();

                        GeoCoordinate coord = new GeoCoordinate();
                        coord.Latitude = locationData["lat"];
                        coord.Longitude = locationData["lng"];
                        if (curPoint["cb_location_altitude"] != null)
                        {
                            coord.Altitude = Convert.ToDouble(curPoint["cb_location_altitude"]);
                            newObj.Altitude = Convert.ToDouble(curPoint["cb_location_altitude"]);
                        }
                        newObj.Coordinate = coord;

                        newObj.ObjectData = curPoint;

                        if (!this.foundObjects.Keys.Contains(Convert.ToString(newObj.Hash())))//(this.foundObjects[Convert.ToString(newObj.Hash())] == null)
                        {
                            this.foundObjects.Add(Convert.ToString(newObj.Hash()), newObj);
                            this.ReceivedPoint(this.streamName, newObj);
                        }
                    }

                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Failed call to the cloudbase.io APIs");
                }
                return true;
            });

            List<string> itemsToRemove = new List<string>();
            foreach (KeyValuePair<string, CBGeoLocatedObject> item in this.foundObjects)
            {
                if (item.Value.Coordinate.GetDistanceTo(currentLocation) > this.SearchRadius)
                {
                    this.RemovingPoint(this.streamName, item.Value);
                    itemsToRemove.Add(item.Key);
                }
            }

            foreach (string itemKey in itemsToRemove)
            {
                this.foundObjects.Remove(itemKey);
            }
        }
        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            CBHelperSearchCondition cond = new CBHelperSearchCondition("FirstName", CBConditionOperator.CBOperatorEqual, "Cloud");
            /*
            List<CBDataAggregationCommand> commands = new List<CBDataAggregationCommand>();

            CBDataAggregationCommandProject project = new CBDataAggregationCommandProject();
            project.IncludeFields.Add("Symbol");
            project.IncludeFields.Add("Price");
            project.IncludeFields.Add("AveragePrice");
            commands.Add(project);

            CBDataAggregationCommandGroup group = new CBDataAggregationCommandGroup();
            group.AddOutputField("Symbol");
            group.AddGroupFormulaForField("AveragePrice", CBDataAggregationGroupOperator.CBDataAggregationGroupAvg, "Price");
            commands.Add(group);
            */
            if (App.helper != null)
            {
                // search documents in the test collection
                //App.helper.DebugMode = true;
                //App.helper.SearchDocumentAggregate("security_master_3", commands, delegate(CBHelper.CBResponseInfo resp)
                App.helper.SearchDocument("users", cond, delegate(CBResponseInfo resp)
                {
                    this.OutputBox.Text = "OUTPUT: " + resp.OutputString;
                    return true;
                });
            }
        }
        private void SearchObjectButton_Click(object sender, RoutedEventArgs e)
        {
            CBHelperSearchCondition cond = new CBHelperSearchCondition("FirstName", CBConditionOperator.CBOperatorEqual, "Cloud");

            App.helper.SearchDocument("test_windows8", cond, delegate(CBResponseInfo resp)
            {
                this.OutputText.Text = "OUTPUT: " + resp.OutputString;
                return true;
            });
        }