/*
 * 作成日: 2007/07/21
 */
package net.sourceforge.swingx;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;

public class SxTextUtilities {
	/**
	 * バイト配列をダンプする.
	 */
	public static String dump(byte[] data) {
		StringBuffer result = new StringBuffer("ADDRESS  +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF\n");
		
		for (int i=0; i<data.length; i+=16) {
			String address = toHexString(i, 8);
			StringBuffer hex = new StringBuffer();
			for (int j=0; j<16; j++) {
				if (i+j < data.length) {
					hex.append(toHexString(data[i+j], 2)).append(" ");
				}
				else {
					hex.append("   ");
				}
			}
			StringBuffer chr = new StringBuffer();
			for (int j=0; j<16; j++) {
				if (i+j < data.length) {
					if (data[i+j] >= 0x20 && data[i+j] <= 0x7E) {
						chr.append((char) data[i+j]);
					}
					else {
						chr.append("?");
					}
				}
				else {
					break;
				}
			}
			result.append(address).append(" ").append(hex).append(chr).append("\n");
		}
		return result.toString();
	}
	public static String toHexString(int x, int len) {
		if (len <= 0) return "";
		return toHexString(x>>4, len-1) + "0123456789ABCDEF".charAt(x&0x0F);
	}
	public static boolean equalsString(String s1, String s2) {
		if (s1 == null && s2 == null) return true;
		if (s1 == null || s2 == null) return false;
		return s1.equals(s2);
	}
	/** nullを考慮した文字列比較. nullは昇順のとき末尾になる。 */
	public static int compareString(String str1, String str2) {
		if (str1==str2) return 0;
		if (str1==null) return -1;
		if (str2==null) return 1;
		return str1.compareTo(str2);
	}

	public static String getStackTraceString(Throwable th) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		th.printStackTrace(pw);
		return sw.toString();
	}
	/**
	 * 文字列を置き換える.
	 * 同一文字列内に複数の変換対象があってもよい。
	 * @param	str		対象となる文字列
	 * @param	src		変換前(ex."<")
	 * @param	dst		変換後(ex."&lt;")
	 * @return			置換された文字列
	 */
	public static String replace(String str, String src, String dst) {
		String newStr = "";
		int lastpos = 0;
		for(;;) {
			int pos = str.indexOf(src, lastpos);
			if(pos==-1) break;
			newStr += str.substring(lastpos, pos);
			newStr += dst;
			lastpos = pos + src.length();
		}
		return newStr + str.substring(lastpos);
	}	
	public static String decodeXml(String str) {
		if (str.compareTo("<null/>") == 0) return null;
		str = replace(str, "&lt;", "<");
		str = replace(str, "&gt;", ">");
		str = replace(str, "&quot;", "\"");
		str = replace(str, "&amp;", "&");
		return str;
	}
	
	public static String encodeXml(String str) {
		if (str == null) return "<null/>";
		str = replace(str, "&", "&amp;");
		str = replace(str, "<", "&lt;");
		str = replace(str, ">", "&gt;");
		str = replace(str, "\"", "&quot;");
		return str;
	}
	public static String[] splitLine(String text) {
		ArrayList list = new ArrayList();
		int pos = text.indexOf("\n");
		while (pos != -1) {
			list.add(text.substring(0, pos+1));
			text = text.substring(pos+1);
			pos = text.indexOf("\n");
		}
		if (text.length() > 0) list.add(text);
		String[] result = new String[list.size()];
		for (int i=0; i<list.size(); i++) {
			result[i] = (String) list.get(i);
		}
		return result;
	}
	/**
	 * 指定された位置は何行目か？
	 * 最初の行は0行目。1行目ではない。
	 * 指定された位置が改行のときは前の行になる。 
	 */
	public static int[] getLineColumnIndex(String text, int pos) {
		int line = 0;
		int col = 0;
		for (int i=0; i<pos; i++) {
			if (text.charAt(i) == '\n') {
				line++;
				col = 0;
			} else {
				col++;
			}
		}
		return new int[] {line, col};
	}
	/** 最初に見つかったindexを返す。 */
	public static int search(boolean[] array, boolean value) {
		for (int i=0; i<array.length; i++) {
			if (array[i] == value) return i;
		}
		return -1;
	}
}
