package com.nutiteq.utils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.util.Vector;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;
import com.mgmaps.utils.Tools;
import com.nutiteq.components.Rectangle;
import com.nutiteq.components.Sortable;
import com.nutiteq.components.WgsPoint;
import com.nutiteq.log.Log;
public class Utils {
private static final String HTTP_PREFIX = "http://";
private static final String HTTPS_PREFIX = "https://";
private static final String FILE_PREFIX = "file://";
private static final String JAR_RESOURCE_PREFIX = "/";
public static final int RESOURCE_TYPE_NETWORK = 1;
public static final int RESOURCE_TYPE_FILE = 2;
public static final int RESOURCE_TYPE_JAR = 4;
private static final int[] POW2_TABLE = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
private Utils() {
}
public static boolean rectanglesIntersect(final int rOneX, final int rOneY, final int rOneWidth, final int rOneHeight, final int rTwoX,
final int rTwoY, final int rTwoWidth, final int rTwoHeight) {
//TODO jaanus : check this. maybe can add some optimization
final int rectOneX = rOneWidth > 0 ? rOneX : rOneX + rOneWidth;
final int rectOneY = rOneHeight > 0 ? rOneY : rOneY + rOneHeight;
final int rectOneWidth = Math.abs(rOneWidth);
final int rectOneHeight = Math.abs(rOneHeight);
final int rectTwoX = rTwoWidth > 0 ? rTwoX : rTwoX + rTwoWidth;
final int rectTwoY = rTwoHeight > 0 ? rTwoY : rTwoY + rTwoHeight;
final int rectTwoWidth = Math.abs(rTwoWidth);
final int rectTwoHeight = Math.abs(rTwoHeight);
if (rectTwoY + rectTwoHeight < rectOneY || // is the bottom of two above the top of one?
rectTwoY > rectOneY + rectOneHeight || // is the top of two below bottom of one?
rectTwoX + rectTwoWidth < rectOneX || // is the right of two to the left of one?
rectTwoX > rectOneX + rectOneWidth) { // is the left of two to the right of one?
return false;
}
return true;
}
public static int binarySearch(final int[] array, final int target) {
int high = array.length;
int low = -1;
int probe;
while (high - low > 1) {
probe = (high + low) / 2;
if (array[probe] > target) {
high = probe;
} else {
low = probe;
}
}
if (low == -1 || array[low] != target) {
return -1;
} else {
return low;
}
}
public static int binarySearch(final String[] array, final String target) {
int high = array.length;
int low = -1;
int probe;
while (high - low > 1) {
probe = (high + low) / 2;
if (array[probe].compareTo(target) > 0) {
high = probe;
} else {
low = probe;
}
}
if (low == -1 || !array[low].equals(target)) {
return -1;
} else {
return low;
}
}
public static void bubbleSort(final Sortable[] array) {
final int elements = array.length;
int i;
int j;
Sortable t = null;
for (i = 0; i < elements; i++) {
for (j = 1; j < (elements - i); j++) {
if (array[j - 1].compareTo(array[j]) > 0) {
t = array[j - 1];
array[j - 1] = array[j];
array[j] = t;
}
}
}
}
public static void bubbleSort(final int array[]) {
final int elements = array.length;
int i;
int j;
int t = 0;
for (i = 0; i < elements; i++) {
for (j = 1; j < (elements - i); j++) {
if (array[j - 1] > array[j]) {
t = array[j - 1];
array[j - 1] = array[j];
array[j] = t;
}
}
}
}
public static void doubleBubbleSort(final int mainArray[], final int[] secondArray) {
final int elements = mainArray.length;
int i;
int j;
int t = 0;
int t2 = 0;
for (i = 0; i < elements; i++) {
for (j = 1; j < (elements - i); j++) {
if (mainArray[j - 1] > mainArray[j]) {
t = mainArray[j - 1];
t2 = secondArray[j - 1];
mainArray[j - 1] = mainArray[j];
secondArray[j - 1] = secondArray[j];
mainArray[j] = t;
secondArray[j] = t2;
}
}
}
}
public static void doubleBubbleSort(final String mainArray[], final String[] secondArray) {
final int elements = mainArray.length;
int i;
int j;
String t;
String t2;
for (i = 0; i < elements; i++) {
for (j = 1; j < (elements - i); j++) {
if (mainArray[j - 1].compareTo(mainArray[j]) > 0) {
t = mainArray[j - 1];
t2 = secondArray[j - 1];
mainArray[j - 1] = mainArray[j];
secondArray[j - 1] = secondArray[j];
mainArray[j] = t;
secondArray[j] = t2;
}
}
}
}
/**
* Avoid FP operations.
*/
public static int log2(final int x) {
for (int i = POW2_TABLE.length - 1; i >= 0; i--) {
if (x == POW2_TABLE[i]) {
return i;
}
}
throw new IllegalArgumentException("Do not know the log2 from " + x);
}
public static Image resizeImageAndCopyPrevious(final int newWidth, final int newHeight, final Image resized) {
// TODO jaanus : if new is smaller can optimize with
// createImage(Image image, int x, int y, int width, int height, int
// transform)
final Image result = Image.createImage(newWidth, newHeight);
final Graphics g = result.getGraphics();
g.drawImage(resized, (newWidth - resized.getWidth()) / 2, (newHeight - resized.getHeight()) / 2, Graphics.TOP | Graphics.LEFT);
return result;
}
public static Rectangle mergeAreas(final Rectangle areaOne, final Rectangle areaTwo) {
final int resultX = Math.min(areaOne.getX(), areaTwo.getX());
final int resultY = Math.min(areaOne.getY(), areaTwo.getY());
final int areaOneRightX = areaOne.getX() + areaOne.getWidth();
final int areaTwoRightX = areaTwo.getX() + areaTwo.getWidth();
final int areaOneBottomY = areaOne.getY() + areaOne.getHeight();
final int areaTwoBottomY = areaTwo.getY() + areaTwo.getHeight();
final int resultWidth = Math.max(areaOneRightX, areaTwoRightX) - resultX;
final int resultHeight = Math.max(areaOneBottomY, areaTwoBottomY) - resultY;
return new Rectangle(resultX, resultY, resultWidth, resultHeight);
}
public static String[] split(final String string, final String splitBy) {
final Vector tokens = new Vector();
final int tokenLength = splitBy.length();
int tokenStart = 0;
int splitIndex;
while ((splitIndex = string.indexOf(splitBy, tokenStart)) != -1) {
tokens.addElement(string.substring(tokenStart, splitIndex));
tokenStart = splitIndex + tokenLength;
}
tokens.addElement(string.substring(tokenStart));
final String[] result = new String[tokens.size()];
tokens.copyInto(result);
return result;
}
public static Rectangle areaToScreen(final Rectangle area, final int viewX, final int viewY, final int viewWidth, final int viewHeight) {
final int areaX = area.getX() < viewX ? viewX : area.getX();
final int areaY = area.getY() < viewY ? viewY : area.getY();
final int areaW = area.getX() + area.getWidth() > viewX + viewWidth ? viewX + viewWidth - areaX : area.getX() + area.getWidth() - areaX;
final int areaH = area.getY() + area.getHeight() > viewY + viewHeight ? viewY + viewHeight - areaY : area.getY() + area.getHeight()
- areaY;
return new Rectangle(areaX - viewX, areaY - viewY, areaW, areaH);
}
public static String[] wrapText(final String text, final Font font, final int maxWidth) {
return Tools.wrapText(text, font, maxWidth, 0);
}
public static Image createImage(final String image) {
try {
return Image.createImage(image);
} catch (final IOException e) {
Log.debug("createImage '" + image + "': " + e.getMessage());
Log.printStackTrace(e);
return null;
}
}
public static double round(final double num) {
final double floor = Math.floor(num);
if (num - floor >= 0.5) {
return Math.ceil(num);
} else {
return floor;
}
}
public static double parseDecimalDegree(final String hoursMinutesFractions, final String whereOnGlobe) {
final int dotPos = hoursMinutesFractions.indexOf('.');
final String degrees = hoursMinutesFractions.substring(0, dotPos - 2);
final String minutes = hoursMinutesFractions.substring(dotPos - 2);
try {
final double result = Double.parseDouble(degrees) + Double.parseDouble(minutes) / 60;
return "W".equals(whereOnGlobe) || "S".equals(whereOnGlobe) ? -result : result;
} catch (final NumberFormatException e) {
return 0.0;
}
}
public static String replaceAll(final String original, final String tokenToBeReplaced, final String value) {
//TODO jaanus : optimize
final StringBuffer result = new StringBuffer();
final String[] originalSplit = split(original, tokenToBeReplaced);
for (int i = 0; i < originalSplit.length; i++) {
result.append(originalSplit[i]);
if (i != originalSplit.length - 1) {
result.append(value);
}
}
return result.toString();
}
public static WgsPoint parseWgsFromString(final String lon, final String lat) {
try {
return new WgsPoint(Double.parseDouble(lon), Double.parseDouble(lat));
} catch (final NumberFormatException e) {
return null;
}
}
public static Reader createInputStreamReader(final byte[] data) {
InputStreamReader reader;
final InputStream is = new ByteArrayInputStream(data);
try {
reader = new InputStreamReader(is, "utf-8");
} catch (final Exception e) {
reader = new InputStreamReader(is);
}
return reader;
}
public static int parseInt(final String intString) {
return parseInt(intString, 0);
}
public static int parseInt(final String intString, final int defaultValue) {
try {
return Integer.parseInt(intString);
} catch (final NumberFormatException e) {
return defaultValue;
}
}
public static String urlEncode(final String string) {
return Tools.urlEncode(string);
}
public static String toStringWithLeadingZeroes(final int number, final int totalNumbers) {
final StringBuffer result = new StringBuffer(Integer.toString(number));
for (int i = result.length(); i < totalNumbers; i++) {
result.insert(0, '0');
}
return result.toString();
}
public static void closeStream(final InputStream is) {
IOUtils.closeStream(is);
}
public static void closeStream(final OutputStream os) {
IOUtils.closeStream(os);
}
public static void closeReader(final Reader reader) {
IOUtils.closeReader(reader);
}
public static void closeRecordStore(final RecordStore rs) {
if (rs != null) {
try {
rs.closeRecordStore();
} catch (final RecordStoreException ignore) {
}
}
}
public static String readLine(final InputStream is) {
try {
return Tools.readLine2(is);
} catch (final IOException e) {
return null;
}
}
public static String prepareForParameters(final String url) {
if (url.endsWith("?") || url.endsWith("&")) {
return url;
}
if (url.indexOf("?") > 0) {
return url + "&";
} else {
return url + "?";
}
}
public static int getResourceType(final String resourcePath) {
final String path = resourcePath.trim().toLowerCase();
if (path.startsWith(HTTP_PREFIX) || path.startsWith(HTTPS_PREFIX)) {
return RESOURCE_TYPE_NETWORK;
} else if (path.startsWith(FILE_PREFIX)) {
return RESOURCE_TYPE_FILE;
} else if (path.startsWith(JAR_RESOURCE_PREFIX)) {
return RESOURCE_TYPE_JAR;
}
return 0;
}
/**
* generates round polygon (circle) based on center, radius and number of points
* Bases on spheroid with WGS84 primary axis radius (6378137 m)
* @param center defines lat, long of center
* @param radius in meters
* @param points number of required points. 360/points should be integer. About 24 looks typically fine.
* @return array of WgsPoints. Can be used to make a line or polygon from these
*/
public static WgsPoint[] circlePoints(WgsPoint center, double radius, int points) {
double earthsRadius = 6378137; // in meters for Wgs84
double d2r = Math.PI / 180; // degrees to radians
double r2d = 180 / Math.PI;
double rLatitude = r2d * (radius / earthsRadius);
double rLongitude = rLatitude / Math.cos(d2r * center.getLat());
WgsPoint[] out = new WgsPoint[points + 2];
for (int i = 0; i <= points + 1; i++) {
double theta = Math.PI * ((double) i / ((double) points / 2));
double pLong = center.getLon() + (rLongitude * Math.cos(theta));
double pLat = center.getLat() + (rLatitude * Math.sin(theta));
out[i] = new WgsPoint(pLong, pLat);
}
return out;
}
}