/* * Copyright 2014 Artem Chikin * Copyright 2014 Artem Herasymchuk * Copyright 2014 Tom Krywitsky * Copyright 2014 Henry Pabst * Copyright 2014 Bradley Simons * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ca.ualberta.cmput301w14t08.geochan.models; import java.util.Calendar; import java.util.Date; import java.util.concurrent.TimeUnit; import android.os.Parcel; import android.os.Parcelable; /** * Handles all operations of threads in the application. * It aggregates a Comment object and stores the extra * information that is needed to represent a ThreadComment * (the title). * * @author Henry Pabst * @author Artem Chikin * */ public class ThreadComment implements Parcelable { private Comment bodyComment; private String title; private long id; /** * Constructs a ThreadComment object. */ public ThreadComment() { super(); this.title = "No title"; this.bodyComment = new Comment(); Long.parseLong(bodyComment.getId()); } /** * Constructs the ThreadComment object and sets the title, * body comment and id. * @param bodyComment the body comment * @param title the title */ public ThreadComment(Comment bodyComment, String title) { super(); this.title = title; this.id = Long.parseLong(bodyComment.getId()); this.bodyComment = bodyComment; } /** * Determines the distance between the Thread (defined by the GeoLocation of * the top comment) and the provided GeoLocation in terms of coordinates. * * @param geo * The GeoLocation we want to determine the distance from. * @return The distance, in terms of coordinates, between the Thread and the * passed GeoLocation. */ public double getDistanceFrom(GeoLocation geo) { GeoLocation loc = this.getBodyComment().getLocation(); double dist = loc.distance(geo); return dist; } /** * Determines the time passed between when the Thread was posted and the * passed Date in terms of number of hours. * * @param date * The Date we are comparing with. * @return The number of hours between when the Thread was posted and the * passed Date. Returns a minimum of 0.5. */ public double getTimeFrom(Date date) { Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); cal1.setTime(this.getThreadDate()); cal2.setTime(date); long t1 = cal1.getTimeInMillis(); long t2 = cal2.getTimeInMillis(); if (TimeUnit.MILLISECONDS.toHours(Math.abs(t1 - t2)) < 1) { return 0.5; } else { return TimeUnit.MILLISECONDS.toHours(Math.abs(t1 - t2)); } } /** * Determines the score of a thread relevant to a GeoLocation. * * @param geo * The GeoLocation relevant to sorting. In sorting, the * Thread.sortLoc GeoLocation of the sorting thread is used and * should be set in the fragment. * @return The score of the comment in relation to the user's location and * current time. */ public double getScoreFromUser(GeoLocation geo) { int distConst = 25; int timeConst = 10; long maxScore = 100000000; double minScore = 0.0001; if (geo == null) { return 0; } double distScore = distConst * (1 / Math.sqrt(this.getDistanceFrom(geo))); double timeScore = timeConst * (1 / Math.sqrt(this.getTimeFrom(new Date()))); if (distScore + timeScore > maxScore) { return maxScore; } else if (distScore + timeScore < minScore) { return minScore; } else { return distScore + timeScore; } } /** * Searches a parent comment recursively for a child comment identified * by its ElasticSearch id. * @param parent the parent comment * @param id the id of the comment to search for * @return the found comment, or null if no such comment was found */ public Comment findCommentById(Comment parent, String id) { Comment c = null; if (parent.getId().equals(id)) { c = parent; } for (Comment child : parent.getChildren()) { Comment c2 = findCommentById(child, id); if (c2 != null) { c = c2; } } return c; } /** * Describes any special objects contained in the Parcelable representation. * Not used in our implementation. */ @Override public int describeContents() { return 0; } /** * Builds a Parcel from a ThreadComment object. * @param dest the destination Parcel * @param flags contextual flags */ @Override public void writeToParcel(Parcel dest, int flags) { dest.writeParcelable(getBodyComment(), flags); dest.writeValue(title); dest.writeValue(id); } /** * Constructs a ThreadComment object from a Parcel. * @param in the Parcel */ public ThreadComment(Parcel in) { super(); this.setBodyComment((Comment) in.readValue(getClass().getClassLoader())); this.setTitle((String) in.readValue(getClass().getClassLoader())); this.setId((long) in.readLong()); } /** * Creates ThreadComments from Parcels */ public static final Parcelable.Creator<ThreadComment> CREATOR = new Parcelable.Creator<ThreadComment>() { public ThreadComment createFromParcel(Parcel in) { return new ThreadComment(in); } public ThreadComment[] newArray(int size) { return new ThreadComment[size]; } }; /* Getters and setters below */ public Date getThreadDate() { return getBodyComment().getCommentDate(); } public void setThreadDate(Date threadDate) { getBodyComment().setCommentDate(threadDate); } public String getId() { return Long.toString(id); } public void setId(long id) { this.id = id; } public Comment getBodyComment() { return bodyComment; } public void setBodyComment(Comment bodyComment) { this.bodyComment = bodyComment; Long.parseLong(bodyComment.getId()); } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }