/*
* 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.helpers;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import ca.ualberta.cmput301w14t08.geochan.models.Comment;
import ca.ualberta.cmput301w14t08.geochan.models.GeoLocation;
import ca.ualberta.cmput301w14t08.geochan.models.ThreadComment;
/**
* Helper class. Manages sorting of ArrayLists of different ThreadComments and
* Comments by different measures.
*
* @author Henry Pabst
*
*/
public class SortUtil {
public static final int SORT_DATE_NEWEST = 0;
public static final int SORT_DATE_OLDEST = 1;
@Deprecated
public static final int SORT_SCORE_HIGHEST = 3;
@Deprecated
public static final int SORT_SCORE_LOWEST = 4;
public static final int SORT_USER_SCORE_HIGHEST = 5;
public static final int SORT_USER_SCORE_LOWEST = 6;
public static final int SORT_LOCATION = 7;
public static final int SORT_IMAGE = 8;
private static GeoLocation commentSortGeo = null;
private static GeoLocation threadSortGeo = null;
public static GeoLocation getCommentSortGeo() {
if (commentSortGeo == null) {
return new GeoLocation(0, 0);
}
return commentSortGeo;
}
public static GeoLocation getThreadSortGeo() {
if (threadSortGeo == null) {
return new GeoLocation(0, 0);
}
return threadSortGeo;
}
public static void setCommentSortGeo(GeoLocation geo) {
commentSortGeo = geo;
}
public static void setThreadSortGeo(GeoLocation geo) {
threadSortGeo = geo;
}
/**
* Sorts the ArrayList of ThreadComments passed to it according to the tag
* passed. The passed GeoLocation is used in sorting by location or score.
*
* @param tag
* Tag specifying the sorting method to be used.
* @param threads
* The ArrayList of ThreadComments to be sorted.
*/
public static void sortThreads(int tag, ArrayList<ThreadComment> threads) {
switch (tag) {
case (SORT_DATE_OLDEST):
Collections.sort(threads, sortThreadsByDateOldest());
break;
case (SORT_DATE_NEWEST):
Collections.sort(threads, sortThreadsByDateNewest());
break;
case (SORT_USER_SCORE_HIGHEST):
try{
Collections.sort(threads, sortThreadsByUserScoreHighest());
} catch (NullPointerException e) {
//If the device has never gotten a location, we fall back on
//sorting by newest date, and approximation to relevance.
Collections.sort(threads, sortThreadsByDateNewest());
}
break;
case (SORT_USER_SCORE_LOWEST):
try{
Collections.sort(threads, sortThreadsByUserScoreLowest());
} catch (NullPointerException e){
//Fallback for if the device has never gotten a location.
Collections.sort(threads, sortThreadsByDateOldest());
}
break;
case (SORT_LOCATION):
Collections.sort(threads, sortThreadsByLocation());
break;
}
}
/**
* Sorts the ArrayList of Comments according to the tag passed to it.
* Recursively sorts all the children of these comments according to the
* same measure.
*
* @param tag
* Tag specifying the type of sorting to be done.
* @param coms
* The ArrayList of Comments to be sorted.
*/
public static void sortComments(int tag, ArrayList<Comment> coms) {
switch (tag) {
case (SORT_DATE_OLDEST):
Collections.sort(coms, sortCommentsByDateOldest());
for (Comment c : coms) {
sortComments(tag, c.getChildren());
}
break;
case (SORT_DATE_NEWEST):
Collections.sort(coms, sortCommentsByDateNewest());
for (Comment c : coms) {
sortComments(tag, c.getChildren());
}
break;
case (SORT_LOCATION):
Collections.sort(coms, sortCommentsByLocation());
for (Comment c : coms) {
sortComments(tag, c.getChildren());
}
break;
case (SORT_USER_SCORE_HIGHEST):
Collections.sort(coms, sortCommentsByUserScoreHighest());
for (Comment c : coms) {
sortComments(tag, c.getChildren());
}
break;
case (SORT_USER_SCORE_LOWEST):
Collections.sort(coms, sortCommentsByUserScoreLowest());
for (Comment c : coms) {
sortComments(tag, c.getChildren());
}
break;
case (SORT_IMAGE):
Collections.sort(coms, sortCommentsByImage());
for (Comment c : coms) {
sortComments(tag, c.getChildren());
}
break;
}
}
/**
* Comparator for pushing comments with images to the top. Uses comment date
* to break ties if both comments have images, or do not have images.
*
* @return A comparator used to sort comments by image.
*/
private static Comparator<Comment> sortCommentsByImage() {
return new Comparator<Comment>() {
public int compare(Comment c1, Comment c2) {
if (c1.hasImage() && !(c2.hasImage())) {
return -1;
} else if (!(c1.hasImage()) && c2.hasImage()) {
return 1;
} else if (c1.hasImage() == c2.hasImage()) {
int val = c1.getCommentDate().compareTo(c2.getCommentDate());
if (val < 0) {
return -1;
} else if (val > 0) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing old comments in a thread to the top.
*
* @return a Comparator for sorting Comments by oldest date.
*/
private static Comparator<Comment> sortCommentsByDateOldest() {
return new Comparator<Comment>() {
public int compare(Comment c1, Comment c2) {
int val = c1.getCommentDate().compareTo(c2.getCommentDate());
if (val < 0) {
return -1;
} else if (val > 0) {
return 1;
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing new comments in a thread to the top.
*
* @return A Comparator for sorting Comments by newest Date.
*/
private static Comparator<Comment> sortCommentsByDateNewest() {
return new Comparator<Comment>() {
public int compare(Comment c1, Comment c2) {
int val = c1.getCommentDate().compareTo(c2.getCommentDate());
if (val < 0) {
return 1;
} else if (val > 0) {
return -1;
} else {
return 0;
}
}
};
}
/**
* Returns a comparator for pushing higher scored comments to the top.
*
* @return A Comparator for pushing higher scored comments to the top.
*/
private static Comparator<Comment> sortCommentsByUserScoreHighest() {
return new Comparator<Comment>() {
public int compare(Comment c1, Comment c2) {
double val1 = c1.getScoreFromUser(SortUtil.getCommentSortGeo());
double val2 = c2.getScoreFromUser(SortUtil.getCommentSortGeo());
if (val1 > val2) {
return -1;
} else if (val1 < val2) {
return 1;
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing lower scored comments (relative to user set
* location) to the top.
*
* @return A comparator for sorting comments by score relative to user set
* location.
*/
private static Comparator<Comment> sortCommentsByUserScoreLowest() {
return new Comparator<Comment>() {
public int compare(Comment c1, Comment c2) {
double val1 = c1.getScoreFromUser(SortUtil.getCommentSortGeo());
double val2 = c2.getScoreFromUser(SortUtil.getCommentSortGeo());
if (val1 > val2) {
return 1;
} else if (val1 < val2) {
return -1;
} else {
return 0;
}
}
};
}
/**
* Comparator for sorting comments in a thread based on the current
* SortUtil.commentSortGeo.
*
* @return the comparator
*/
private static Comparator<Comment> sortCommentsByLocation() {
return new Comparator<Comment>() {
public int compare(Comment c1, Comment c2) {
double val1 = c1.getDistanceFrom(SortUtil.getCommentSortGeo());
double val2 = c2.getDistanceFrom(SortUtil.getCommentSortGeo());
if (val1 > val2) {
return 1;
} else if (val1 < val2) {
return -1;
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing old threads to the top.
*
* @return a Comparator for sorting threads by oldest date.
*/
private static Comparator<ThreadComment> sortThreadsByDateOldest() {
return new Comparator<ThreadComment>() {
public int compare(ThreadComment t1, ThreadComment t2) {
int val = t1.getThreadDate().compareTo(t2.getThreadDate());
if (val < 0) {
return -1;
} else if (val > 0) {
return 1;
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing new threads to the top.
*
* @return a Comparator for sorting Comments by newest Date.
*/
private static Comparator<ThreadComment> sortThreadsByDateNewest() {
return new Comparator<ThreadComment>() {
public int compare(ThreadComment t1, ThreadComment t2) {
int val = t1.getThreadDate().compareTo(t2.getThreadDate());
if (val < 0) {
return 1;
} else if (val > 0) {
return -1;
} else {
return 0;
}
}
};
}
/**
* Comparator for passing higher scored Threads to the top.
*
* @return A Comparator used to sort ThreadComments according to highest
* score.
*/
private static Comparator<ThreadComment> sortThreadsByUserScoreHighest() {
return new Comparator<ThreadComment>() {
public int compare(ThreadComment t1, ThreadComment t2) {
double val1 = t1.getScoreFromUser(SortUtil.getThreadSortGeo());
double val2 = t2.getScoreFromUser(SortUtil.getThreadSortGeo());
if (val1 > val2) {
return -1;
} else if (val1 < val2) {
return 1;
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing lower scored Threads to the top.
*
* @return A Comparator used to sort ThreadComments according to lowest
* score.
*/
private static Comparator<ThreadComment> sortThreadsByUserScoreLowest() {
return new Comparator<ThreadComment>() {
public int compare(ThreadComment t1, ThreadComment t2) {
double val1 = t1.getScoreFromUser(SortUtil.getThreadSortGeo());
double val2 = t2.getScoreFromUser(SortUtil.getThreadSortGeo());
if (val1 > val2) {
return 1;
} else if (val1 < val2) {
return -1;
} else {
return 0;
}
}
};
}
/**
* Comparator for pushing ThreadComments closer to SortUtil's threadSortGeo
* to the top.
*
* @return A Comparator used to sort ThreadComments according to location.
*/
private static Comparator<ThreadComment> sortThreadsByLocation() {
return new Comparator<ThreadComment>() {
public int compare(ThreadComment t1, ThreadComment t2) {
double val1 = t1.getDistanceFrom(SortUtil.getThreadSortGeo());
double val2 = t2.getDistanceFrom(SortUtil.getThreadSortGeo());
if (val1 > val2) {
return 1;
} else if (val1 < val2) {
return -1;
} else {
return 0;
}
}
};
}
}