package ca.ualberta.cs.team5geotopics; import java.util.ArrayList; import java.util.StringTokenizer; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.location.Location; import android.net.ConnectivityManager; import android.provider.Settings.Secure; import android.util.Log; // code adapted from http://android-developers.blogspot.ca/2011/03/identifying-app-installations.html /** * Holds all the data that the individual user whom is using the application * creates/modifies. This includes top-level comments and replies and makes the * view availible when the user goes to "My Comments" from the start screen. * */ @SuppressWarnings("rawtypes") public class User extends AModel<AView> { private static UserIO userIO = new UserIO(); private UserLocationServices userLocation = new UserLocationServices(); transient private static User myself; transient private boolean ioDisabled = false; transient private boolean needUpdate = false; transient private BroadcastReceiver webConnectionReceiver; // User Profile Saved Variables private String mID; private ArrayList<String> mBookMarks; private ArrayList<String> mFavourites; private ArrayList<String> mComments; private String userName; private String biography; private String contactInfo; private Bitmap profilePic; private User() { mBookMarks = new ArrayList<String>(); mFavourites = new ArrayList<String>(); mComments = new ArrayList<String>(); this.mID = Secure.getString(userLocation.getContext() .getContentResolver(), Secure.ANDROID_ID); setUserName("Anonymous"); webConnectionReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (userLocation.isNetworkAvailable() && needUpdate == true) { Log.w("Connectivity", "Pushing profile update"); syncUser(); needUpdate = false; } } }; userLocation.getContext().registerReceiver(webConnectionReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); } public void setmID(String mID){ this.mID = mID; } /** * Returns a single instance of the User. This is a lazy implementation and * will only create the single instance (if it does not exist) upon request. * * @return myself The instance of the current user */ public static User getInstance() { if (myself == null) { myself = userIO.loadUser(); if (myself == null) { myself = new User(); } } return myself; } /** * Initialises the user with a test setup. Use and edit this function if the * regular implementation of user has a dependency you need to change in * order for proper testing. * */ public void testSetup() { this.mComments = new ArrayList<String>(); ioDisabled = true; }; /** * Returns the profile ID associated with this profile * * @return The unique profile ID */ public String getProfileID() { Log.w("MID", "Profile ID: " + this.mID); return this.mID; } /** * This empties the local hot list of authored comments. This will not clear * any comments written to disk it will only clear the hot versions that * have been put into the list. * */ public void clearLocalMyComments() { mComments.clear(); } /** * This empties the local hot list of favourite comments. This will not clear * any comments written to disk it will only clear the hot versions that * have been put into the list. * */ public void clearLocalMyFavrouties() { mFavourites.clear(); } /** * This empties the local hot list of bookmarked comments. This will not clear * any comments written to disk it will only clear the hot versions that * have been put into the list. * */ public void clearLocalMyBookmarks() { mBookMarks.clear(); } /** * Messages to read and write dependent files * * @return id The ID of the file containing comment */ public String readInstallIDFile() { return userIO.readInstallIDFile(); } /** * Writes the users install files back to disk. This includes the users * unique ID and their post count. This info needs to be stored as it is * used to generate unique post ID's for any new comments the user makes. * Their Post's ID's is a combination of their ID and their post count. */ public void writeInstallFiles() { userIO.writeInstallFiles(); } /** * Reads the users post count off disk. This number is used to track how * many comments the user has posted. Its most common use is to be used in * combination with the user ID to create unique ID's for a users posts. * * @return postCount The post count of the user */ public String readPostCount() { return userIO.readPostCount(); } public void updatePostCountFile() { userIO.updatePostCountFile(); } /** * Checks if local install files exist. This does a check to see if the * files which sound contain the info exist in the applications file system. * It does not check that the contents have anything useful in them. * * @return boolean If the installation and post count exist */ public boolean installFilesExist() { return userIO.installFilesExist(); } /** * Adds a comment to the local hot list of User comments. Will notify any * views watching the user class and write the list out to disk. * * @param comment * The comment to be added to the local list. */ public void addToMyComments(CommentModel comment) { String ID = generateIDString(comment); Log.w("MyComments", ID); mComments.add(ID); userIO.writeUser(this, ioDisabled); Log.w("User", "7"); } /** * Used to get a copy of the array of my comments. Used mostly to display * the list in a view. * * @return this.mComments The ArrayList<CommentModel> of comments. */ public ArrayList<String> getMyComments() { return this.mComments; } /** * Checks if the supplied ID is inside the users bookmarks. Most useful for * the User Controller to decide if it needs to add a comment ID to the * bookmarks array or remove it. Also used by the views to determine if a * comment is bookmarked. * * @param ID * The ID of the comment we are checking * @return */ public boolean inBookmarks(CommentModel comment) { String ID = generateIDString(comment); if (mBookMarks == null) { Log.w("Bookmark", "NULL"); } return mBookMarks.contains(ID); } /** * Adds a comment ID to the bookmarks array. Does not check for duplicates. * * @param ID * The comment ID */ public void addBookmark(CommentModel comment) { String ID = generateIDString(comment); Log.w("Bookmark", "Adding: " + ID); mBookMarks.add(ID); Log.w("User", "1"); userIO.writeUser(this, ioDisabled); } /** * Removes a comment ID from the bookmarks array. Does not check to see if * it exists before removing just removes IF it exists. * * @param ID * The comment ID */ public void removeBookmark(CommentModel comment) { String ID = generateIDString(comment); Log.w("Bookmark", "Removing: " + ID); mBookMarks.remove(ID); Log.w("User", "2"); userIO.writeUser(this, ioDisabled); } /** * Checks if the supplied ID is inside the users bookmarks. Most useful for * the User Controller to decide if it needs to add a comment ID to the * bookmarks array or remove it. Also used by the views to determin if a * comment is bookmarked. * * @param ID * The ID of the comment we are checking * @return */ public boolean inFavourites(CommentModel comment) { String ID = generateIDString(comment); return mFavourites.contains(ID); } /** * Adds a comment ID to the bookmarks array. Does not check for duplicates. * * @param ID * The comment ID */ public void addFavourite(CommentModel comment) { String ID = generateIDString(comment); Log.w("Favourites", "Adding: " + ID); mFavourites.add(ID); Log.w("User", "3"); userIO.writeUser(this, ioDisabled); } /** * Removes a comment ID from the bookmarks array. Does not check to see if * it exists before removing just removes IF it exists. * * @param ID * The comment ID */ public void removeFavourite(CommentModel comment) { String ID = generateIDString(comment); Log.w("Favourites", "Removing: " + ID); mFavourites.remove(ID); Log.w("User", "4"); userIO.writeUser(this, ioDisabled); } /** * Builds a special comment ID for simple storage. This is * parentID:CommentID. This allows us to store both as one string then break * it apart to get it the individual parts back later. * * @param comment * THe comment * @return */ public String generateIDString(CommentModel comment) { return comment.getmParentID() + ":" + comment.getmEsID(); } /** * Breaks up an ID string and returns the parent ID portion. Format is * ParentID:CommentID * * @param ID * The full ID String * @return the parent ID */ public String breakParentID(String ID) { return this.tokenizeID(ID).get(0); } /** * Breaks up an ID string and returns the comment ID portion. Format is * ParentID:CommentID * * @param ID * The full ID String * @return the comment ID */ public String breakID(String ID) { return this.tokenizeID(ID).get(1); } /** * Tokenizes an ID string using ':' as the delimiter. * * @param ID * The ID string * @return An array list of the token strings */ private ArrayList<String> tokenizeID(String ID) { ArrayList<String> parts = new ArrayList<String>(); StringTokenizer st = new StringTokenizer(ID, ":"); while (st.hasMoreTokens()) { parts.add(st.nextToken()); } return parts; } /** * Used to get the usersCurrentLocation, available at any time. The users * Location is optionally used (by default) when a comment is * created/edited. Users location is also used any time the application * calls a user-location based sorting function * * If no provider is enabled it returns the users last stored location. * * @return User's Current/Last Known Location */ public Location getCurrentLocation() { return userLocation.getCurrentLocation(); } /** * Returns the array of strings representing the ID's necessary to get the * comments in my bookmarks from the web or the cache. * * @return Array of the IDs <String> */ public ArrayList<String> getMyBookmarks() { return this.mBookMarks; } /** * Returns the array of strings representing the ID's necessary to get the * comments in my favourites from the web or the cache. * * @return Array of the IDs <String> */ public ArrayList<String> getMyFavourites() { return this.mFavourites; } /** * Returns the profile picture associated with this profile. Used to display * the profile pic in the UI. * * @return A profiles profile picture. */ public Bitmap getProfilePic() { return profilePic; } /** * Sets a new profile picture. This is something a user might do for their * own profile but should not be able to be done to ones we do not own. * * @param profilePic * The new profile pic */ public void setProfilePic(Bitmap profilePic) { this.profilePic = profilePic; Log.w("User", "5"); } /** * Returns the contact information associated with this profile. Used to * display the info in the UI. * * @return The profile uses contact info */ public String getContactInfo() { return contactInfo; } /** * Sets a new contact info for the user. Should be a single string * containing an e-mail address or a twitter handle, etc. * * @param contactInfo * The new contact info. */ private void setContactInfo(String contactInfo) { this.contactInfo = contactInfo; } /** * Gets the biography for the user profile. Used to display this info in the * UI. * * @return Profile biography */ public String getBiography() { return biography; } /** * Sets a new user biography. Should only be able to set your own biography * not others. * * @param biography * The new biography */ private void setBiography(String biography) { this.biography = biography; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } /** * Updates the local profile with new information then sync's it online. * * @param userName * The new username * @param contactInfo * The new contact Info * @param bio * The new Bio * @param profile * The new profile picture */ public void update(String userName, String contactInfo, String bio, Bitmap profile) { this.setUserName(userName); this.setContactInfo(contactInfo); this.setBiography(bio); this.setProfilePic(profile); userIO.writeUser(this, ioDisabled); this.syncUser(); } /** * This will sync the user class with the online storage. If web is * unavailable then flag the user for update once it comes online. */ private void syncUser() { ProfilePush pusher = new ProfilePush(); if (userLocation.isNetworkAvailable()) { pusher.pushProfile(this); needUpdate = false; } else { needUpdate = true; } } /** * Used to add OR remove a comment ID from the favourites's list. If the ID * exists its removed, else its added. * * @param ID * The comment ID */ public void favourite(CommentModel comment) { if (comment != null) { if (!(inFavourites(comment))) { addFavourite(comment); } else { removeFavourite(comment); } } } /** * Used to add OR remove a comment ID from the bookmark's list. If the ID * exists its removed, else its added. * * @param ID * The comment ID */ public void bookmark(CommentModel comment) { if (!(inBookmarks(comment))) { addBookmark(comment); } else { removeBookmark(comment); } } }