/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.model.entity;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.ScheduledFuture;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.CharNameTable;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.instancemanager.MailManager;
import com.l2jserver.gameserver.model.itemcontainer.Mail;
import com.l2jserver.util.Rnd;
/**
*
* @author Migi, DS
*/
public class Message
{
private static final int EXPIRATION = 360; // 15 days
private static final int COD_EXPIRATION = 12; // 12 hours
private static final int UNLOAD_ATTACHMENTS_INTERVAL = 900000; // 15-30 mins
// post state
public static final int DELETED = 0;
public static final int READED = 1;
public static final int REJECTED = 2;
private final int _messageId, _senderId, _receiverId;
private final long _expiration;
private String _senderName = null;
private String _receiverName = null;
private final String _subject, _content;
private boolean _unread, _fourStars, _news;
private boolean _deletedBySender;
private boolean _deletedByReceiver;
private long _reqAdena;
private boolean _hasAttachments;
private Mail _attachments = null;
private ScheduledFuture<?> _unloadTask = null;
/*
* Constructor for restoring from DB.
*/
public Message(ResultSet rset) throws SQLException
{
_messageId = rset.getInt("messageId");
_senderId = rset.getInt("senderId");
_receiverId = rset.getInt("receiverId");
_subject = rset.getString("subject");
_content = rset.getString("content");
_expiration = rset.getLong("expiration");
_reqAdena = rset.getLong("reqAdena");
_hasAttachments = rset.getBoolean("hasAttachments");
_unread = rset.getBoolean("isUnread");
_deletedBySender = rset.getBoolean("isDeletedBySender");
_deletedByReceiver = rset.getBoolean("isDeletedByReceiver");
_fourStars = rset.getBoolean("isFourStars");
_news = rset.getBoolean("isNews");
}
/*
* This constructor used for creating new message.
*/
public Message(int senderId, int receiverId, boolean isCod, String subject, String text, long reqAdena)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = senderId;
_receiverId = receiverId;
_subject = subject;
_content = text;
_expiration = (isCod ? System.currentTimeMillis() + COD_EXPIRATION * 3600000 : System.currentTimeMillis() + EXPIRATION * 3600000);
_hasAttachments = false;
_unread = true;
_deletedBySender = false;
_deletedByReceiver = false;
_reqAdena = reqAdena;
}
/*
* This constructor used for auto-generation of the "return attachments" message
*/
public Message(Message msg)
{
_messageId = IdFactory.getInstance().getNextId();
_senderId = msg.getSenderId();
_receiverId = msg.getSenderId();
_subject = "";
_content = "";
_expiration = System.currentTimeMillis() + EXPIRATION * 3600000;
_unread = true;
_deletedBySender = true;
_deletedByReceiver = false;
_fourStars = true;
_reqAdena = 0;
_hasAttachments = true;
_attachments = msg.getAttachments();
msg.removeAttachments();
_attachments.setNewMessageId(_messageId);
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
}
public static final PreparedStatement getStatement(Message msg, Connection con) throws SQLException
{
PreparedStatement stmt = con.prepareStatement("INSERT INTO messages (messageId, senderId, receiverId, subject, content, expiration, reqAdena, hasAttachments, isUnread, isDeletedBySender, isDeletedByReceiver, isFourStars, isNews) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
stmt.setInt(1, msg._messageId);
stmt.setInt(2, msg._senderId);
stmt.setInt(3, msg._receiverId);
stmt.setString(4, msg._subject);
stmt.setString(5, msg._content);
stmt.setLong(6, msg._expiration);
stmt.setLong(7, msg._reqAdena);
stmt.setString(8, String.valueOf(msg._hasAttachments));
stmt.setString(9, String.valueOf(msg._unread));
stmt.setString(10, String.valueOf(msg._deletedBySender));
stmt.setString(11, String.valueOf(msg._deletedByReceiver));
stmt.setString(12, String.valueOf(msg._fourStars));
stmt.setString(13, String.valueOf(msg._news));
return stmt;
}
public final int getId()
{
return _messageId;
}
public final int getSenderId()
{
return _senderId;
}
public final int getReceiverId()
{
return _receiverId;
}
public final String getSenderName()
{
if (_senderName == null)
{
if (_fourStars)
return "****";
_senderName = CharNameTable.getInstance().getNameById(_senderId);
if (_senderName == null)
_senderName = "";
}
return _senderName;
}
public final String getReceiverName()
{
if (_receiverName == null)
{
_receiverName = CharNameTable.getInstance().getNameById(_receiverId);
if (_receiverName == null)
_receiverName = "";
}
return _receiverName;
}
public final String getSubject()
{
return _subject;
}
public final String getContent()
{
return _content;
}
public final boolean isLocked()
{
return _reqAdena > 0;
}
public final long getExpiration()
{
return _expiration;
}
public final int getExpirationSeconds()
{
return (int)(_expiration / 1000);
}
public final boolean isUnread()
{
return _unread;
}
public final void markAsRead()
{
if (_unread)
{
_unread = false;
MailManager.getInstance().markAsReadInDb(_messageId);
}
}
public final boolean isDeletedBySender()
{
return _deletedBySender;
}
public final void setDeletedBySender()
{
if (!_deletedBySender)
{
_deletedBySender = true;
if (_deletedByReceiver)
MailManager.getInstance().deleteMessageInDb(_messageId);
else
MailManager.getInstance().markAsDeletedBySenderInDb(_messageId);
}
}
public final boolean isDeletedByReceiver()
{
return _deletedByReceiver;
}
public final void setDeletedByReceiver()
{
if (!_deletedByReceiver)
{
_deletedByReceiver = true;
if (_deletedBySender)
MailManager.getInstance().deleteMessageInDb(_messageId);
else
MailManager.getInstance().markAsDeletedByReceiverInDb(_messageId);
}
}
public final boolean isFourStars()
{
return _fourStars;
}
public final boolean isNews()
{
return _news;
}
public final void setIsNews(boolean val)
{
_news = val;
}
public final long getReqAdena()
{
return _reqAdena;
}
public final synchronized Mail getAttachments()
{
if (!_hasAttachments)
return null;
if (_attachments == null)
{
_attachments = new Mail(_senderId, _messageId);
_attachments.restore();
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
}
return _attachments;
}
public final boolean hasAttachments()
{
return _hasAttachments;
}
public final synchronized void removeAttachments()
{
if (_attachments != null)
{
_attachments = null;
_hasAttachments = false;
MailManager.getInstance().removeAttachmentsInDb(_messageId);
if (_unloadTask != null)
_unloadTask.cancel(false);
}
}
public final synchronized Mail createAttachments()
{
if (_hasAttachments || _attachments != null)
return null;
_attachments = new Mail(_senderId, _messageId);
_hasAttachments = true;
_unloadTask = ThreadPoolManager.getInstance().scheduleGeneral(new AttachmentsUnloadTask(this), UNLOAD_ATTACHMENTS_INTERVAL + Rnd.get(UNLOAD_ATTACHMENTS_INTERVAL));
return _attachments;
}
protected final synchronized void unloadAttachments()
{
if (_attachments != null)
{
_attachments.deleteMe();
_attachments = null;
}
}
static class AttachmentsUnloadTask implements Runnable
{
private Message _msg;
AttachmentsUnloadTask(Message msg)
{
_msg = msg;
}
public void run()
{
if (_msg != null)
{
_msg.unloadAttachments();
_msg = null;
}
}
}
}