package com.instructure.canvasapi.model;
import android.os.Parcel;
import com.instructure.canvasapi.utilities.APIHelpers;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @author Josh Ruesch
*
* Copyright (c) 2014 Instructure. All rights reserved.
*/
public class Conversation extends CanvasModel<Conversation> {
public enum WorkflowState {READ, UNREAD, ARCHIVED, UNKNOWN}
private long id; // The unique id for the conversation.
private String subject; // Message Subject
private String workflow_state; // The workflowState of the conversation (unread, read, archived)
private String last_message; // 100 character preview of the last message.
private String last_message_at; // Date of the last message sent.
private String last_authored_message_at;
private int message_count; // Number of messages in the conversation.
private boolean subscribed; // Whether or not the user is subscribed to the current message.
private boolean starred; // Whether or not the message is starred.
private List<String> properties = new ArrayList<String>();
private String avatar_url; // The avatar to display. Knows if group, user, etc.
private boolean visible; // Whether this conversation is visible in the current context. Not 100% what that means.
// The IDs of all people in the conversation. EXCLUDING the current user unless it's a monologue.
private List<Long> audience = new ArrayList<Long>();
//TODO: Audience contexts.
// The name and IDs of all participants in the conversation.
private List<BasicUser> participants = new ArrayList<BasicUser>();
// Messages attached to the conversation.
private List<Message> messages = new ArrayList<Message>();
// helper variables
private Date lastMessageDate;
private boolean deleted = false; // Used to set whether or not we've determined it to be deleted with a failed retrofit call.
private String deletedString = ""; // The string to show if something is deleted.
///////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////
public Conversation(boolean deleted, String deletedStringToShow){
this.deleted = deleted;
this.deletedString = deletedStringToShow;
}
///////////////////////////////////////////////////////////////////////////
//region Getters and Setters
///////////////////////////////////////////////////////////////////////////
@Override
public long getId() {
return id;
}
public WorkflowState getWorkflowState() {
if ("unread".equalsIgnoreCase(workflow_state)) {
return WorkflowState.UNREAD;
} else if ("archived".equalsIgnoreCase(workflow_state)) {
return WorkflowState.ARCHIVED;
} else if ("read".equalsIgnoreCase(workflow_state)) {
return WorkflowState.READ;
} else {
return WorkflowState.UNKNOWN;
}
}
public void setId(long id){
this.id = id;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setWorkflowState(WorkflowState state) {
if(state == WorkflowState.UNREAD){
workflow_state = "unread";
} else if (state == WorkflowState.ARCHIVED){
workflow_state = "archived";
} else if (state == WorkflowState.READ){
workflow_state = "read";
} else{
workflow_state = "";
}
}
public void setLastMessage(String message){
this.last_message = message;
}
public String getLastMessagePreview() {
if(deleted){
return deletedString;
}
return last_message;
}
public Date getLastMessageSent() {
if (lastMessageDate == null) {
lastMessageDate = APIHelpers.stringToDate(last_message_at);
}
return lastMessageDate;
}
public Date getLastAuthoredMessageSent() {
Date lastAuthoredDate = null;
if (last_authored_message_at != null) {
lastAuthoredDate = APIHelpers.stringToDate(last_authored_message_at);
}
return lastAuthoredDate;
}
public void setLastMessageSent(Date date) {
lastMessageDate = date;
}
public int getMessageCount() {
return message_count;
}
public String getLastMessageAt(){return last_message_at;}
public String getLastAuthoredMessageAt() { return last_authored_message_at; }
public boolean isSubscribed() {
return subscribed;
}
public void setSubscribed(boolean subscribed){
this.subscribed = subscribed;
}
public boolean isStarred() {
return starred;
}
public void setStarred(boolean starred) {
this.starred = starred;
}
public boolean isLastAuthor() {
for(int i = 0; i < properties.size(); i++)
{
if(properties.get(i).equals("last_author")){
return true;
}
}
return false;
}
public boolean hasAttachments() {
for(int i = 0; i < properties.size(); i++)
{
if(properties.get(i).equals("attachments")){
return true;
}
}
return false;
}
public boolean hasMedia() {
for(int i = 0; i < properties.size(); i++)
{
if(properties.get(i).equals("media_objects")){
return true;
}
}
return false;
}
public List<Long> getAudienceIDs() {
return audience;
}
public List<BasicUser> getAllParticipants() {
return participants;
}
public String getAvatarURL() {
return avatar_url;
}
public boolean isVisible() {
return visible;
}
public boolean isMonologue (long myUserID) {
return determineMonologue(myUserID);
}
public List<Message> getMessages() {
return messages;
}
public String getMessageTitle(long myUserID, String monologue) {
return determineMessageTitle(myUserID,monologue);
}
public boolean isDeleted(){return deleted;}
///////////////////////////////////////////////////////////////////////////
//endregion Getters and Setters
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Required Overrides
///////////////////////////////////////////////////////////////////////////
// We want opposite of natural sorting order of date since we want the newest one to come first
@Override
public Date getComparisonDate() {
//sent messages have a last_authored_message_at that other messages won't. In that case last_message_at can be null,
//but last_authored_message isn't
if(last_authored_message_at != null) {
return getLastAuthoredMessageSent();
}
else {
return getLastMessageSent();
}
}
@Override
public String getComparisonString() {
return getLastMessagePreview();
}
///////////////////////////////////////////////////////////////////////////
// Helpers
///////////////////////////////////////////////////////////////////////////
private boolean determineMonologue(long userID) {
if(audience == null){
return false;
} else if (audience.size() == 0){
return true;
}
for(int i = 0; i < audience.size(); i++){
if(audience.get(i) == userID){
return true;
}
}
return false;
}
private String determineMessageTitle(long myUserID, String monologueDefault) {
if(deleted){
return deletedString;
}
else if (isMonologue(myUserID)) {
return monologueDefault;
}
ArrayList<BasicUser> normalized = new ArrayList<BasicUser>();
//Normalize the message!
for (int i = 0; i < getAllParticipants().size(); i++) {
if (getAllParticipants().get(i).getId() == myUserID) {
continue;
} else {
normalized.add(getAllParticipants().get(i));
}
}
if (normalized.size() > 2) {
return normalized.get(0).getUsername() + String.format(" and %d more", normalized.size() - 1);
} else {
String participants = "";
for (int i = 0; i < normalized.size(); i++) {
if (!participants.equals("")) {
participants += ", ";
}
participants += normalized.get(i).getUsername();
}
return participants;
}
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.id);
dest.writeString(this.workflow_state);
dest.writeString(this.last_message);
dest.writeString(this.last_message_at);
dest.writeInt(this.message_count);
dest.writeByte(subscribed ? (byte) 1 : (byte) 0);
dest.writeByte(starred ? (byte) 1 : (byte) 0);
dest.writeList(this.properties);
dest.writeString(this.avatar_url);
dest.writeByte(visible ? (byte) 1 : (byte) 0);
dest.writeList(this.audience);
dest.writeList(this.participants);
dest.writeList(this.messages);
dest.writeLong(lastMessageDate != null ? lastMessageDate.getTime() : -1);
dest.writeByte(deleted ? (byte) 1 : (byte) 0);
dest.writeString(this.deletedString);
dest.writeString(this.last_authored_message_at);
dest.writeString(this.subject);
}
private Conversation(Parcel in) {
this.id = in.readLong();
this.workflow_state = in.readString();
this.last_message = in.readString();
this.last_message_at = in.readString();
this.message_count = in.readInt();
this.subscribed = in.readByte() != 0;
this.starred = in.readByte() != 0;
in.readList(this.properties, String.class.getClassLoader());
this.avatar_url = in.readString();
this.visible = in.readByte() != 0;
in.readList(this.audience, Long.class.getClassLoader());
in.readList(this.participants, BasicUser.class.getClassLoader());
in.readList(this.messages, Message.class.getClassLoader());
long tmpLastMessageDate = in.readLong();
this.lastMessageDate = tmpLastMessageDate == -1 ? null : new Date(tmpLastMessageDate);
this.deleted = in.readByte() != 0;
this.deletedString = in.readString();
this.last_authored_message_at = in.readString();
this.subject = in.readString();
}
public static Creator<Conversation> CREATOR = new Creator<Conversation>() {
public Conversation createFromParcel(Parcel source) {
return new Conversation(source);
}
public Conversation[] newArray(int size) {
return new Conversation[size];
}
};
}