/*******************************************************************************
Jimm - Mobile Messaging - J2ME ICQ clone
Copyright (C) 2003-05 Jimm Project
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.
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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
********************************************************************************
File: src/jimm/Emotions.java
Version: 0.5.1 Date: 2006/10/31
Author(s): Artyomov Denis
*******************************************************************************/
package jimm;
//#sijapp cond.if modules_SMILES is "true" #
import java.util.Vector;
import javax.microedition.lcdui.*;
import java.io.*;
import jimm.util.ResourceBundle;
import DrawControls.*;
public class Emotions implements VirtualListCommands, CommandListener
{
private static Emotions _this;
final private static ImageList images = new ImageList();
final private static Vector findedEmotions = new Vector();
private static boolean used;
private static int[] selEmotionsIndexes, textCorrIndexes;
private static String[] selEmotionsWord, selEmotionsSmileNames, textCorrWords;
public Emotions()
{
int iconsSize;
used = false;
_this = this;
Vector textCorr = new Vector();
Vector selEmotions = new Vector();
//#sijapp cond.if modules_DEBUGLOG is "true"#
System.gc();
long mem = Runtime.getRuntime().freeMemory();
//#sijapp cond.end#
// Load file "smiles.txt"
InputStream stream = this.getClass().getResourceAsStream("/smiles.txt");
if (stream == null) return;
DataInputStream dos = new DataInputStream(stream);
try
{
StringBuffer strBuffer = new StringBuffer();
boolean eof = false, clrf = false;
// Read icon size
readStringFromStream(strBuffer, dos);
iconsSize = Integer.parseInt(strBuffer.toString());
for (;;)
{
// Read smile index
readStringFromStream(strBuffer, dos);
Integer currIndex = Integer.valueOf(strBuffer.toString());
// Read smile name
readStringFromStream(strBuffer, dos);
String smileName = strBuffer.toString();
// Read smile strings
for (int i = 0;; i++)
{
try
{
clrf = readStringFromStream(strBuffer, dos);
}
catch (EOFException eofExcept)
{
eof = true;
}
String word = new String(strBuffer).trim();
// Add pair (word, integer) to textCorr
if (word.length() != 0) insertTextCorr(textCorr, word, currIndex);
// Add triple (index, word, name) to selEmotions
if (i == 0) selEmotions.addElement(new Object[] {currIndex, word, smileName});
if (clrf || eof) break;
}
if (eof) break;
}
stream.close();
// Read images
images.load("/smiles.png", iconsSize, iconsSize, -1);
}
catch (Exception e)
{
return;
}
// Write emotions data from vectors to arrays
int size = selEmotions.size();
selEmotionsIndexes = new int[size];
selEmotionsWord = new String[size];
selEmotionsSmileNames = new String[size];
for (int i = 0; i < size; i++)
{
Object[] data = (Object[])selEmotions.elementAt(i);
selEmotionsIndexes[i] = ((Integer)data[0]).intValue();
selEmotionsWord[i] = (String)data[1];
selEmotionsSmileNames[i] = (String)data[2];
}
size = textCorr.size();
textCorrWords = new String[size];
textCorrIndexes = new int[size];
for (int i = 0; i < size; i++)
{
Object[] data = (Object[])textCorr.elementAt(i);
textCorrWords[i] = (String)data[0];
textCorrIndexes[i] = ((Integer)data[1]).intValue();
}
//#sijapp cond.if modules_DEBUGLOG is "true"#
selEmotions.removeAllElements();
selEmotions = null;
textCorr.removeAllElements();
textCorr = null;
dos = null;
stream = null;
System.gc();
System.out.println("Emotions used: "+(mem-Runtime.getRuntime().freeMemory()));
//#sijapp cond.end#
used = true;
}
// Add smile text and index to textCorr in decreasing order of text length
static void insertTextCorr(Vector textCorr, String word, Integer index)
{
Object[] data = new Object[] {word, index};
int wordLen = word.length();
int size = textCorr.size();
int insIndex = 0;
for (; insIndex < size; insIndex++)
{
Object[] cvtData = (Object[])textCorr.elementAt(insIndex);
int cvlDataWordLen = ((String)cvtData[0]).length();
if (cvlDataWordLen <= wordLen)
{
textCorr.insertElementAt(data, insIndex);
return;
}
}
textCorr.addElement(data);
}
// Reads simple word from stream. Used in Emotions().
// Returns "true" if break was found after word
static boolean readStringFromStream(StringBuffer buffer, DataInputStream stream) throws IOException, EOFException
{
byte chr;
buffer.setLength(0);
for (;;)
{
chr = stream.readByte();
if ((chr == ' ') || (chr == '\n') || (chr == '\t')) break;
if (chr == '_') chr = ' ';
if (chr >= ' ') buffer.append((char)chr);
}
return (chr == '\n');
}
static private void findEmotionInText(String text, String emotion, int index, int startIndex)
{
int findedIndex, len = emotion.length();
findedIndex = text.indexOf(emotion, startIndex);
if (findedIndex == -1) return;
findedEmotions.addElement( new int[] {findedIndex, len, index} );
}
static public void addTextWithEmotions(TextList textList, String text, int fontStyle, int textColor, int bigTextIndex)
{
if (!used || !Options.getBoolean(Options.OPTION_USE_SMILES))
{
textList.addBigText(text, textColor, fontStyle, bigTextIndex);
return;
}
int startIndex = 0;
for (;;)
{
findedEmotions.removeAllElements();
int size = textCorrWords.length;
for (int i = 0; i < size; i++)
{
findEmotionInText
(
text,
textCorrWords[i],
textCorrIndexes[i],
startIndex
);
}
if (findedEmotions.isEmpty()) break;
int count = findedEmotions.size();
int minIndex = 100000, data[] = null, minArray[] = null;
for (int i = 0; i < count; i++)
{
data = (int[])findedEmotions.elementAt(i);
if (data[0] < minIndex)
{
minIndex = data[0];
minArray = data;
}
}
if (startIndex != minIndex)
textList.addBigText(text.substring(startIndex, minIndex), textColor, fontStyle, bigTextIndex);
textList.addImage
(
images.elementAt(minArray[2]),
text.substring(minIndex, minIndex+minArray[1]),
images.getWidth(),
images.getHeight(),
bigTextIndex
);
startIndex = minIndex+minArray[1];
}
int lastIndex = text.length();
if (lastIndex != startIndex)
textList.addBigText(text.substring(startIndex, lastIndex), textColor, fontStyle, bigTextIndex);
}
///////////////////////////////////
// //
// UI for emotion selection //
// //
///////////////////////////////////
static private Displayable lastDisplay;
static private CommandListener selectionListener;
static private Command cmdOk = new Command(ResourceBundle.getString("select"), Command.OK, 1);
static private Command cmdCancel = new Command(ResourceBundle.getString("cancel"), Command.BACK, 2);
static private String emotionText;
static private Selector selector;
static public void selectEmotion(CommandListener selectionListener_, Displayable lastDisplay_)
{
selectionListener = selectionListener_;
lastDisplay = lastDisplay_;
//selList = new TextList(null);
selector = new Selector();
JimmUI.setColorScheme(selector);
// #sijapp cond.if target is "MIDP2" | target is "MOTOROLA" | target is "SIEMENS2"#
selector.setFullScreenMode(false);
// #sijapp cond.end#
selector.addCommand(cmdOk);
selector.addCommand(cmdCancel);
selector.setCommandListener(_this);
Jimm.display.setCurrent(selector);
}
public void commandAction(Command c, Displayable d)
{
if (c == cmdOk) select();
else if (c == cmdCancel)
{
Jimm.display.setCurrent(lastDisplay);
selector = null;
}
}
public void onKeyPress(VirtualList sender, int keyCode,int type) {}
public void onCursorMove(VirtualList sender) {}
public void onItemSelected(VirtualList sender)
{
select();
}
static private void select()
{
Jimm.display.setCurrent(lastDisplay);
selector = null;
System.gc();
selectionListener.commandAction(cmdOk, selector);
}
static public String getSelectedEmotion()
{
return emotionText;
}
static public boolean isMyOkCommand(Command command)
{
return (command == cmdOk);
}
/////////////////////////
// //
// class Selector //
// //
/////////////////////////
static class Selector extends VirtualList implements VirtualListCommands
{
static private int cols, rows, itemHeight, curCol;
static private Selector _this;
Selector()
{
super(null);
_this = this;
setVLCommands(this);
int drawWidth = getWidth()-scrollerWidth-2;
setCursorMode(SEL_NONE);
int imgHeight = images.getHeight();
itemHeight = imgHeight+5;
cols = drawWidth/itemHeight;
rows = (selEmotionsIndexes.length+cols-1)/cols;
curCol = 0;
showCurrSmileName();
}
//#sijapp cond.if target is "MIDP2"#
protected boolean pointerPressedOnUtem(int index, int x, int y)
{
int lastCol = curCol;
curCol = x/itemHeight;
if (curCol < 0) curCol = 0;
if (curCol >= cols) curCol = cols-1;
if (lastCol != curCol)
{
showCurrSmileName();
invalidate();
}
return false;
}
// #sijapp cond.end#
protected void drawItemData
(
Graphics g,
boolean isSelected,
int index,
int x1, int y1, int x2, int y2,
int fontHeight
)
{
int xa, xb;
int startIdx = cols*index;
int imagesCount = images.size();
xa = x1;
for (int i = 0; i < cols; i++, startIdx++)
{
if (startIdx >= selEmotionsIndexes.length) break;
int smileIdx = selEmotionsIndexes[startIdx];
xb = xa+itemHeight;
if (smileIdx < imagesCount)
g.drawImage(images.elementAt(smileIdx), xa+3, y1+3, Graphics.TOP|Graphics.LEFT);
if (isSelected && (i == curCol))
{
g.setColor(this.getTextColor());
g.setStrokeStyle(Graphics.DOTTED);
g.drawRect(xa, y1, itemHeight-1, y2-y1-1);
}
xa = xb;
}
}
static private void showCurrSmileName()
{
int selIdx = _this.getCurrIndex()*cols+curCol;
if (selIdx >= selEmotionsSmileNames.length) return;
emotionText = selEmotionsWord[selIdx];
_this.setCaption(selEmotionsSmileNames[selIdx]);
}
public int getItemHeight(int itemIndex)
{
return itemHeight;
}
protected int getSize()
{
return rows;
}
protected void get(int index, ListItem item)
{
}
public void onKeyPress(VirtualList sender, int keyCode, int type)
{
if (type == VirtualList.KEY_PRESSED)
{
int lastCol = curCol;
switch (getGameAction(keyCode))
{
case LEFT:
if (curCol != 0) curCol--;
break;
case RIGHT:
if (curCol < (cols-1)) curCol++;
break;
}
int index = curCol+getCurrIndex()*cols;
if (index >= selEmotionsIndexes.length) curCol = (selEmotionsIndexes.length-1)%cols;
if (lastCol != curCol)
{
invalidate();
showCurrSmileName();
}
}
}
public void onCursorMove(VirtualList sender)
{
showCurrSmileName();
}
public void onItemSelected(VirtualList sender)
{
select();
}
}
}
//#sijapp cond.end#
|