/*
* Contact.java
*
* Created on 6.01.2005, 19:16
*
* Copyright (c) 2005-2007, Eugene Stahov (evgs), http://bombus-im.org
*
* 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 2
* of the License, or (at your option) any later version.
*
* You can also redistribute and/or modify this program under the
* terms of the Psi License, specified in the accompanied COPYING
* file, as published by the Psi Project; either dated January 1st,
* 2005, 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 library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package Client;
import com.alsutton.jabber.JabberDataBlock;
import images.MoodIcons;
import images.RosterIcons;
import javax.microedition.lcdui.Graphics;
//#if CLIPBOARD_EVGS
//# import ui.ClipBoardString;
//#endif
import ui.Colors;
import vcard.VCard;
import java.util.*;
import ui.IconTextElement;
import ui.ImageList;
import com.alsutton.jabber.datablocks.Presence;
//
import Client.Config;
//#ifdef CLIENTS_ICONS
import modules.ClientsIcons;
//#endif
//
/**
* Contact
* @author Eugene Stahov
*/
public class Contact extends IconTextElement
//#if CLIPBOARD_EVGS
//# implements ClipBoardString
//#endif
{
public final static byte ORIGIN_ROSTER=0;
public final static byte ORIGIN_ROSTERRES=1;
public final static byte ORIGIN_CLONE=2;
public final static byte ORIGIN_PRESENCE=3;
public final static byte ORIGIN_GROUPCHAT=4;
public final static byte ORIGIN_GC_MEMBER=5;
public final static byte ORIGIN_GC_MYSELF=6;
/*public final static String XEP184_NS="http://www.xmpp.org/extensions/xep-0184.html#ns";
public final static int DELIVERY_NONE=0;
public final static int DELIVERY_HANDSHAKE=1;
public final static int DELIVERY_XEP184=2;
public final static int DELIVERY_XEP22=3;*/
//
private Config cf;
public short incomingState=0;
public final static short INC_NONE=0;
public final static short INC_APPEARING=1;
public final static short INC_VIEWING=2;
//#if AUTOSCROLLING
public boolean moveToLatest=false;
//#endif
//#ifdef LOGROTATE
public boolean redraw=false;
//#endif
//#if PREV_MSG
public String previousMessage;
//#endif
//
/** Creates a new instance of Contact */
protected Contact (){
//lastReaded=0;
super(RosterIcons.getInstance());
cf=Config.getInstance(); msgs=null; //<+voffk>
msgs=new Vector();
key1="";
}
public String nick;
public Jid jid;
public String bareJid; // for roster/subscription manipulating
public int status; //<*voffk>
public int priority;
public Group group; //<*voffk>
public int transport;
public boolean acceptComposing;
public Integer incomingComposing;
public int deliveryType;
//private boolean isActive;
public String msgSuspended;
//public int key1;
protected int key0;
protected String key1;
public byte origin;
//public boolean gcMyself;
public String subscr;
public int offline_type=Presence.PRESENCE_UNKNOWN;
public boolean ask_subscribe;
public Vector msgs;
private int newMsgCnt=-1;
public int unreadType;
public int lastUnread;
//
/*int ilHeight;
int maxImgHeight;*/
///public int breakPoint; ///save cursor pos - voffk
//
public VCard vcard;
//#if PEP
public int pepMood=-1;
//#if PEP_TUNE
public boolean pepTune;
//#endif
//#endif
//public long conferenceJoinTime;
public int firstUnread(){
int unreadIndex=0;
for (Enumeration e=msgs.elements(); e.hasMoreElements();) {
if (((Msg)e.nextElement()).unread) break;
unreadIndex++;
}
return unreadIndex;
}
public Contact(final String Nick, final String sJid, final int Status, String subscr) {
this();
nick=Nick; jid= new Jid(sJid); status=Status;
bareJid=sJid;
this.subscr=subscr;
setSortKey((Nick==null)?sJid:Nick);
//msgs.removeAllElements();
//calculating transport
transport=RosterIcons.getInstance().getTransportIndex(jid.getTransport());
}
public Contact clone(Jid newjid, final int status) {
Contact clone=new Contact();
clone.group=group;
clone.jid=newjid;
clone.nick=nick;
clone.key1=key1;
clone.subscr=subscr;
clone.offline_type=offline_type;
clone.vcard=vcard; //<+voffk>
clone.origin=ORIGIN_CLONE;
clone.status=status;
clone.transport=RosterIcons.getInstance().getTransportIndex(newjid.getTransport()); //<<<<
//#if PEP
clone.pepMood=pepMood;
//#if PEP_TUNE
clone.pepTune=pepTune;
//#endif
//#endif
clone.bareJid=bareJid;
return clone;
}
public int getImageIndex() {
if (getNewMsgsCount()>0)
switch (unreadType) {
case Msg.MESSAGE_TYPE_AUTH: return RosterIcons.ICON_AUTHRQ_INDEX;
default: return RosterIcons.ICON_MESSAGE_INDEX;
}
if (incomingComposing!=null) return RosterIcons.ICON_COMPOSING_INDEX;
if (incomingState>0) return incomingState; //<+voffk>
int st=(status==Presence.PRESENCE_OFFLINE)?offline_type:status;
if (st<8) st+=transport;
return st;
}
//#if PEP || CLIENTS_ICONS
public void drawItem(Graphics g, int ofs, boolean sel) {
int w=g.getClipWidth();
int h=g.getClipHeight();
int xo=g.getClipX();
int yo=g.getClipY();
//#if CLIENTS_ICONS
if (cf.showClientsIcons)
if (client>-1) {
ImageList clients=ClientsIcons.getInstance();
/*int clientImgSize=clients.getWidth();
w-=clientImgSize;
clients.drawImage(g, client, w, (h-clientImgSize)/2);
if (maxImgHeight=0 && pepMood<61) { //<*voffk>
ImageList moods=MoodIcons.getInstance();
w-=moods.getWidth();
moods.drawImage(g, pepMood, w,0);
}
//#if PEP_TUNE
if (pepTune) {
w-=il.getWidth();
il.drawImage(g, RosterIcons.ICON_PROFILE_INDEX+3, w,0);
}
//#endif
//#endif
g.setClip(xo, yo, w, h);
super.drawItem(g, ofs, sel);
}
//#endif
//#if PEP || CLIENTS_ICONS
public int getVWidth() { //<+voffk>
int ofs=0;
//#if PEP
if (pepMood>=0 && pepMood<61) {
ofs+=MoodIcons.getInstance().getWidth();
}
//#if PEP_TUNE
if (pepTune) {
ofs+=il.getWidth();
}
//#endif
//#endif
//#if CLIENTS_ICONS
if (cf.showClientsIcons)
if (client>-1)
ofs+=ClientsIcons.getInstance().getWidth();
//#endif
return super.getVWidth()+ofs;
}
//#endif
public int getNewMsgsCount() {
if (getGroupType()==Groups.TYPE_IGNORE) return 0;
//return msgs.size()-lastReaded;
if (newMsgCnt>-1) return newMsgCnt;
int nm=0;
unreadType=Msg.MESSAGE_TYPE_IN;
for (Enumeration e=msgs.elements(); e.hasMoreElements(); ) {
Msg m=(Msg)e.nextElement();
if (m.unread) {
nm++;
if (m.messageType==Msg.MESSAGE_TYPE_AUTH) unreadType=m.messageType;
}
}
return newMsgCnt=nm;
}
//public boolean needsCount(){ return (newMsgCnt<0); }
public boolean active(){ //<*voffk>
if (msgSuspended!=null) return true;
//if (msgs.size()>1) return true;
if (msgs.size()==0) return false;
//return (((Msg)msgs.elementAt(0)).messageType!=Msg.MESSAGE_TYPE_PRESENCE);
for (Enumeration e=msgs.elements(); e.hasMoreElements(); ) {
Msg m=(Msg)e.nextElement();
if (m.messageType!=Msg.MESSAGE_TYPE_PRESENCE
//#if PEP
&& m.messageType!=Msg.MESSAGE_TYPE_MOOD
//#endif
) return true;
}
return false;
//return isActive; //<-voffk>
}
public void resetNewMsgCnt() { newMsgCnt=-1; newHighLitedMsgCnt=-1; } //<*voffk>
public void setComposing (boolean state) {
incomingComposing=(state)? new Integer(RosterIcons.ICON_COMPOSING_INDEX):null;
//System.out.println("Composing:"+state);
}
public int compare(IconTextElement right){
Contact c=(Contact) right;
//1. status
int cmp;
//if (origin>=ORIGIN_GROUPCHAT && c.origin>=ORIGIN_GROUPCHAT) {
// if ((cmp=origin-c.origin) !=0) return cmp;
//} else {
// if ((cmp=status-c.status) !=0) return cmp;
//}
if ((cmp=key0-c.key0) !=0) return cmp;
if ((cmp=status-c.status) !=0) return cmp;
if ((cmp=key1.compareTo(c.key1)) !=0) return cmp;
if ((cmp=c.priority-priority) !=0) return cmp;
return c.transport-transport;
//return 0;
};
public void addMessage(Msg m) { //<*voffk>
//m.body=util.strconv.shuffler(m.body);
boolean first_replace=false;
if (origin!=ORIGIN_GROUPCHAT) {
if (m.isPresence())
if (msgs.size()==1)
if ( ((Msg)msgs.firstElement()).isPresence())
/*if (origin!=ORIGIN_GROUPCHAT)*/ first_replace=true;
}
//#ifdef LOGROTATE
else { redraw=deleteOldMessages(); }
//#endif
if (first_replace) {
msgs.setElementAt(m,0);
return;
}
//#if AUTOSCROLLING
if (cf.autoScrolling)
moveToLatest=true;
//#endif
msgs.addElement(m);
/*if ( (m.messageType!=Msg.MESSAGE_TYPE_PRESENCE)
&& (m.messageType!=Msg.MESSAGE_TYPE_MOOD) ) {
isActive=true;
}*/ //<-voffk>
if (m.unread) {
lastUnread=msgs.size()-1;
if (m.messageType>unreadType) unreadType=m.messageType;
if (newMsgCnt>=0) newMsgCnt++;
if (m.isHighlited()) //<+voffk>
if (newHighLitedMsgCnt>=0) newHighLitedMsgCnt++;
}
}
public int getColor() {
switch (status) {
case Presence.PRESENCE_CHAT: return Colors.CONTACT_CHAT;
case Presence.PRESENCE_AWAY: return Colors.CONTACT_AWAY;
case Presence.PRESENCE_XA: return Colors.CONTACT_XA;
case Presence.PRESENCE_DND: return Colors.CONTACT_DND;
}
return Colors.CONTACT_DEFAULT;
};
public int getFontIndex() { //<*voffk>
if (cf.rosterBoldFont) {
return (status<5)?1:0;
}
return (active() && !(cf.ghostMotor))?1:0;
}
public String toString() {
if (origin>ORIGIN_GROUPCHAT) return nick;
if (origin==ORIGIN_GROUPCHAT) return getJid();
return (nick==null)?getJid():nick+jid.getResource();
}
public final String getName(){ return (nick==null)?bareJid:nick; } //<*voffk>
//public void onSelect(){}
public final String getJid() {
return jid.getJid();
}
/*public final String getBareJid() {
return bareJid;
}*/ //<-voffk>
/*public String getNickJid() {
if (nick==null) return bareJid;
return nick+" <"+bareJid+">";
}*/ //<-voffk>
/**
* Splits string like "name@jabber.ru/resource" to vector
* containing 2 substrings
* @return Vector.elementAt(0)="name@jabber.ru"
* Vector.elementAt(1)="resource"
*/
/*
public static final Vector SplitJid(final String jid) {
Vector result=new Vector();
int i=jid.lastIndexOf('/');
if (i==-1){
result.addElement(jid);
result.addElement(null);
} else {
result.addElement(jid.substring(0,i));
result.addElement(jid.substring(i+1));
}
return result;
}
*/
public final void purge() { //<*voffk>
msgs=null;
msgs=new Vector();
vcard=null;
//#if PREV_MSG
previousMessage=null;
//#endif
resetNewMsgCnt();
//isActive=false;
}
public final void setSortKey(String sortKey){
key1=(sortKey==null)? "": sortKey.toLowerCase();
}
public String getTipString() {
int nm=getNewMsgsCount();
if (nm!=0) return String.valueOf(nm);
if (nick!=null) return bareJid;
return null;
}
//public Group getGroup() { return group; } <-voffk>
public int getGroupType() {
if (group==null) return 0;
return group.type;
}
//
/*public boolean inGroup(Group ingroup) { return group==ingroup; }
public void setGroup(Group group) { this.group = group; } */
public void setStatus(int status) {
//setComposing(false);
//#if !ReleaseZVOFFK
setIncoming(0);
//#endif
this.status = status;
if (status>=Presence.PRESENCE_OFFLINE) acceptComposing=false;
}
/*public int getStatus() {
return status;
}*/
void markDelivered(String id) {
if (id==null) return;
for (Enumeration e=msgs.elements(); e.hasMoreElements();) {
Msg m=(Msg)e.nextElement();
if (m.id!=null)
if (m.id.equals(id)) m.delivered=true;
}
}
//#if CLIPBOARD_EVGS
//# public String toClipBoardString() { return getJid(); }
//#endif
public final void smartPurge(int cursor) {
try {
if (cursor==msgs.size()) {
msgs=null;
msgs=new Vector();
}
else
for (int i=0; i0) return newHighLitedMsgCnt;
int nhm=0;
if (getGroupType()!=Groups.TYPE_IGNORE) {
for (Enumeration e=msgs.elements(); e.hasMoreElements(); ) {
Msg m=(Msg)e.nextElement();
if (m.unread && m.isHighlited()) {
nhm++;
}
}
}
return newHighLitedMsgCnt=nhm;
}
//#ifdef LOGROTATE
public final boolean deleteOldMessages() {
int limit=cf.msgCountLimit;
if (msgs.size()
}