public SpecialNotification(JToken item, string venueId)
 {
     var js = item["special"];
     if (js != null)
     {
         Special = CompactSpecial.ParseJson(js, venueId);
     }
 }
Exemplo n.º 2
0
        public SpecialNotification(JToken item, string venueId)
        {
            var js = item["special"];

            if (js != null)
            {
                Special = CompactSpecial.ParseJson(js, venueId);
            }
        }
Exemplo n.º 3
0
            protected override object DeserializeCore(JObject json, Type objectType, SpecialLoadContext context)
            {
                try
                {
                    var nv = new Special(context);

                    var special = json["special"];
                    if (special != null)
                    {
                        nv.CompactSpecial = CompactSpecial.ParseJson(special, context.VenueId);
                    }

                    // Should be quick since this usually happens right after a
                    // check-in.
                    if (!string.IsNullOrEmpty(context.VenueId))
                    {
                        nv.Venue = DataManager.Current.Load <Venue>(context.VenueId,
                                                                    (venue) =>
                        {
                            //nv.Venue
                            nv.IsLoadComplete = true;
                        },
                                                                    (error) =>
                        {
                            nv.IsLoadComplete = true;
                        });
                    }
                    //else
                    //{
                    // This really is probably an error condition.


                    nv.IsLoadComplete = true;


                    //}

                    return(nv);
                }
                catch (Exception e)
                {
                    throw new UserIntendedException(
                              "There was a problem trying to read information about the special.", e);
                }
            }
            protected override object DeserializeCore(JObject json, Type objectType, LimitingLoadContext context)
            {
                try
                {
                    var nv = new SpecialsSearch(context);
                    nv.IgnoreRaisingPropertyChanges = true;

                    var specials = json["specials"];
                    nv.SpecialsText = "no specials";
                    if (specials != null)
                    {
                        // cout
                        var items = specials["items"];
                        nv.Specials = new SpecialGroup();
                        foreach (var item in items)
                        {
                            CompactSpecial special = CompactSpecial.ParseJson(item, null);
                            nv.Specials.Add(special);
                        }

                        if (nv.Specials.Count > 1)
                        {
                            nv.SpecialsText = nv.Specials.Count.ToString(CultureInfo.InvariantCulture) +
                                              " specials nearby";
                        }
                        else
                        {
                            if (nv.Specials.Count == 1)
                            {
                                nv.SpecialsText = "1 special nearby";
                            }
                        }
                    }

                    nv.IgnoreRaisingPropertyChanges = false;
                    nv.IsLoadComplete = true;

                    return(nv);
                }
                catch (Exception e)
                {
                    throw new UserIntendedException("Nearby specials could not be loaded right now, sorry.", e);
                }
            }
Exemplo n.º 5
0
        private static object HydrateCompactObject(TargetObjectType type, JToken item)
        {
            try
            {
                if (item != null)
                {
                    switch (type)
                    {
                    case TargetObjectType.Badge:
                        return(Badge.ParseJson(item));

                    case TargetObjectType.Checkin:
                        return(Checkin.ParseJson(item));

                    case TargetObjectType.Special:
                        // VenueId, if null, must be parsed out of the
                        // notification or else it will throw. FYI.
                        return(CompactSpecial.ParseJson(item, null));

                    case TargetObjectType.Tip:
                        return(Tip.ParseJson(item));

                    case TargetObjectType.Url:
                        Uri uri = Json.TryGetUriProperty(item, "url");
                        return(uri);

                    case TargetObjectType.User:
                        return(CompactUser.ParseJson(item));

                    case TargetObjectType.Venue:
                        return(CompactVenue.ParseJson(item));

                    default:
                        break;
                    }
                }
            }
            catch (Exception)
            {
            }

            return(null);
        }
        public static CompactSpecial ParseJson(JToken json, string venueId)
        {
            var cs = new CompactSpecial();

            // OVERRIDE! Used for nearby specials.
            var vn = json["venue"];

            if (vn != null)
            {
                var venue = CompactVenue.ParseJson(vn);
                if (venue != null)
                {
                    cs.CompactVenue = venue;
                    venueId         = venue.VenueId;
                }
            }

            Debug.Assert(venueId != null);

            cs.VenueId = venueId;

            cs.SpecialId = Json.TryGetJsonProperty(json, "id");

            Debug.Assert(cs.VenueId != null);

            if (!string.IsNullOrEmpty(cs.SpecialId))
            {
                cs.LocalSpecialUri = new Uri(
                    string.Format(CultureInfo.InvariantCulture,
                                  "/JeffWilcox.FourthAndMayor.Specials;component/Special.xaml?id={0}&venueId={1}", cs.SpecialId, cs.VenueId),
                    UriKind.Relative);
            }

            cs.Message = Json.TryGetJsonProperty(json, "message");

            cs.Title = Json.TryGetJsonProperty(json, "title");

            cs.Description = Json.TryGetJsonProperty(json, "description");

            cs.FinePrint = Json.TryGetJsonProperty(json, "finePrint");

            cs.IconType = Json.TryGetJsonProperty(json, "icon");
            if (!string.IsNullOrEmpty(cs.IconType))
            {
                cs.IconUri = new Uri(
                    string.Format(
                        CultureInfo.InvariantCulture,
                        "http://foursquare.com/img/business/special_icons/{0}.png",
                        cs.IconType), UriKind.Absolute);
            }

            // new in my 1.5 v
            cs.State = Json.TryGetJsonProperty(json, "state");
            SpecialState sst;

            switch (cs.State)
            {
            case "unlocked":
                sst = SpecialState.Unlocked;
                break;

            case "before start":
                sst = SpecialState.BeforeStart;
                break;

            case "in progress":
                sst = SpecialState.InProgress;
                break;

            case "taken":
                sst = SpecialState.Taken;
                break;

            default:
            case "locked":
                sst = SpecialState.Locked;
                break;
            }
            cs.SpecialState = sst;

            cs.Provider = Json.TryGetJsonProperty(json, "provider");

            string prog = Json.TryGetJsonProperty(json, "progress");

            if (!string.IsNullOrEmpty(prog))
            {
                int pg;
                if (int.TryParse(prog, out pg))
                {
                    cs.Progress = pg;
                }
            }

            cs.ProgressDescription = Json.TryGetJsonProperty(json, "progressDescription");

            // Minutes remaining until the special can be unlocked (flash only)
            prog = Json.TryGetJsonProperty(json, "detail");
            if (!string.IsNullOrEmpty(prog))
            {
                int pg;
                if (int.TryParse(prog, out pg))
                {
                    cs.Detail = pg;
                }
            }

            // A number indicating the maximum (swarm, flash) or minimum
            // (friends) number of people allowed to unlock the special.
            prog = Json.TryGetJsonProperty(json, "target");
            if (!string.IsNullOrEmpty(prog))
            {
                int pg;
                if (int.TryParse(prog, out pg))
                {
                    cs.Target = pg;
                }
            }

            // not part of the v3 docs...
            // cs.Redemption = Json.TryGetJsonProperty(json, "redemption");

            cs.IsUnlocked = Json.TryGetJsonBool(json, "unlocked");
            cs.IsLocked   = !cs.IsUnlocked;

            // A list of friends currently checked in, as compact user objects
            // (friends special only).
            var fh = json["friendsHere"];

            if (fh != null)
            {
                var list = new List <CompactUser>();
                foreach (var friend in fh)
                {
                    var cu = CompactUser.ParseJson(friend);
                    if (cu != null)
                    {
                        list.Add(cu);
                    }
                }
                cs.FriendsHere = list;
            }

            string      type = Json.TryGetJsonProperty(json, "type");
            SpecialType st;

            switch (type)
            {
            case "mayor":
                st = SpecialType.Mayor;
                break;

            case "frequency":
                st = SpecialType.Frequency;
                break;

            case "count":
                st = SpecialType.Count;
                break;

            case "regular":
                st = SpecialType.Regular;
                break;

            case "friends":
                st = SpecialType.Friends;
                break;

            case "swarm":
                st = SpecialType.Swarm;
                break;

            case "flash":
                st = SpecialType.Flash;
                break;

            case "other":
            default:
                st = SpecialType.Other;
                break;
            }
            cs.Type = st;

            /*
             * "item": {
             * "special": {
             * "id": "4d6d69fa40fc8eecde57a5ba",
             * "type": "other",
             * "message": "New clients: Receive 20% off your first service at Capelli's when you check in at Foursquare!",
             * "description": "for some other condition",
             * "unlocked": true,
             * "icon": "frequency",
             * "title": "Special Offer",
             * "state": "unlocked",
             * "provider": "foursquare",
             * "redemption": "standard"
             * }
             * */

            return(cs);
        }
        public static CompactSpecial ParseJson(JToken json, string venueId)
        {
            var cs = new CompactSpecial();

            // OVERRIDE! Used for nearby specials.
            var vn = json["venue"];
            if (vn != null)
            {
                var venue = CompactVenue.ParseJson(vn);
                if (venue != null)
                {
                    cs.CompactVenue = venue;
                    venueId = venue.VenueId;
                }
            }

            Debug.Assert(venueId != null);

            cs.VenueId = venueId;

            cs.SpecialId = Json.TryGetJsonProperty(json, "id");

            Debug.Assert(cs.VenueId != null);

            if (!string.IsNullOrEmpty(cs.SpecialId))
            {
                cs.LocalSpecialUri = new Uri(
                    string.Format(CultureInfo.InvariantCulture,
                    "/JeffWilcox.FourthAndMayor.Specials;component/Special.xaml?id={0}&venueId={1}", cs.SpecialId, cs.VenueId),
                    UriKind.Relative);
            }

            cs.Message = Json.TryGetJsonProperty(json, "message");

            cs.Title = Json.TryGetJsonProperty(json, "title");

            cs.Description = Json.TryGetJsonProperty(json, "description");

            cs.FinePrint = Json.TryGetJsonProperty(json, "finePrint");

            cs.IconType = Json.TryGetJsonProperty(json, "icon");
            if (!string.IsNullOrEmpty(cs.IconType))
            {
                cs.IconUri = new Uri(
                    string.Format(
                    CultureInfo.InvariantCulture,
                    "http://foursquare.com/img/business/special_icons/{0}.png", 
                    cs.IconType), UriKind.Absolute);
            }

            // new in my 1.5 v
            cs.State = Json.TryGetJsonProperty(json, "state");
            SpecialState sst;
            switch (cs.State)
            {
                case "unlocked":
                    sst = SpecialState.Unlocked;
                    break;

                case "before start":
                    sst = SpecialState.BeforeStart;
                    break;

                case "in progress":
                    sst = SpecialState.InProgress;
                    break;

                case "taken":
                    sst = SpecialState.Taken;
                    break;

                default:
                case "locked":
                    sst = SpecialState.Locked;
                    break;
            }
            cs.SpecialState = sst;

            cs.Provider = Json.TryGetJsonProperty(json, "provider");

            string prog = Json.TryGetJsonProperty(json, "progress");
            if (!string.IsNullOrEmpty(prog))
            {
                int pg;
                if (int.TryParse(prog, out pg))
                {
                    cs.Progress = pg;
                }
            }

            cs.ProgressDescription = Json.TryGetJsonProperty(json, "progressDescription");

            // Minutes remaining until the special can be unlocked (flash only)
            prog = Json.TryGetJsonProperty(json, "detail");
            if (!string.IsNullOrEmpty(prog))
            {
                int pg;
                if (int.TryParse(prog, out pg))
                {
                    cs.Detail = pg;
                }
            }

            // A number indicating the maximum (swarm, flash) or minimum 
            // (friends) number of people allowed to unlock the special.
            prog = Json.TryGetJsonProperty(json, "target");
            if (!string.IsNullOrEmpty(prog))
            {
                int pg;
                if (int.TryParse(prog, out pg))
                {
                    cs.Target = pg;
                }
            }

            // not part of the v3 docs...
            // cs.Redemption = Json.TryGetJsonProperty(json, "redemption");

            cs.IsUnlocked = Json.TryGetJsonBool(json, "unlocked");
            cs.IsLocked = !cs.IsUnlocked;

            // A list of friends currently checked in, as compact user objects 
            // (friends special only).
            var fh = json["friendsHere"];
            if (fh != null)
            {
                var list = new List<CompactUser>();
                foreach (var friend in fh)
                {
                    var cu = CompactUser.ParseJson(friend);
                    if (cu != null)
                    {
                        list.Add(cu);
                    }
                }
                cs.FriendsHere = list;
            }

            string type = Json.TryGetJsonProperty(json, "type");
            SpecialType st;
            switch (type)
            {
                case "mayor":
                    st = SpecialType.Mayor;
                    break;

                case "frequency":
                    st = SpecialType.Frequency;
                    break;

                case "count":
                    st = SpecialType.Count;
                    break;

                case "regular":
                    st = SpecialType.Regular;
                    break;

                case "friends":
                    st = SpecialType.Friends;
                    break;

                case "swarm":
                    st = SpecialType.Swarm;
                    break;

                case "flash":
                    st = SpecialType.Flash;
                    break;

                case "other":
                default:
                st = SpecialType.Other;
                break;
            }
            cs.Type = st;

            /*
             "item": {
      "special": {
        "id": "4d6d69fa40fc8eecde57a5ba",
        "type": "other",
        "message": "New clients: Receive 20% off your first service at Capelli's when you check in at Foursquare!",
        "description": "for some other condition",
        "unlocked": true,
        "icon": "frequency",
        "title": "Special Offer",
        "state": "unlocked",
        "provider": "foursquare",
        "redemption": "standard"
      }
             * */

            return cs;
        }
Exemplo n.º 8
0
            protected override object DeserializeCore(JObject json, Type objectType, LoadContext context)
            {
                var v = new Venue(context);

                try
                {
                    var venue = json["venue"];

                    CompactVenue bv = CompactVenue.ParseJson(venue);
                    v.VenueId = bv.VenueId;
                    Debug.Assert(v.VenueId != null);

                    // TODO: Consider architecture.
                    v.Location    = bv.Location;
                    v.Address     = bv.Address;
                    v.City        = bv.City;
                    v.CrossStreet = bv.CrossStreet;
                    v.State       = bv.State;
                    v.Zip         = bv.Zip;
                    v.Name        = bv.Name;

                    var menuEntry = venue["menu"];
                    if (menuEntry != null)
                    {
                        string mobileMenu = Json.TryGetJsonProperty(menuEntry, "mobileUrl");
                        if (!string.IsNullOrEmpty(mobileMenu))
                        {
                            v.HasMenu = true;
                        }
                    }

                    string desc = Checkin.SanitizeString(Json.TryGetJsonProperty(venue, "description"));
                    if (desc != null)
                    {
                        v.Description = desc;
                    }

                    // TODO: V2: timeZone // timeZone: "America/New_York"

                    string swu = Json.TryGetJsonProperty(venue, "shortUrl");
                    if (swu != null)
                    {
                        v.ShortWebUri = new Uri(swu);
                    }

                    string verif = Json.TryGetJsonProperty(venue, "verified");
                    if (verif != null && verif.ToLowerInvariant() == "true")
                    {
                        v.IsVerified = true;
                    }

                    // older code.
                    string phone = Json.TryGetJsonProperty(venue, "phone");
                    if (phone != null)
                    {
                        v.Phone = phone; // User.FormatSimpleUnitedStatesPhoneNumberMaybe(phone);
                    }

                    // newer code for contact stuff.
                    var contact = venue["contact"];
                    if (contact != null)
                    {
                        v.Twitter = Json.TryGetJsonProperty(contact, "twitter");

                        string newerPhone = Json.TryGetJsonProperty(contact, "phone");
                        if (newerPhone != null)
                        {
                            v.Phone = newerPhone;
                        }

                        string bestPhone = Json.TryGetJsonProperty(contact, "formattedPhone");
                        if (bestPhone != null)
                        {
                            v.FormattedPhone = bestPhone;
                        }

                        // fallback.
                        if (v.FormattedPhone == null && !string.IsNullOrEmpty(v.Phone))
                        {
                            v.FormattedPhone = User.FormatSimpleUnitedStatesPhoneNumberMaybe(v.Phone);
                        }
                    }

                    string homepage = Json.TryGetJsonProperty(venue, "url");
                    if (!string.IsNullOrEmpty(homepage))
                    {
                        v.Homepage = new Uri(homepage, UriKind.Absolute);
                    }

                    var todos = venue["todos"];
                    if (todos != null)
                    {
                        var items = todos["items"];
                        if (items != null)
                        {
                            var todosList = new List <Todo>();
                            foreach (var todo in items)
                            {
                                var td = Todo.ParseJson(todo);
                                if (td != null)
                                {
                                    todosList.Add(td);
                                }
                            }
                            v.Todos = todosList;
                        }
                    }

                    var events = venue["events"];
                    if (events != null)
                    {
                        string pct = Json.TryGetJsonProperty(events, "count");
                        int    pcti;
                        if (int.TryParse(pct, out pcti))
                        {
                            v.EventsCount = pcti;

                            if (pcti > 0)
                            {
                                v.EventsSummary = Json.TryGetJsonProperty(events, "summary");
                            }

                            if (v.HasEvents)
                            {
                                // ? will this work ?
                                v.Events = DataManager.Current.Load <VenueEvents>(
                                    new LoadContext(
                                        v.LoadContext.Identity
                                        )
                                    );
                            }
                        }
                    }

                    var photos = venue["photos"];
                    if (photos != null)
                    {
                        string pct = Json.TryGetJsonProperty(photos, "count");
                        int    pcti;
                        if (int.TryParse(pct, out pcti))
                        {
                            if (pcti == 1)
                            {
                                v.PhotosCount = "1 photo";
                            }
                            else if (pcti > 1)
                            {
                                v.PhotosCount = pcti.ToString() + " photos";
                            }

                            // get the grounds
                            if (pcti > 0)
                            {
                                var groups = photos["groups"];
                                if (groups != null)
                                {
                                    var pg = new List <PhotoGroup>();
                                    foreach (var item in groups)
                                    {
                                        string name  = Json.TryGetJsonProperty(item, "name");
                                        var    items = item["items"];
                                        var    group = new PhotoGroup();
                                        group.Name = name;
                                        foreach (var it in items)
                                        {
                                            Photo p = Photo.ParseJson(it);
                                            if (p != null)
                                            {
                                                group.Add(p);
                                            }
                                        }
                                        if (group.Count > 0)
                                        {
                                            pg.Add(group);
                                        }
                                    }
                                    if (pg.Count > 0)
                                    {
                                        v.PhotoGroups = pg;
                                    }
                                }
                            }
                        }
                    }
                    // Allowing the GIC to show the empty template.
                    if (v.PhotoGroups == null)
                    {
                        v.PhotoGroups = new List <PhotoGroup>();
                    }

                    string htodo = Json.TryGetJsonProperty(venue, "hasTodo"); // checkin mode only
                    if (htodo != null && htodo.ToLowerInvariant() == "true")
                    {
                        v.HasToDo = true;
                    }

                    v.HereNow = "Nobody";
                    bool hereNow = false;
                    var  herenow = venue["hereNow"];
                    if (herenow != null)
                    {
                        bool isSelfHere = false;

                        string summary = Json.TryGetJsonProperty(herenow, "summary");
                        if (summary != null)
                        {
                            v.HereNow = summary;
                        }

                        var    groups = herenow["groups"];
                        string hn     = Json.TryGetJsonProperty(herenow, "count");
                        if (/*!string.IsNullOrEmpty(hn) &&*/ groups != null) // I still want to compute this anyway.
                        {
                            int totalCount     = int.Parse(hn, CultureInfo.InvariantCulture);
                            int remainingCount = totalCount;

                            var hereNowGroups = new List <CheckinsGroup>();
                            foreach (var group in groups)
                            {
                                string type  = Json.TryGetJsonProperty(group, "type");  // friends, others
                                string name  = Json.TryGetJsonProperty(group, "name");  // "friends here", "other people here"
                                string count = Json.TryGetJsonProperty(group, "count"); // the count, an int
                                var    items = group["items"];

                                if (items != null)
                                {
                                    var cg = new CheckinsGroup {
                                        Name = name
                                    };

                                    foreach (var item in items)
                                    {
                                        Checkin cc = Checkin.ParseJson(item);
                                        remainingCount--;
                                        if (cc.User != null && cc.User.Relationship == FriendStatus.Self)
                                        {
                                            // Self!
                                            var selfGroup = new CheckinsGroup {
                                                Name = "you're here!"
                                            };
                                            isSelfHere = true;
                                            selfGroup.Add(cc);
                                            hereNowGroups.Add(selfGroup);
                                        }
                                        else
                                        {
                                            cg.Add(cc);
                                        }
                                    }

                                    if (cg.Count > 0)
                                    {
                                        hereNowGroups.Add(cg);
                                    }
                                }
                            }

                            // Special last item with the remainder count.
                            if (remainingCount > 0 && hereNowGroups.Count > 0)
                            {
                                var lastGroup = hereNowGroups[hereNowGroups.Count - 1];
                                var hnr       = new Checkin
                                {
                                    HereNowRemainderText =
                                        remainingCount == 1
                                            ? "... plus 1 person"
                                            : "... plus " + remainingCount.ToString() + " people",
                                };
                                lastGroup.Add(hnr);
                            }

                            v.HereNowGroups = hereNowGroups;

                            // subtract one for self
                            if (isSelfHere)
                            {
                                totalCount--;
                            }
                            string prefix = (isSelfHere ? "You and " : string.Empty);
                            if (string.IsNullOrEmpty(summary))
                            {
                                if (totalCount > 1)
                                {
                                    v.HereNow = prefix + Json.GetPrettyInt(totalCount) + " " + (isSelfHere ? "other " : "") + "people";
                                }
                                else if (totalCount == 1)
                                {
                                    v.HereNow = prefix + "1 " + (isSelfHere ? "other " : "") + "person";
                                }
                                else if (totalCount == 0 && isSelfHere)
                                {
                                    v.HereNow = "You are here";
                                }
                            }

                            if (totalCount > 0)
                            {
                                hereNow = true;
                            }
                        }
                    }

                    v.HasHereNow = hereNow;

                    var stats = venue["stats"];
                    if (stats != null)
                    {
                        string checkins = Json.TryGetJsonProperty(stats, "checkinsCount");
                        if (checkins != null)
                        {
                            int i;
                            if (int.TryParse(checkins, out i))
                            {
                                v.Checkins = i;
                            }
                        }

                        checkins = Json.TryGetJsonProperty(stats, "usersCount");
                        if (checkins != null)
                        {
                            int i;
                            if (int.TryParse(checkins, out i))
                            {
                                v.TotalPeople = i;
                            }
                        }
                    }

                    var mayor = venue["mayor"];
                    if (mayor != null)
                    {
                        string mayorCheckinCount = Json.TryGetJsonProperty(mayor, "count");

                        var user = mayor["user"];
                        if (user != null)
                        {
                            v.Mayor = CompactUser.ParseJson(user);
                        }

                        // Note there is a mayor.count property, it is the num
                        // of checkins in the last 60 days.
                    }

                    var beenHere = venue["beenHere"];
                    if (beenHere != null)
                    {
                        string c = Json.TryGetJsonProperty(beenHere, "count");
                        if (c != null)
                        {
                            int i;
                            if (int.TryParse(c, out i))
                            {
                                v.BeenHere = i;
                            }
                        }
                    }

                    var tips = venue["tips"];
                    if (tips != null)
                    {
                        string tipsCountStr = Json.TryGetJsonProperty(tips, "count");
                        if (tipsCountStr != null)
                        {
                            int tc;
                            if (int.TryParse(tipsCountStr, out tc))
                            {
                                if (tc <= 0)
                                {
                                    tipsCountStr = "No tips";
                                }
                                else if (tc == 1)
                                {
                                    tipsCountStr = "1 tip";
                                }
                                else
                                {
                                    tipsCountStr = tc.ToString() + " tips";
                                }
                            }
                        }
                        else
                        {
                            tipsCountStr = "No tips";
                        }
                        v.TipsCountText = tipsCountStr;

                        var ml        = new List <TipGroup>();
                        var tipGroups = tips["groups"];
                        if (tipGroups != null)
                        {
                            foreach (var tipGroup in tipGroups)
                            {
                                //string groupType = Json.TryGetJsonProperty(tipGroup, "type"); // others, ???v2
                                string groupName = Json.TryGetJsonProperty(tipGroup, "name"); // tips from others
                                //string countStr = Json.TryGetJsonProperty(tipGroup, "count");

                                var tipSet = tipGroup["items"];
                                if (tipSet != null)
                                {
                                    TipGroup tg = new TipGroup {
                                        Name = groupName
                                    };
                                    foreach (var tip in tipSet)
                                    {
                                        Tip t = Tip.ParseJson(tip, typeof(Model.Venue), (string)context.Identity);
                                        if (t != null)
                                        {
                                            tg.Add(t);
                                        }
                                    }
                                    if (tg.Count > 0)
                                    {
                                        ml.Add(tg);
                                    }
                                }
                            }
                        }
                        v.TipGroups = ml;
                    }

                    var specials     = venue["specials"];
                    var specialsList = new SpecialGroup {
                        Name = "specials here"
                    };
                    if (specials != null)
                    {
                        try
                        {
                            var items = specials["items"];
                            if (items != null)
                            {
                                foreach (var s in items)
                                {
                                    CompactSpecial cs = CompactSpecial.ParseJson(s, v.VenueId);
                                    if (cs != null)
                                    {
                                        specialsList.Add(cs);

                                        if (cs.IsUnlocked)
                                        {
                                            v.SpecialUnlocked = true;
                                        }
                                    }
                                }
                                if (specialsList.Count == 1)
                                {
                                    specialsList.Name = "special here";
                                }
                            }
                        }
                        catch (Exception)
                        {
                            // 3.4 moves to a new Foursquare API version and so
                            // we don't want old cached data to throw here.
                        }
                    }
                    v.Specials = specialsList;

                    var nearby             = venue["specialsNearby"];
                    var nearbySpecialsList = new SpecialGroup {
                        Name = "specials nearby"
                    };
                    if (nearby != null)
                    {
                        foreach (var s in nearby)
                        {
                            CompactSpecial cs = CompactSpecial.ParseJson(s, null);
                            if (cs != null)
                            {
                                nearbySpecialsList.Add(cs);
                            }
                        }
                        if (nearbySpecialsList.Count == 1)
                        {
                            nearbySpecialsList.Name = "special nearby";
                        }
                    }
                    v.NearbySpecials = nearbySpecialsList;

                    var cmb = new List <SpecialGroup>(2);
                    if (specialsList.Count > 0)
                    {
                        cmb.Add(specialsList);
                    }
                    if (nearbySpecialsList.Count > 0)
                    {
                        cmb.Add(nearbySpecialsList);
                    }
                    v.CombinedSpecials = cmb;

                    var categories = venue["categories"];
                    if (categories != null)
                    {
                        foreach (var cat in categories)
                        {
                            var cc = Category.ParseJson(cat);
                            if (cc != null && cc.IsPrimary)
                            {
                                v.PrimaryCategory = cc;
                                break;
                            }
                            // Just the first actually!
                            break;
                        }
                    }

                    // stats
                    // .herenow
                    // .checkins
                    // beenhere: me:true;

                    // specials

                    var tags = venue["tags"];
                    if (tags != null)
                    {
                        List <string> tl = new List <string>();
                        foreach (string tag in tags)
                        {
                            tl.Add(tag);
                        }

                        if (tl.Count > 0)
                        {
                            v.Tags = tl;

                            StringBuilder sb = new StringBuilder();
                            for (int i = 0; i < tl.Count; i++)
                            {
                                if (i > 0)
                                {
                                    sb.Append(", ");
                                }

                                sb.Append(tl[i]);
                            }

                            v.TagsString = sb.ToString();
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new UserIntendedException(
                              "There was a problem trying to read the venue information.", e);
                }

                v.IsLoadComplete = true;

                return(v);
            }
        public static CompactVenue ParseJson(JToken venue)
        {
            var b = new CompactVenue();

            b.VenueId = Json.TryGetJsonProperty(venue, "id");
            Debug.Assert(b.VenueId != null);

            // FUTURE: Centralize handling of location.
            var location = venue["location"];

            if (location != null)
            {
                b.Address = Json.TryGetJsonProperty(location, "address");

                b.City        = Json.TryGetJsonProperty(location, "city");
                b.CrossStreet = Json.TryGetJsonProperty(location, "crossStreet");
                b.State       = Json.TryGetJsonProperty(location, "state");
                b.Zip         = Json.TryGetJsonProperty(location, "postalCode");

                if (b.Address != null || b.CrossStreet != null)
                {
                    b.AddressLine = SpaceAfterIfThere(b.Address) + WrapIfThere(b.CrossStreet, "(", ")");
                }

                var gl  = location["lat"];
                var gll = location["lng"];
                // didn't work in Brazil and other place!
                //string gl = Json.TryGetJsonProperty(location, "lat");
                //string gll = Json.TryGetJsonProperty(location, "lng");
                if (gl != null && gll != null)
                {
                    try
                    {
                        b._location = new LocationPair
                        {
                            Latitude  = (double)gl,  // double.Parse(gl, CultureInfo.InvariantCulture),
                            Longitude = (double)gll, // double.Parse(gll, CultureInfo.InvariantCulture),
                        };
                    }
                    catch
                    {
                    }
                }

                string dist = Json.TryGetJsonProperty(location, "distance");
                if (dist == null)
                {
                    b.Meters = double.NaN;
                }
                else
                {
                    b.Meters = double.Parse(dist, CultureInfo.InvariantCulture);
                }
            }

            b.Name = Json.TryGetJsonProperty(venue, "name");
            if (b.Name != null)
            {
                b.Name = Checkin.SanitizeString(b.Name);
            }

            string verif = Json.TryGetJsonProperty(venue, "verified");
            // NOTE: Is this even useful to expose? (A bool property)

            var todos = venue["todos"];

            if (todos != null)
            {
                // temporary hack around lists...

                var subListOne = todos["id"];
                if (subListOne != null)
                {
                    var userSubTree = todos["user"];
                    if (userSubTree != null)
                    {
                        string userIsSelf = Json.TryGetJsonProperty(userSubTree, "relationship");
                        if (userIsSelf != null && userIsSelf == "self")
                        {
                            b.HasTodo = true;
                        }
                    }
                }

                //string htodo = Json.TryGetJsonProperty(todos, "count"); // checkin mode only
                //int i;
                //if (int.TryParse(htodo, CultureInfo.InvariantCulture);
                //if (i > 0)
                //{
                //b.HasTodo = true;
                //}
            }

            var specials = venue["specials"];

            if (specials != null)
            {
                try
                {
                    var cv            = new List <CompactSpecial>();
                    var specialsItems = specials["items"];
                    if (specialsItems != null)
                    {
                        foreach (var special in specialsItems)
                        {
                            if (special != null)
                            {
                                CompactSpecial spo = CompactSpecial.ParseJson(special, b.VenueId);
                                if (spo != null)
                                {
                                    cv.Add(spo);
                                }
                            }
                        }
                    }
                    if (cv.Count > 0)
                    {
                        b.Specials = cv;
                    }
                }
                catch (Exception)
                {
                    // As of 3.4, and a new Foursquare API version, specials
                    // returned are in dictionary format. This prevents cached
                    // data from throwing here.
                }
            }

            var stats = venue["stats"];

            if (stats != null)
            {
                // NOTE: V2: Add these properties to the POCO

                string checkinsCount = Json.TryGetJsonProperty(stats, "checkinsCount");
                int    i;
                if (int.TryParse(checkinsCount, out i))
                {
                    b.CheckinsCount = i;
                }

                string usersCount = Json.TryGetJsonProperty(stats, "usersCount");
            }

            var hereNow = venue["hereNow"];

            if (hereNow != null)
            {
                string hnc = Json.TryGetJsonProperty(hereNow, "count");
                int    hni;
                if (int.TryParse(hnc, out hni))
                {
                    if (hni > 1)
                    {
                        b.HereNow = Json.GetPrettyInt(hni) + " people";
                    }
                    else if (hni == 1)
                    {
                        b.HereNow = "1 person";
                    }
                }
            }

            var pc = venue["categories"];

            if (pc != null)
            {
                // FUTURE: A collection of all the categories.
                foreach (var category in pc)
                {
                    // NOTE: For this version, just grabbing the first categ.
                    b.PrimaryCategory = Category.ParseJson(category);
                    break;
                }
            }

            var contact = venue["contact"];

            if (contact != null)
            {
                b.Phone = Json.TryGetJsonProperty(contact, "phone");
                // NOTE: VENUE TWITTER?
            }

            b.VenueUri = new Uri(
                string.Format(
                    CultureInfo.InvariantCulture,
                    "/Views/Venue.xaml?id={0}&name={1}",
                    Uri.EscapeDataString(b.VenueId),
                    Uri.EscapeDataString(b.Name)), UriKind.Relative);

            return(b);
        }