/*********************************************************************************************************
 * 프로그램명 : User.java 프로그램설명 : 사용자에 대한 정보를 얻을 수 있는 class 작성자 : 조용준 변 경 : 강원중 작성일 : 2003.12.09 변경일 : 2003.12.09
 **********************************************************************************************************/

package kr.co.kihyun.text.html;

import java.util.*;

import javax.swing.text.*;
import javax.swing.text.html.*;

import kr.co.kihyun.lang.MString;

public class CallbackHandler extends HTMLEditorKit.ParserCallback {

	private boolean stTD;
	private boolean stTR;
	private int tableCount = 0;
	private int trCount = 0;
	private int tdCount = 0;

	private String text;
	private String colspan;
	private String rowspan;
	private String width;

	private Hashtable<String, String> TD = null;
	private List<Hashtable<String, String>> vTDs = new ArrayList<Hashtable<String, String>>();

	public CallbackHandler() {
		init();
	}

	private void init() {
		text = "";
		colspan = "";
		rowspan = "";
		width = "";
		// stTD = false;
		stTD = true;
		stTR = false;
		TD = new Hashtable<String, String>();
	}

	public int getTRCount() {
		return trCount;
	}

	public List<Hashtable<String, String>> getTDs() {
		setTDName();
		return vTDs;
	}

	public void setTDName() {
		int trCount = 0;
		int edTR = 0;
		int edTABLE = 0;

		// hash table 에서 table, tr 값을 가져와서 tr 의 갯수를 구한다.
		Hashtable<String, String> ht = null;
		int table = 0;
		int tr = 0;
		for (int i = 0; i < vTDs.size(); i++) {
			// i 번째 element 를 가져온다. 형식은 {width=7%, tr=1, text=????, table=1, colspan=1, rowspan=1}
			ht = vTDs.get(i);
			// table과 tr 의 값을 가져옴
			table = getInt(ht, "table");
			tr = getInt(ht, "tr");

			// tr 갯수 세기
			if (edTABLE != table || edTR != tr)
				trCount++;
			edTR = tr;
			edTABLE = table;
		}

		int TD[][] = new int[trCount + 10][256];

		for (int i = 0; i < trCount + 10; i++) {
			for (int j = 0; j < 256; j++) {
				TD[i][j] = -2;
			}
		}

		edTABLE = 0;
		edTR = 0;

		int iRow = -1;
		int iCol = 0;
		int colspan = 0;
		int rowspan = 0;

		for (int i = 0; i < vTDs.size(); i++) {
			ht = vTDs.get(i);
			table = getInt(ht, "table");
			tr = getInt(ht, "tr");
			colspan = getInt(ht, "colspan");
			rowspan = getInt(ht, "rowspan");
			if (edTABLE != table || edTR != tr) {
				iRow++;
				iCol = 0;
			}
			while (TD[iRow][iCol] != -2)
				iCol++;
			for (int rs = 0, cs = 0; rs < rowspan; rs++) {
				for (cs = 0; cs < colspan; cs++) {
					if (rowspan == 1 && colspan == 1) {
						if (rs == rowspan - 1 && cs == colspan - 1) {
							TD[iRow + rs][iCol + cs] = i;
						} else {
							TD[iRow + rs][iCol + cs] = -1;
						}
					} else {

						if (rs == 0 && cs == 0) {
							TD[iRow + rs][iCol + cs] = i;
						} else {
							TD[iRow + rs][iCol + cs] = -1;
						}
					}
				}
			}
			edTABLE = table;
			edTR = tr;
		}

		for (int i = 0, j = 0; i < trCount; i++) {
			for (j = 0; j < 256; j++) {
				if (TD[i][j] == -2)
					break;
				if (TD[i][j] > -1) {
					ht = vTDs.get(TD[i][j]);
					ht.put("name", (getInt2Abc(j) + (i + 1)));// sell 번호를 만든다.
					ht.put("col", "" + j);
					ht.put("row", "" + i);
					vTDs.set(TD[i][j], ht);
					tdCount = (tdCount >= j) ? tdCount : j;
				}
			}
		}
	}

	public void handleText(char[] data, int pos) {
		String sText = "";
		sText = new String(changeNBSP(data));

		if (stTD) {
			text += sText;
		}
	}

	public char[] changeNBSP(char[] data) {
		for (int i = 0; i < data.length; i++) {
			if ((int) data[i] == 160 || (int) data[i] == 12288) {
				data[i] = ' ';
			}
		}
		return data;
	}

	public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
		if (t == HTML.Tag.TABLE) {
			tableCount++;
			trCount = 0;
			stTR = true;
		}

		if (t == HTML.Tag.TR) {
			trCount++;
			stTR = true;
		}

		if (t == HTML.Tag.TD) {
			stTD = true;
			if (stTR != true) {
				stTR = true;
				trCount++;
			}

			width = (String) a.getAttribute(HTML.Attribute.WIDTH);
			colspan = (String) a.getAttribute(HTML.Attribute.COLSPAN);
			rowspan = (String) a.getAttribute(HTML.Attribute.ROWSPAN);
		}
	}

	public void handleEndTag(HTML.Tag t, int pos) {
		if (t == HTML.Tag.TD) {
			stTD = false;

			TD.put("table", "" + tableCount);
			TD.put("tr", "" + trCount);
			TD.put("text", MString.checkNull(text));
			TD.put("width", MString.checkNull(width));

			colspan = MString.checkNull(colspan);
			if ("".equals(colspan))
				colspan = "1";
			rowspan = MString.checkNull(rowspan);

			if ("".equals(rowspan))
				rowspan = "1";

			TD.put("colspan", colspan);
			TD.put("rowspan", rowspan);

			vTDs.add(TD);

			text = "";
			colspan = "";
			rowspan = "";
			width = "";
			stTD = false;
			TD = new Hashtable<String, String>();
		}

		if (t == HTML.Tag.TR) {
			stTR = false;
		}

                //42.비어있는 if문 : Delete by YOUNGJUN,CHO
		//if (t == HTML.Tag.TABLE) {
		//}
                //------------------------------------------------
	}

	// ///////////// 추가 ///////////////
	public int getInt(Hashtable<String, String> ht, String Key) throws NumberFormatException {
		String str = ht.get(Key);
		return Integer.parseInt(str);
	}

	public String getInt2Abc(int i) {
		if (i < 26) {
			return "" + (char) ('A' + i);
		} else {
			return getInt2Abc((i / 26) - 1) + getInt2Abc(i % 26);
		}
	}

	static public String getCutPreTag(String copyForm) {
		int strPre = 0;

		strPre = copyForm.indexOf("<pre>");

		if (strPre < 0) {
			strPre = copyForm.indexOf("<PRE>");
		}

		if (strPre >= 0) {
			copyForm = copyForm.substring(5, copyForm.length());
		}

		int endPre = 0;
		endPre = copyForm.lastIndexOf("</pre");

		if (strPre < 0) {
			endPre = copyForm.lastIndexOf("</PRE");
		}

		if (endPre >= 0) {
			copyForm = copyForm.substring(0, endPre);
		}

		return copyForm;
	}
}
