public IEnumerable<Group> SearchGroupsByName(string searchTerm)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            string baseUrl = "/groups?search=" + Uri.EscapeDataString(searchTerm);

            return GetGroupsAllPages(baseUrl);
        }
        public Barcode GetBarcodeData(string barcode)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            var resp = req.ExecuteGetRequestAndParse(_parentSession, string.Format("/barcodes/{0}", barcode));

            return new Barcode(resp);
        }
        public Group GetGroupByID(int groupId)
        {
            if (_cache.IsCached<Group>())
            {
                var cachedGroups = _cache.GetCachedItems<Group>();
                var targetGroup = cachedGroups.FirstOrDefault(g => g.ID == groupId);

                if (targetGroup != null) { return targetGroup; }
            }

            Request.CityApiRequest req = new Request.CityApiRequest();
            var response = req.ExecuteGetRequestAndParse(_parentSession, string.Format("/groups/{0}", groupId));

            return new Group(response);
        }
        private IEnumerable<Checkin> GetCheckinsAllPages(string baseUrl, DateTime? sinceDate)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            var response = req.ExecuteGetRequestAndParse(_parentSession, baseUrl);
            var dynResp = response as dynamic;
            double totalEntries = dynResp.total_entries;
            double totalPages = dynResp.total_pages;
            double perPage = dynResp.per_page;
            double currentPage = dynResp.current_page;

            List<Checkin> checkins = new List<Checkin>();

            checkins.AddRange(ParseResponseToCheckinList(response));

            for (int i = 2; i <= totalPages; i++)
            {
                string pageQueryString = "page=" + i.ToString();
                string url = baseUrl;

                if (url.Contains("?"))
                {
                    url = url + "&" + pageQueryString;
                }
                else
                {
                    url = url + "?" + pageQueryString;
                }

                var pageResponse = req.ExecuteGetRequestAndParse(_parentSession, url);
                var nextCheckinList = ParseResponseToCheckinList(pageResponse);

                foreach (var ci in nextCheckinList)
                {
                    if (sinceDate.HasValue)
                    {
                        if (ci.CheckedInAt < sinceDate)
                        {
                            return checkins;
                        }
                    }

                    checkins.Add(ci);
                }
            }

            return checkins;
        }
        public IEnumerable<FamilyUser> GetFamilyOfUser(User user)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            var familyResults = req.ExecuteGetRequestAndParse(_parentSession, string.Format("/users/{0}/family", user.ID));

            List<FamilyUser> familyUsers = new List<FamilyUser>();

            dynamic famMembers = familyResults["family_members"];

            foreach (var famMember in famMembers)
            {
                string famRole = famMember.family_role;
                double userId = famMember.user_id;

                familyUsers.Add(new FamilyUser() { FamilyRole = famRole, User = GetUserByID(Convert.ToInt32(userId)) });
            }

            return familyUsers;
        }
        public User GetUserByID(int userId)
        {
            if (_cache.IsCached<User>())
            {
                var cachedUsers = _cache.GetCachedItems<User>();
                var targetUser = cachedUsers.FirstOrDefault(g => g.ID == userId);

                if (targetUser != null) { return targetUser; }
            }

            if (_individualUserCache.ContainsKey(userId))
            {
                return _individualUserCache[userId];
            }

            Request.CityApiRequest req = new Request.CityApiRequest();
            var response = req.ExecuteGetRequestAndParse(_parentSession, string.Format("/users/{0}?include_custom_fields=true", userId));

            var u = new User(response);

            _individualUserCache[u.ID] = u;

            return u;
        }
        private IEnumerable<Group> GetGroupsAllPages(string baseUrl)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            var response = req.ExecuteGetRequestAndParse(_parentSession, baseUrl);
            var dynResp = response as dynamic;
            double totalEntries = dynResp.total_entries;
            double totalPages = dynResp.total_pages;
            double perPage = dynResp.per_page;
            double currentPage = dynResp.current_page;

            List<Group> groups = new List<Group>();

            groups.AddRange(ParseResponseToGroupList(response));

            for (int i = 2; i <= totalPages; i++)
            {
                string pageQueryString = "page=" + i.ToString();
                string url = baseUrl;

                if (url.Contains("?"))
                {
                    url = url + "&" + pageQueryString;
                } else {
                    url = url + "?" + pageQueryString;
                }

                var pageResponse = req.ExecuteGetRequestAndParse(_parentSession, url);
                groups.AddRange(ParseResponseToGroupList(pageResponse));
            }

            return groups;
        }
        public IEnumerable<User> SearchUsersByName(string searchTerm)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            string baseUrl = "/Users?search=" + Uri.EscapeDataString(searchTerm);

            return GetUsersAllPages(baseUrl, null);
        }
        private IEnumerable<User> GetUsersAllPages(string baseUrl, int? maxResults)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();
            var response = req.ExecuteGetRequestAndParse(_parentSession, baseUrl);
            var dynResp = response as dynamic;
            double totalEntries = dynResp.total_entries;
            double totalPages = dynResp.total_pages;
            double perPage = dynResp.per_page;
            double currentPage = dynResp.current_page;

            List<User> usersList = new List<User>();

            usersList.AddRange(ParseResponseToUserList(response));

            for (int i = 2; i <= totalPages; i++)
            {
                string pageQueryString = "page=" + i.ToString();
                string url = baseUrl;

                if (url.Contains("?"))
                {
                    url = url + "&" + pageQueryString;
                }
                else
                {
                    url = url + "?" + pageQueryString;
                }

                var pageResponse = req.ExecuteGetRequestAndParse(_parentSession, url);
                usersList.AddRange(ParseResponseToUserList(pageResponse));

                if (maxResults.HasValue)
                {
                    if (usersList.Count > maxResults.Value)
                    {
                        break;
                    }
                }
            }

            return usersList;
        }
        public IEnumerable<Checkin> GetCheckinsByBarcode(string barcode)
        {
            Request.CityApiRequest req = new Request.CityApiRequest();

            return ParseResponseToCheckinList(req.ExecuteGetRequestAndParse(_parentSession, string.Format("/checkins/by_barcode/{0}", barcode)));
        }
 public Checkin GetCheckinByID(int checkinID)
 {
     Request.CityApiRequest req = new Request.CityApiRequest();
     return new Checkin(req.ExecuteGetRequestAndParse(_parentSession, string.Format("/checkins/{0}", checkinID)));
 }