package jimmui.view.chat;
import jimm.*;
import jimm.cl.SysTextList;
import jimm.comm.StringUtils;
import jimm.history.*;
import jimmui.Clipboard;
import jimmui.HotKeys;
import jimmui.model.chat.ChatModel;
import jimmui.model.chat.MessData;
import jimmui.view.base.*;
import jimmui.view.base.touch.*;
import jimmui.view.icons.Icon;
import jimmui.view.menu.MenuModel;
import protocol.Contact;
import protocol.Protocol;
import protocol.ui.*;
import javax.microedition.lcdui.Font;
/**
* Created with IntelliJ IDEA.
* <p/>
* Date: 21.07.13 21:44
*
* @author vladimir
*/
public class ChatContent extends SomeContent {
private ChatModel model;
private boolean selectMode;
public static final String ADDRESS = ", ";
public ChatContent(SomeContentList view, ChatModel model) {
super(view);
this.model = model;
}
@Override
public void setTopByOffset(int offset) {
super.setTopByOffset(offset);
model.bottomOffset = getTopOffset() + view.getContentHeight();
}
@Override
protected void setCurrItem(int cItem) {
super.setCurrItem(cItem);
model.current = getCurrItem();
}
@Override
public int getSize() {
return model.size();
}
@Override
public int getItemHeight(int itemIndex) {
return model.getItemHeight(model.getMessage(itemIndex));
}
@Override
public void drawItemData(GraphicsEx g, int index, int x, int y, int w, int h, int skip, int to) {
MessData mData = model.getMessage(index);
int header = model.getMessageHeaderHeight(mData);
if (0 < header) {
int visHeader = Math.min(Math.max(0, header - skip), to);
drawMessageHeader(g, mData, x, y, w, header, skip, visHeader);
y += header;
h -= header;
skip -= header;
}
model.getMessage(index).par.paint(model.fontSet, g, 1, y, skip, to);
}
public void drawItemBack(GraphicsEx g, int index, int selected, int x, int y, int w, int h, int skip, int to) {
MessData mData = model.getMessage(index);
byte bg;
if (mData.isMarked()) {
bg = CanvasEx.THEME_CHAT_BG_MARKED;
} else if (mData.isService()) {
bg = CanvasEx.THEME_CHAT_BG_SYSTEM;
} else if ((index & 1) == 0) {
bg = mData.isIncoming() ? CanvasEx.THEME_CHAT_BG_IN : CanvasEx.THEME_CHAT_BG_OUT;
} else {
bg = mData.isIncoming() ? CanvasEx.THEME_CHAT_BG_IN_ODD : CanvasEx.THEME_CHAT_BG_OUT_ODD;
}
if (g.notEqualsColor(CanvasEx.THEME_BACKGROUND, bg)) {
if (selected == index) {
g.setThemeColor(CanvasEx.THEME_SELECTION_BACK, bg, 0xA0);
} else {
g.setThemeColor(bg);
}
g.fillRect(x, y + skip, w, to);
}
}
private void drawMessageHeader(GraphicsEx g, MessData mData, int x1, int y1, int w, int baseLine, int skip, int visHeight) {
Icon icon = InfoFactory.msgIcons.iconAt(mData.iconIndex);
if (null != icon) {
int iconWidth = g.drawImage(icon, x1, y1, baseLine) + 1;
x1 += iconWidth;
w -= iconWidth;
}
Font[] set = model.fontSet;
Font boldFont = set[CanvasEx.FONT_STYLE_BOLD];
g.setFont(boldFont);
g.setThemeColor(getInOutColor(mData.isIncoming()));
Font plainFont = set[CanvasEx.FONT_STYLE_PLAIN];
String time = mData.isMarked() ? " v " : mData.strTime;
int timeWidth = plainFont.stringWidth(time);
g.drawString(mData.getNick(), x1, y1, w - timeWidth, baseLine, skip, visHeight);
g.setFont(plainFont);
g.drawString(time, x1 + w - timeWidth, y1, timeWidth, baseLine, skip, visHeight);
}
private byte getInOutColor(boolean incoming) {
return incoming ? CanvasEx.THEME_CHAT_INMSG : CanvasEx.THEME_CHAT_OUTMSG;
}
@Override
public void doJimmAction(int action) {
switch (action) {
case NativeCanvas.JIMM_MENU:
view.showMenu(getMenu());
return;
case NativeCanvas.JIMM_BACK:
if (0 == model.size()) {
Jimm.getJimm().jimmModel.unregisterChat(model);
}
Jimm.getJimm().getCL().activate(getContact());
return;
case NativeCanvas.JIMM_SELECT:
onMessageSelected();
return;
}
if (!model.writable && ((ACTION_REPLY == action)
|| (Contact.USER_MENU_MESSAGE == action))) {
return;
}
switch (action) {
case ACTION_REPLY:
execJimmAction(NativeCanvas.JIMM_SELECT);
break;
case ACTION_COPY_TEXT:
copyText();
break;
case ACTION_GOTO_URL:
SysTextList.gotoURL(getCurrentText());
break;
case ACTION_SELECT:
markItem(getCurrItem());
break;
// #sijapp cond.if modules_HISTORY is "true" #
case ACTION_ADD_TO_HISTORY:
addTextToHistory();
break;
// #sijapp cond.end#
case ACTION_DEL_CHAT:
Jimm.getJimm().getChatUpdater().removeMessagesAtCursor(model);
if (0 < getSize()) {
view.restore();
} else {
Jimm.getJimm().jimmModel.unregisterChat(model);
Jimm.getJimm().getCL().activate(null);
}
break;
// #sijapp cond.if modules_FILES="true"#
case ACTION_FT_CANCEL:
Jimm.getJimm().jimmModel.removeTransfer(getCurrentMsgData(), true);
break;
// #sijapp cond.end#
default:
new ContactMenu(getProtocol(), getContact()).doAction(action);
}
}
private static final int ACTION_FT_CANCEL = 900;
private static final int ACTION_REPLY = 901;
private static final int ACTION_ADD_TO_HISTORY = 902;
private static final int ACTION_COPY_TEXT = 903;
private static final int ACTION_GOTO_URL = 904;
private static final int ACTION_DEL_CHAT = 905;
private static final int ACTION_SELECT = 906;
private MenuModel getContextMenu() {
MessData md = getCurrentMsgData();
MenuModel menu = new MenuModel();
// #sijapp cond.if modules_FILES="true"#
if ((null != md) && md.isFile()) {
menu.addItem("cancel", ACTION_FT_CANCEL);
} else {
menu.addItem("select", ACTION_SELECT);
}
// #sijapp cond.else#
menu.addItem("select", ACTION_SELECT);
// #sijapp cond.end#
if (!selectMode) {
if ((null != md) && md.isURL()) {
menu.addItem("goto_url", ACTION_GOTO_URL);
}
}
menu.addItem("copy_text", ACTION_COPY_TEXT);
if (!selectMode) {
// #sijapp cond.if modules_HISTORY is "true" #
if (!Options.getBoolean(Options.OPTION_HISTORY) && getContact().hasHistory()) {
menu.addItem("add_to_history", ACTION_ADD_TO_HISTORY);
}
// #sijapp cond.end#
if (getContact().isSingleUserContact()) {
if (model.isBlogBot()) {
menu.addItem("reply", ACTION_REPLY);
}
} else {
if (model.writable) {
menu.addItem("reply", ACTION_REPLY);
}
}
}
menu.setActionListener(new Binder(this));
return menu;
}
protected MenuModel getMenu() {
if (selectMode) {
MenuModel menu = new MenuModel();
menu.addItem("copy_text", ACTION_COPY_TEXT);
menu.setActionListener(new Binder(this));
return menu;
}
boolean accessible = model.writable && (getContact().isSingleUserContact() || getContact().isOnline());
MessData md = getCurrentMsgData();
MenuModel menu = new MenuModel();
// #sijapp cond.if modules_ANDROID isnot "true" #
// #sijapp cond.if modules_FILES="true"#
if ((null != md) && md.isFile()) {
menu.addItem("cancel", ACTION_FT_CANCEL);
}
// #sijapp cond.end#
// #sijapp cond.end#
if (model.hasAuthRequests()) {
menu.addItem("grant", Contact.USER_MENU_GRANT_AUTH);
menu.addItem("deny", Contact.USER_MENU_DENY_AUTH);
}
// #sijapp cond.if modules_ANDROID isnot "true" #
// not in touch
if (getContact().isSingleUserContact()) {
if (model.isBlogBot()) {
menu.addItem("message", Contact.USER_MENU_MESSAGE);
menu.addItem("reply", ACTION_REPLY);
} else {
menu.addItem("reply", Contact.USER_MENU_MESSAGE);
}
} else {
if (model.writable) {
menu.addItem("message", Contact.USER_MENU_MESSAGE);
menu.addItem("reply", ACTION_REPLY);
}
}
// #sijapp cond.end#
if (!getContact().isSingleUserContact()) {
menu.addItem("list_of_users", Contact.USER_MENU_USERS_LIST);
}
// #sijapp cond.if modules_ANDROID isnot "true" #
if ((null != md) && md.isURL()) {
menu.addItem("goto_url", ACTION_GOTO_URL);
}
// #sijapp cond.end#
// #sijapp cond.if modules_FILES is "true"#
if (accessible) {
if (jimm.modules.fs.FileSystem.isSupported()) {
menu.addItem("ft_name", Contact.USER_MENU_FILE_TRANS);
}
if (FileTransfer.isPhotoSupported()) {
menu.addItem("ft_cam", Contact.USER_MENU_CAM_TRANS);
}
}
// #sijapp cond.end#
// #sijapp cond.if modules_ANDROID isnot "true" #
menu.addItem("copy_text", ACTION_COPY_TEXT);
// #sijapp cond.end#
if (accessible) {
if (!Clipboard.isClipBoardEmpty()) {
menu.addItem("paste", Contact.USER_MENU_PASTE);
}
}
getContact().addChatMenuItems(menu);
// #sijapp cond.if modules_ANDROID isnot "true" #
// #sijapp cond.if modules_HISTORY is "true" #
if (!Options.getBoolean(Options.OPTION_HISTORY) && getContact().hasHistory()) {
menu.addItem("add_to_history", ACTION_ADD_TO_HISTORY);
}
// #sijapp cond.end#
// #sijapp cond.end#
if (!getContact().isAuth()) {
menu.addItem("requauth", Contact.USER_MENU_REQU_AUTH);
}
//menu.addItem("user_menu", USER_MENU_SHOW);
//if (!getContact().isSingleUserContact() && getContact().isOnline()) {
// menu.addItem("leave_chat", Contact.CONFERENCE_DISCONNECT);
//}
menu.addItem("delete_chat", ACTION_DEL_CHAT);
menu.setActionListener(new Binder(this));
return menu;
}
void onMessageSelected() {
if (selectMode) {
markItem(getCurrItem());
return;
}
if (getContact().isSingleUserContact()) {
if (model.isBlogBot()) {
writeMessage(getBlogPostId(getCurrentText()));
return;
}
writeMessage(null);
return;
}
MessData md = getCurrentMsgData();
String nick = ((null == md) || md.isFile()) ? null : md.getNick();
writeMessageTo(model.getMyName().equals(nick) ? null : nick);
}
private Contact getContact() {
return model.contact;
}
private Protocol getProtocol() {
return model.protocol;
}
public final void writeMessageTo(String nick) {
if (null != nick) {
if ('/' == nick.charAt(0)) {
nick = ' ' + nick;
}
nick += ADDRESS;
} else {
nick = "";
}
writeMessage(nick);
}
public final void writeMessage(String initText) {
if (model.writable) {
// #sijapp cond.if modules_ANDROID is "true" #
if (true) {
((Chat)view).activate();
Jimm.getJimm().getDisplay().getNativeCanvas().getInput().setText(initText);
return;
}
// #sijapp cond.end #
MessageEditor editor = Jimm.getJimm().getMessageEditor();
if (null != editor) {
editor.writeMessage(getProtocol(), getContact(), initText);
}
}
}
private void markItem(int item) {
MessData mData = model.getMessage(item);
mData.setMarked(!mData.isMarked());
selectMode = hasSelectedItems();
invalidate();
}
private boolean hasSelectedItems() {
for (int i = 0; i < model.size(); ++i) {
MessData md = model.getMessage(i);
if (md.isMarked()) {
return true;
}
}
return false;
}
// #sijapp cond.if modules_HISTORY is "true" #
private void addTextToHistory() {
MessData md = getCurrentMsgData();
if ((null == md) || (null == md.getText())) {
return;
}
if (getContact().hasHistory()) {
HistoryStorage.getHistory(getContact()).addText(md.getText(), md.isIncoming(), md.getNick(), md.getTime());
}
}
// #sijapp cond.end#
private MessData getCurrentMsgData() {
try {
int messIndex = getCurrItem();
return (messIndex < 0) ? null : model.getMessage(messIndex);
} catch (Exception e) {
return null;
}
}
protected String getCurrentText() {
MessData md = getCurrentMsgData();
return (null == md) ? "" : md.getText();
}
protected void resetSelected() {
selectMode = false;
for (int i = 0; i < model.size(); ++i) {
model.getMessage(i).setMarked(false);
}
}
private String copySelected() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < model.size(); ++i) {
MessData md = model.getMessage(i);
if (md.isMarked()) {
String msg = md.getText();
if (md.isMe()) {
msg = "*" + md.getNick() + " " + msg;
}
sb.append(Clipboard.serialize(md.isIncoming(), md.getNick() + " " + md.strTime, msg));
sb.append("\n");
}
}
return 0 == sb.length() ? null : sb.toString();
}
private void copyText() {
String all = copySelected();
if (null != all) {
resetSelected();
Clipboard.setClipBoardText(all);
return;
}
MessData md = getCurrentMsgData();
if (null == md) {
return;
}
String msg = md.getText();
if (md.isMe()) {
msg = "*" + md.getNick() + " " + msg;
}
Clipboard.setClipBoardText(md.isIncoming(), md.getNick(), md.strTime, msg);
}
private String getBlogPostId(String text) {
if (StringUtils.isEmpty(text)) {
return null;
}
String lastLine = text.substring(text.lastIndexOf('\n') + 1);
if (0 == lastLine.length()) {
return null;
}
if ('#' != lastLine.charAt(0)) {
return null;
}
int numEnd = lastLine.indexOf(' ');
if (-1 != numEnd) {
lastLine = lastLine.substring(0, numEnd);
}
return lastLine + " ";
}
protected void beforePaint() {
model.resetUnreadMessages();
((Chat)view).updateStatusIcons();
}
// #sijapp cond.if modules_TOUCH is "true"#
protected void touchItemTaped(int item, int x, TouchState state) {
if (state.isLong || (view.getWidth() - view.minItemHeight < x)) {
view.showMenu(getContextMenu());
} else if (selectMode) {
markItem(item);
} else if (state.isLong) {
view.showMenu(getMenu());
} else if (state.isSecondTap) {
execJimmAction(NativeCanvas.JIMM_SELECT);
}
}
// #sijapp cond.end#
protected final boolean doKeyReaction(int keyCode, int actionCode, int type) {
if (CanvasEx.KEY_PRESSED == type) {
switch (keyCode) {
case NativeCanvas.CALL_KEY:
actionCode = 0;
break;
case NativeCanvas.CLEAR_KEY:
execJimmAction(ACTION_DEL_CHAT);
return true;
}
switch (actionCode) {
case NativeCanvas.NAVIKEY_LEFT:
case NativeCanvas.NAVIKEY_RIGHT:
Jimm.getJimm().getCL().showNextPrevChat(model, NativeCanvas.NAVIKEY_RIGHT == actionCode);
return true;
}
}
if (NativeCanvas.NAVIKEY_FIRE == actionCode) {
if (CanvasEx.KEY_RELEASED != type) {
return true;
}
if ('5' == keyCode) {
execJimmAction(NativeCanvas.JIMM_SELECT);
} else {
if (Jimm.getJimm().getDisplay().getNativeCanvas().isLongFirePress()) {
markItem(getCurrItem());
} else {
writeMessage(null);
}
}
return true;
}
if (HotKeys.execHotKey(getProtocol(), getContact(), keyCode, type)) {
return true;
}
return super.doKeyReaction(keyCode, actionCode, type);
}
}