package com.zulip.android.models;
import android.graphics.Color;
import android.text.TextUtils;
import android.util.Log;
import com.google.gson.annotations.SerializedName;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.ForeignCollection;
import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.field.ForeignCollectionField;
import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.table.DatabaseTable;
import com.zulip.android.ZulipApp;
import com.zulip.android.util.ZLog;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import java.sql.SQLException;
import java.util.List;
@DatabaseTable(tableName = "streams")
public class Stream {
public static final String ID_FIELD = "id";
public static final String NAME_FIELD = "name";
public static final String COLOR_FIELD = "color";
public static final String SUBSCRIBED_FIELD = "subscribed";
private static final int DEFAULT_COLOR = Color.GRAY;
private static final String MESSAGES_FIELD = "messages";
private static final String INHOMEVIEW_FIELD = "inHomeView";
private static final String INVITEONLY_FIELD = "inviteOnly";
@SerializedName("stream_id")
@DatabaseField(columnName = ID_FIELD, id = true)
private int id;
@SerializedName("description")
private String description;
@SerializedName("subscribers")
private List<String> subscribers;
@SerializedName("pin_to_top")
private boolean pinToTop;
@SerializedName("audible_notifications")
private boolean audibleNotifications;
@SerializedName("email_address")
private String emailAddress;
@SerializedName("desktop_notifications")
private boolean desktopNotifications;
@ForeignCollectionField(columnName = MESSAGES_FIELD)
private ForeignCollection<Message> messages;
@DatabaseField(columnName = SUBSCRIBED_FIELD)
private boolean subscribed;
@DatabaseField(columnName = NAME_FIELD, uniqueIndex = true)
@SerializedName("name")
private String name;
@DatabaseField(columnName = COLOR_FIELD)
private int parsedColor;
@SerializedName("color")
private String fetchedColor;
@DatabaseField(columnName = INVITEONLY_FIELD)
@SerializedName("invite_only")
private boolean inviteOnly;
@DatabaseField(columnName = INHOMEVIEW_FIELD)
@SerializedName("in_home_view")
private boolean inHomeView;
/**
* Construct an empty Stream object.
*/
public Stream() {
this.subscribed = false;
}
/**
* Construct a new Stream object when all that's known is the name.
* <p/>
* These should be sensible defaults.
*
* @param name The stream name
*/
public Stream(String name) {
this.name = name;
parsedColor = DEFAULT_COLOR;
inHomeView = true; // Sure, why not
inviteOnly = false; // Most probably
}
private static int parseColor(String color) {
// Color.parseColor does not handle colors of the form #f00.
// Pre-process them into normal 6-char hex form.
if (color.length() == 4) {
char r = color.charAt(1);
char g = color.charAt(2);
char b = color.charAt(3);
color = "#" + r + r + g + g + b + b;
}
return Color.parseColor(color);
}
public static Stream getByName(ZulipApp app, String name) {
Stream stream = null;
try {
RuntimeExceptionDao<Stream, Object> streams = app.getDao(Stream.class);
stream = streams.queryBuilder().where()
.eq(Stream.NAME_FIELD, new SelectArg(name)).queryForFirst();
if (stream == null) {
Log.w("Stream.getByName",
"We received a stream message for a stream we don't have data for. Fake it until you make it.");
stream = new Stream(name);
app.getDao(Stream.class).createIfNotExists(stream);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
return stream;
}
public static Stream getById(ZulipApp app, int id) {
try {
Dao<Stream, Integer> streams = app.getDatabaseHelper().getDao(
Stream.class);
return streams.queryForId(id);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/**
* Checks stream name is valid or not
*
* @param app ZulipApp
* @param streamName Checks this stream name is valid or not
* @return null if stream does not exist else cursor
*/
public static Stream streamCheckBeforeMessageSend(ZulipApp app, CharSequence streamName) {
if (streamName == null) {
return null;
}
try {
return app.getDao(Stream.class)
.queryBuilder().where()
.eq(Stream.NAME_FIELD, new SelectArg(Stream.NAME_FIELD, streamName)).queryForFirst();
} catch (SQLException e) {
ZLog.logException(e);
}
return null;
}
/**
* This function returns the last message read in {@param streamName} stream.
*
* @param app {@link ZulipApp}
* @param streamName name of stream
* @return last message {@link Message} read
*/
public static Message getLastMessageRead(ZulipApp app, String streamName) {
try {
Dao<Message, Integer> messageDao = app.getDatabaseHelper().getDao(Message.class);
// query for message in given stream and orderby timestamp decreasingly
return messageDao.queryBuilder().orderBy(Message.TIMESTAMP_FIELD, false)
.where().eq(Message.RECIPIENTS_FIELD, new SelectArg(Message.RECIPIENTS_FIELD, streamName))
.queryForFirst();
} catch (SQLException e) {
ZLog.logException(e);
}
return null;
}
public String getName() {
return name;
}
public int getParsedColor() {
if (!TextUtils.isEmpty(fetchedColor)) {
parsedColor = parseColor(fetchedColor);
}
return parsedColor;
}
public Boolean getInHomeView() {
return inHomeView;
}
public void setInHomeView(boolean inHomeView) {
this.inHomeView = inHomeView;
}
public Boolean getInviteOnly() {
return inviteOnly;
}
public boolean isSubscribed() {
return subscribed;
}
public void setSubscribed(boolean isSubscribed) {
subscribed = isSubscribed;
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 31).append(name).toHashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj == this) {
return true;
}
if (obj.getClass() != getClass()) {
return false;
}
Stream rhs = (Stream) obj;
return new EqualsBuilder().append(this.name, rhs.name).isEquals();
}
public int getId() {
return id;
}
public void setFetchColor(String fetchedColor) {
this.fetchedColor = fetchedColor;
getParsedColor();
}
public void setDefaultColor() {
this.parsedColor = DEFAULT_COLOR;
}
}