DrawerItem.java revision 2b806edc62eb8e83c77edc471fda4652281a15c4
11799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal/*
21799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * Copyright (C) 2013 The Android Open Source Project
31799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal *
41799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * Licensed under the Apache License, Version 2.0 (the "License");
51799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * you may not use this file except in compliance with the License.
61799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * You may obtain a copy of the License at
71799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal *
81799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal *      http://www.apache.org/licenses/LICENSE-2.0
91799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal *
101799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * Unless required by applicable law or agreed to in writing, software
111799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * distributed under the License is distributed on an "AS IS" BASIS,
121799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * See the License for the specific language governing permissions and
141799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal * limitations under the License.
151799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal */
161799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
171799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalpackage com.android.mail.adapter;
181799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
1978893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sappersteinimport android.view.LayoutInflater;
2078893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sappersteinimport android.view.View;
2178893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sappersteinimport android.view.ViewGroup;
2278893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sappersteinimport android.widget.TextView;
2378893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sapperstein
242b806edc62eb8e83c77edc471fda4652281a15c4James Lemieuximport com.android.bitmap.BitmapCache;
251799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.R;
26c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdonimport com.android.mail.bitmap.ContactResolver;
271799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.providers.Account;
281799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.providers.Folder;
29b958701ff6a98a7d95930e61d91104bb5db3299aRohan Shahimport com.android.mail.ui.AccountItemView;
301799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.ui.ControllableActivity;
311799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.ui.FolderItemView;
3273c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantlerimport com.android.mail.utils.FolderUri;
331799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.utils.LogTag;
341799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalimport com.android.mail.utils.LogUtils;
351799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
36c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon
37f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal/**
38f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal * An element that is shown in the {@link com.android.mail.ui.FolderListFragment}. This class is
39f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal * only used for elements that are shown in the {@link com.android.mail.ui.DrawerFragment}.
40f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal * This class is an enumeration of a few element types: Account, a folder, a recent folder,
41f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal * or a header (a resource string). A {@link DrawerItem} can only be one type and can never
42f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal * switch types. Items are created using methods like
4369086fd48a2e1565806dfd953116d11ab735ab84Tony Mantler * {@link DrawerItem#ofAccount(ControllableActivity, Account, int, boolean, BitmapCache,
4469086fd48a2e1565806dfd953116d11ab735ab84Tony Mantler * ContactResolver)},
4569086fd48a2e1565806dfd953116d11ab735ab84Tony Mantler * {@link DrawerItem#ofWaitView(ControllableActivity)}, etc.
46f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal *
4773c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler * Once created, the item can create a view using
4873c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler * {@link #getView(android.view.View, android.view.ViewGroup)}.
49f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal */
501799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwalpublic class DrawerItem {
511799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    private static final String LOG_TAG = LogTag.getLogTag();
521799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public final Folder mFolder;
531799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public final Account mAccount;
54773f2e6e6994f38bf7d2679f2412d2f14f22c424Andrew Sapperstein    private final int mResource;
559860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah    /** True if the drawer item represents the current account, false otherwise */
56773f2e6e6994f38bf7d2679f2412d2f14f22c424Andrew Sapperstein    private final boolean mIsSelected;
571799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** Either {@link #VIEW_ACCOUNT}, {@link #VIEW_FOLDER} or {@link #VIEW_HEADER} */
581799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public final int mType;
591799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** A normal folder, also a child, if a parent is specified. */
601799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public static final int VIEW_FOLDER = 0;
611799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** A text-label which serves as a header in sectioned lists. */
621799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public static final int VIEW_HEADER = 1;
631799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** An account object, which allows switching accounts rather than folders. */
641799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public static final int VIEW_ACCOUNT = 2;
65ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    /** An expandable object for expanding/collapsing more of the list */
669860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah    public static final int VIEW_WAITING_FOR_SYNC = 3;
6710f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal    /** The value (1-indexed) of the last View type.  Useful when returning the number of types. */
6810f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal    private static final int LAST_FIELD = VIEW_WAITING_FOR_SYNC + 1;
6910f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal
70ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    /** TODO: On adding another type, be sure to change getViewTypes() */
711799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
721799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** The parent activity */
731799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    private final ControllableActivity mActivity;
741799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    private final LayoutInflater mInflater;
751799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
76f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal    // TODO(viki): Put all these constants in an interface.
771799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
78f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal     * Either {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT} or {@link #FOLDER_OTHER} when
791799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * {@link #mType} is {@link #VIEW_FOLDER}, or an {@link #ACCOUNT} in the case of
809860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     * accounts, and {@link #INERT_HEADER} otherwise.
811799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
821799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public final int mFolderType;
832c17fb1cd5176be06b80b98467b75c67c8d6fa70Rohan Shah    /** Non existent item or folder type not yet set */
842c17fb1cd5176be06b80b98467b75c67c8d6fa70Rohan Shah    public static final int UNSET = 0;
851799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** An unclickable text-header visually separating the different types. */
861799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public static final int INERT_HEADER = 0;
87f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal    /** An inbox folder: Inbox, ...*/
88f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal    public static final int FOLDER_INBOX = 1;
891799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** A folder from whom a conversation was recently viewed */
901799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public static final int FOLDER_RECENT = 2;
91f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal    /** A non-inbox folder that is shown in the "everything else" group. */
92f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal    public static final int FOLDER_OTHER = 3;
931799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** An entry for the accounts the user has on the device. */
941799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    public static final int ACCOUNT = 4;
951799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
961799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /** True if this view is enabled, false otherwise. */
975fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal    private final boolean mIsEnabled;
981799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
99c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon    private BitmapCache mImagesCache;
100c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon    private ContactResolver mContactResolver;
101c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon
1027b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    @Override
1037b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    public String toString() {
1047b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        switch(mType) {
1057b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal            case VIEW_FOLDER:
1067b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal                return folderToString();
1077b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal            case VIEW_HEADER:
1087b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal                return headerToString();
1097b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal            case VIEW_ACCOUNT:
1107b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal                return accountToString();
1117b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal            case VIEW_WAITING_FOR_SYNC:
1127b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal                return waitToString();
1137b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        }
1147b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        // Should never come here.
1157b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        return null;
1167b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    }
1177b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal
1181799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
119f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * Creates a drawer item with every instance variable specified.
1209860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     *
121f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param type the type of the item. This must be a VIEW_* element
122f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param activity the underlying activity
123f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param folder a non-null folder, if this is a folder type
1249860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     * @param folderType the type of the folder. For folders this is:
125f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal     *            {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT},
126f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal     *            {@link #FOLDER_OTHER}, or for non-folders this is
1279860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     *            {@link #ACCOUNT}, or {@link #INERT_HEADER}
128f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param account the account object, for an account drawer element
1299860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     * @param resource either the string resource for a header, or the unread
1309860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     *            count for an account.
1319860f5ebcd77bce62f76ccf46cee939fe4f2858aRohan Shah     * @param isCurrentAccount true if this item is the current account
132f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     */
133f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal    private DrawerItem(int type, ControllableActivity activity, Folder folder, int folderType,
134c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon            Account account, int resource, boolean isCurrentAccount, BitmapCache cache,
135c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon            ContactResolver contactResolver) {
136f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mActivity = activity;
137f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mFolder = folder;
138f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mFolderType = folderType;
139f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mAccount = account;
140f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mResource = resource;
141b905f0ea18ee0dc5774adb29c57cd7c122058c71Rohan Shah        mIsSelected = isCurrentAccount;
142f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mInflater = LayoutInflater.from(activity.getActivityContext());
143f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        mType = type;
1445fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal        mIsEnabled = calculateEnabled();
145c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon        mImagesCache = cache;
146c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon        mContactResolver = contactResolver;
147f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal    }
148f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal
149f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal    /**
1501799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * Create a folder item with the given type.
15173c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler     *
152f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param activity the underlying activity
1531799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param folder a folder that this item represents
154f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal     * @param folderType one of {@link #FOLDER_INBOX}, {@link #FOLDER_RECENT} or
155f61bf1c68006b023052860bbed4cad78f4a3fc41Vikram Aggarwal     * {@link #FOLDER_OTHER}
156f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @return a drawer item for the folder.
1571799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
158f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal    public static DrawerItem ofFolder(ControllableActivity activity, Folder folder,
159f479bd60d01e5e752620bcb946d079c697a543f6Andrew Sapperstein            int folderType) {
160c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon        return new DrawerItem(VIEW_FOLDER, activity, folder,  folderType, null, -1, false,
161c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon                null, null);
1621799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
1631799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
1647b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    private String folderToString() {
1657b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        final StringBuilder sb = new StringBuilder("[DrawerItem ");
1667b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(" VIEW_FOLDER ");
1677b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(", mFolder=");
1687b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(mFolder);
1697b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(", mFolderType=");
1707b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(mFolderType);
1717b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append("]");
1727b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        return sb.toString();
1737b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    }
1747b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal
1751799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
1761799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * Creates an item from an account.
177f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param activity the underlying activity
178f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param account the account to create a drawer item for
179f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param unreadCount the unread count of the account, pass zero if
180f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param isCurrentAccount true if the account is the current account, false otherwise
181f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @return a drawer item for the account.
1821799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
183f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal    public static DrawerItem ofAccount(ControllableActivity activity, Account account,
184c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon            int unreadCount, boolean isCurrentAccount, BitmapCache cache,
185c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon            ContactResolver contactResolver) {
186f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal        return new DrawerItem(VIEW_ACCOUNT, activity, null, ACCOUNT, account, unreadCount,
187c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon                isCurrentAccount, cache, contactResolver);
1881799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
1891799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
1907b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    private String accountToString() {
1917b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        final StringBuilder sb = new StringBuilder("[DrawerItem ");
1927b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(" VIEW_ACCOUNT ");
1937b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(", mAccount=");
1947b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(mAccount);
1957b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append("]");
1967b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        return sb.toString();
1977b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    }
1987b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal
1991799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
2001799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * Create a header item with a string resource.
2017e654a970f73e3ebfd6895caa5072c6dcc9e7fb5Rohan Shah     *
202f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @param activity the underlying activity
2031799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param resource the string resource: R.string.all_folders_heading
204f986f32c19f9394e8564b246655b58088f8760adVikram Aggarwal     * @return a drawer item for the header.
2051799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
206f479bd60d01e5e752620bcb946d079c697a543f6Andrew Sapperstein    public static DrawerItem ofHeader(ControllableActivity activity, int resource) {
207c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon        return new DrawerItem(VIEW_HEADER, activity, null, INERT_HEADER, null, resource, false,
208c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon                null, null);
209ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    }
210ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah
2117b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    private String headerToString() {
2127b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        final StringBuilder sb = new StringBuilder("[DrawerItem ");
2137b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(" VIEW_HEADER ");
2147b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(", mResource=");
2157b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append(mResource);
2167b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        sb.append("]");
2177b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        return sb.toString();
2187b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    }
2197b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal
220ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    /**
22110f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * Create a "waiting for initialization" item.
2227e654a970f73e3ebfd6895caa5072c6dcc9e7fb5Rohan Shah     *
22310f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * @param activity the underlying activity
22410f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * @return a drawer item with an indeterminate progress indicator.
22510f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     */
226f479bd60d01e5e752620bcb946d079c697a543f6Andrew Sapperstein    public static DrawerItem ofWaitView(ControllableActivity activity) {
227c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon        return new DrawerItem(VIEW_WAITING_FOR_SYNC, activity, null, INERT_HEADER, null, -1, false,
228c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon                null, null);
22910f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal    }
23010f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal
2313b965d78774a42358ce6bbdcc43b4c8df130a60eScott Kennedy    private static String waitToString() {
2327b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal        return "[DrawerItem VIEW_WAITING_FOR_SYNC ]";
2337b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal    }
2347b34ba1bd4c6e69f52758961619d172bf9bf4021Vikram Aggarwal
235f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal    /**
236f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * Returns a view for the given item. The method signature is identical to that required by a
237f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * {@link android.widget.ListAdapter#getView(int, android.view.View, android.view.ViewGroup)}.
238f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     */
23973c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler    public View getView(View convertView, ViewGroup parent) {
2401799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        final View result;
2411799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        switch (mType) {
2421799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_FOLDER:
243f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal                result = getFolderView(convertView, parent);
2441799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                break;
2451799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_HEADER:
246f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal                result = getHeaderView(convertView, parent);
2471799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                break;
2481799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_ACCOUNT:
249f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal                result = getAccountView(convertView, parent);
2501799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                break;
25110f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal            case VIEW_WAITING_FOR_SYNC:
252f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal                result = getEmptyView(convertView, parent);
25310f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal                break;
2541799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            default:
2551799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                LogUtils.wtf(LOG_TAG, "DrawerItem.getView(%d) for an invalid type!", mType);
2561799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                result = null;
2571799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        }
2581799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        return result;
2591799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
2601799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
2611799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
262ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah     * Book-keeping for how many different view types there are. Be sure to
263ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah     * increment this appropriately once adding more types as drawer items
264ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah     * @return number of different types of view items
265ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah     */
266ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    public static int getViewTypes() {
26710f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal        return LAST_FIELD;
268ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    }
269ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah
270ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    /**
271f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * Returns whether this view is enabled or not. An enabled view is one that accepts user taps
272f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * and acts upon them.
273f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * @return true if this view is enabled, false otherwise.
2741799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
2755fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal    public boolean isItemEnabled() {
2765fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal        return mIsEnabled;
2775fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal    }
2785fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal
2795fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal    /** Calculate whether the item is enabled */
2805fb0d88262b03863480b71b67c0a0d2088e7b660Vikram Aggarwal    private boolean calculateEnabled() {
2811799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        switch (mType) {
2821799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_HEADER :
2831799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                // Headers are never enabled.
2841799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                return false;
2851799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_FOLDER :
2861799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                // Folders are always enabled.
2871799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                return true;
2881799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_ACCOUNT:
2898bcb7c5c37ffd5a1a0c5f4efbcab084830d5e033Rohan Shah                // Accounts are always enabled.
2908bcb7c5c37ffd5a1a0c5f4efbcab084830d5e033Rohan Shah                return true;
29110f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal            case VIEW_WAITING_FOR_SYNC:
29210f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal                // Waiting for sync cannot be tapped, so never enabled.
29310f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal                return false;
2941799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            default:
2951799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                LogUtils.wtf(LOG_TAG, "DrawerItem.isItemEnabled() for invalid type %d", mType);
2961799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                return false;
2971799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        }
2981799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
2991799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
3001799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
3011799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * Returns whether this view is highlighted or not.
3021799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     *
30373c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler     *
304f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * @param currentFolder The current folder, according to the
305f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *                      {@link com.android.mail.ui.FolderListFragment}
306f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * @param currentType The type of the current folder. We want to only highlight a folder once.
307f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *                    A folder might be in two places at once: in "All Folders", and in
308f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *                    "Recent Folder". Valid types of selected folders are :
309f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *                    {@link DrawerItem#FOLDER_INBOX}, {@link DrawerItem#FOLDER_RECENT} or
310f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *                    {@link DrawerItem#FOLDER_OTHER}, or {@link DrawerItem#UNSET}.
311f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal
312f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * @return true if this DrawerItem results in a view that is highlighted (this DrawerItem is
313f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *              the current folder.
3141799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
31573c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler    public boolean isHighlighted(FolderUri currentFolder, int currentType) {
3161799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        switch (mType) {
3171799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_HEADER :
3181799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                // Headers are never highlighted
3191799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                return false;
320e286407580a25914a122480540a2f0be0affcde4Rohan Shah            case VIEW_FOLDER:
321e286407580a25914a122480540a2f0be0affcde4Rohan Shah                // True if folder types and URIs are the same
32273c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler                if (currentFolder != null && mFolder != null && mFolder.folderUri != null) {
32373c015e14f5f0f729e0c77603d4903bafdf848bfTony Mantler                    return (mFolderType == currentType) && mFolder.folderUri.equals(currentFolder);
324e286407580a25914a122480540a2f0be0affcde4Rohan Shah                }
325e286407580a25914a122480540a2f0be0affcde4Rohan Shah                return false;
3261799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            case VIEW_ACCOUNT:
3271799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                // Accounts are never highlighted
3281799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                return false;
32910f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal            case VIEW_WAITING_FOR_SYNC:
33010f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal                // Waiting for sync cannot be tapped, so never highlighted.
33110f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal                return false;
3321799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            default:
3331799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                LogUtils.wtf(LOG_TAG, "DrawerItem.isHighlighted() for invalid type %d", mType);
3341799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal                return false;
3351799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        }
3361799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
3371799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
3381799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
3391799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * Return a view for an account object.
340f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *
3411799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param convertView a view, possibly null, to be recycled.
3421799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param parent the parent viewgroup to attach to.
3431799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @return a view to display at this position.
3441799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
345f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal    private View getAccountView(View convertView, ViewGroup parent) {
346b958701ff6a98a7d95930e61d91104bb5db3299aRohan Shah        final AccountItemView accountItemView;
3471799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        if (convertView != null) {
348b958701ff6a98a7d95930e61d91104bb5db3299aRohan Shah            accountItemView = (AccountItemView) convertView;
3491799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        } else {
350b958701ff6a98a7d95930e61d91104bb5db3299aRohan Shah            accountItemView =
35178893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sapperstein                    (AccountItemView) mInflater.inflate(R.layout.account_item, parent, false);
3521799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        }
353c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon        accountItemView.bind(mActivity.getActivityContext(), mAccount, mIsSelected, mImagesCache,
354c7849b23a73d699b5e7f199f0a3afce5b9dee7a6Martin Hibdon                mContactResolver);
355b958701ff6a98a7d95930e61d91104bb5db3299aRohan Shah        return accountItemView;
3561799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
3571799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
3581799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
359f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     * Returns a text divider between divisions.
360f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *
3611799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param convertView a previous view, perhaps null
3621799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param parent the parent of this view
3631799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @return a text header at the given position.
3641799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
365f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal    private View getHeaderView(View convertView, ViewGroup parent) {
3661799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        final TextView headerView;
3671799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        if (convertView != null) {
3681799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            headerView = (TextView) convertView;
3691799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        } else {
37027abcb2d58204bf9fbb0f72cdd103ccce6fc90c3Andrew Sapperstein            headerView = (TextView) mInflater.inflate(R.layout.folder_list_header, parent, false);
3711799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        }
3721799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        headerView.setText(mResource);
3731799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        return headerView;
3741799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
3751799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
3761799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    /**
3771799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * Return a folder: either a parent folder or a normal (child or flat)
3781799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * folder.
379f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *
3801799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @param convertView a view, possibly null, to be recycled.
3811799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     * @return a view showing a folder at the given position.
3821799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal     */
383f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal    private View getFolderView(View convertView, ViewGroup parent) {
3841799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        final FolderItemView folderItemView;
3851799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        if (convertView != null) {
3861799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            folderItemView = (FolderItemView) convertView;
3871799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        } else {
3881799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal            folderItemView =
38978893c83e9dab75ac9fd5d4e22ceee6b32e87f09Andrew Sapperstein                    (FolderItemView) mInflater.inflate(R.layout.folder_item, parent, false);
3901799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        }
391f479bd60d01e5e752620bcb946d079c697a543f6Andrew Sapperstein        folderItemView.bind(mFolder, mActivity);
3922ad896272a5739972766d6cce095fae94332f099Rohan Shah        folderItemView.setIcon(mFolder);
3931799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal        return folderItemView;
3941799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal    }
395ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah
396ad4c1856e25ab4edf796c220dd25afcbe823276aRohan Shah    /**
39710f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * Return a view for the 'Waiting for sync' item with the indeterminate progress indicator.
398f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal     *
39910f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * @param convertView a view, possibly null, to be recycled.
40010f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * @param parent the parent hosting this view.
40110f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     * @return a view for "Waiting for sync..." at given position.
40210f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal     */
403f51ce08b103e901883eb4e340ee9ad64766c75a2Vikram Aggarwal    private View getEmptyView(View convertView, ViewGroup parent) {
40410f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal        final ViewGroup emptyView;
40510f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal        if (convertView != null) {
40610f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal            emptyView = (ViewGroup) convertView;
40710f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal        } else {
40810f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal            emptyView = (ViewGroup) mInflater.inflate(R.layout.drawer_empty_view, parent, false);
40910f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal        }
41010f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal        return emptyView;
41110f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal    }
41210f7cd3b693f40aec41dbba572e67ee6184b5a66Vikram Aggarwal
4131799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal}
4141799c1217cb69f1a769285839457d0c05b8a2316Vikram Aggarwal
415