/**
 *
 */
package kr.co.kihyun.beans.entity.util;

import java.util.List;

import kr.co.kihyun.beans.entity.TotDoc;
import kr.co.kihyun.beans.entity.TotReport;
import kr.co.kihyun.beans.entity.TotTable;
import kr.co.kihyun.beans.totsys.doc.table.item.ItemList;
import kr.co.kihyun.moumi.doc.table.MTable;
import kr.co.kihyun.moumi.doc.table.MTableAnalysis;
import kr.co.kihyun.moumi.report.MReport;
import kr.co.kihyun.moumi.report.MReportData;
import kr.co.kihyun.moumi.report.MReportMaker;
import kr.co.kihyun.text.html.HtmlUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author bhs
 *
 */
public class TotReportUtil {
	private static final Logger LOG = LoggerFactory.getLogger(TotReportUtil.class);

	public static String toHTML(TotReport totReport) {
		return toHTML(totReport, -1, false, false);
	}

	public static String toHTML(TotReport totReport, boolean removeTitle) {
		return toHTML(totReport, -1, removeTitle, true);
	}

	/**
	 * @param totReport
	 * @param tableNum
	 *            start from 1
	 * @return
	 */
	public static String toHTML(TotReport totReport, int tableNum) {
		return toHTML(totReport, tableNum, false, true);
	}

	// FIXME: evil moumi method
	/**
	 * @param totReport
	 * @param tableNum
	 *            start from 1
	 * @param removeTitle
	 * @return
	 */
	public static String toHTML(TotReport totReport, int tableNum, boolean removeTitle, boolean tableOnly) {
		if (totReport.getData() == null)
			return null;

		String[] dataList = MReportData.getDataArray(totReport.getData());
//		String[] totDataList = MReportData.getDataArray(totReport.getTotData());
		TotDoc totDoc = totReport.getTotDoc();
		if (totDoc.getMasterTotDoc() != null)
			totDoc = totDoc.getMasterTotDoc();
		String[] tableTypesList = totDoc.getTotTables().iterator().next().getTypes().split(",");
		int[] tableColNumList = MReportData.getColNumList(totReport.getData());
		int[] tableRowNumList = MReportData.getRowNumList(totReport.getData());
		String[] titleForms = new String[tableRowNumList.length];
		String[] dataForms = new String[tableRowNumList.length];
		String[] tailForms = new String[tableRowNumList.length];
		for (int i = 0; i < dataList.length; i++) {
			dataList[i] = dataList[i].replaceAll(" ", "&nbsp;");
			dataList[i] = dataList[i].replaceAll("<", "&lt");
			dataList[i] = dataList[i].replaceAll(">", "&gt");
		}

		String[] subForm = new String[tableRowNumList.length];
		String Form = totDoc.getForm();
		int stTABLE = 0;
		int edTABLE = 0;
		int here = 0;

		for (int i = 0; i < tableRowNumList.length; i++) {
			if (Form.indexOf("</table>", here) < 0)
				break;
			subForm[i] = MReport.geteExtractTable(Form, here);
			here = Form.indexOf("</table>", here) + 8;
			//마지막 텍스트 짤리는거 수정
			if(i==tableRowNumList.length-1){
				subForm[i]+=Form.substring(here);
			}
		}
		if (tableOnly)
			subForm = MReport.geteExtractTable(Form);

		int tablePosition = 0;
		int tp = 0;
		StringBuilder reportBuff = new StringBuilder();

		ItemList itemList = new ItemList();
                //v2. 6.SQL 삽입 : DO형식이므로 해결책에 따른 prepare SQL 문으로 변경할 수 없음
		itemList.executeQuery(totDoc.getId());
                //================
		for (int i = 0; i < tableRowNumList.length; i++) {
			/****** 해당 테이블에 해당하는 아이템 타입 리스트를 구함 ******/
			for (tp = tablePosition; tp < itemList.getTableNumList().length; tp++) {
				if ((i + 1) < itemList.getTableNumList()[tp])
					break;
			}

			int[] tmpItemNumList = new int[tp - tablePosition];
			String[] tmpItemNameList = new String[tp - tablePosition];
			int[] tmpItemBNWList = new int[tp - tablePosition];
			int[] tmpItemTypeList = new int[tp - tablePosition];
			String[] tmpItemExprList = new String[tp - tablePosition];
			int[] tmpItemRowList = new int[tp - tablePosition];

			for (int in = 0, t = tablePosition; t < tp; in++, t++) {
				tmpItemNumList[in] = itemList.getNumList()[t];
				tmpItemNameList[in] = itemList.getNameList()[t];
				tmpItemBNWList[in] = itemList.getBNWList()[t];
				tmpItemTypeList[in] = itemList.getTypeList()[t];
				tmpItemExprList[in] = itemList.getExprList()[t];
				tmpItemRowList[in] = itemList.getRecordNumList()[t];
			}
			int tmpInItemNum = 0;
			int tmpIN = 0;
			for (int a = 0; a < tmpItemTypeList.length; a++) {
				if (tmpItemTypeList[a] != 0) { // MItem.TITLE == 0
					tmpIN = a;
					break;
				}
			}
			for (int a = 0; a < tmpItemRowList.length; a++) {
				if (tmpItemRowList[a] < tmpItemRowList[tmpIN])
					tmpInItemNum++;
				else
					break;
			}

			int tmpTitleRowCount = 0;
			if (tmpInItemNum > 0) {
				tmpTitleRowCount = tmpItemRowList[tmpInItemNum - 1] - tmpItemRowList[0] + 1;
			}
			/***** 해당 테이블에 해당하는 아이템 타입 리스트를 구함 끝 *****/

			String[] subDataList = new String[tableColNumList[i]];
//			String[] subTotDataList = new String[tableColNumList[i]];

			int stData = 0;
//			int stTotData = 0;
			for (int c = 0; c < i; c++) {
				stData = stData + (tableColNumList[c] * tableRowNumList[c]);
//				stTotData = stTotData + tableColNumList[c];
			}

			MTableAnalysis tbAnalysis = new MTableAnalysis(subForm[i], tmpItemTypeList);

			titleForms[i] = tbAnalysis.getTitleForm();
			dataForms[i] = tbAnalysis.getDataForm();
			tailForms[i] = tbAnalysis.getTailForm();

			if (removeTitle) {
				stTABLE = titleForms[i].indexOf("<table");
				edTABLE = titleForms[i].indexOf("<tr", stTABLE);

				if (edTABLE > 0) {
					reportBuff.append(titleForms[i].substring(stTABLE, edTABLE));
				} else {
					reportBuff.append(titleForms[i]);
				}
			} else {
				reportBuff.append(titleForms[i]);
			}

			for (int r = 0; r < tableRowNumList[i]; r++) {
				for (int cp = 0; cp < (tableColNumList[i]); cp++) {
					subDataList[cp] = dataList[stData + cp];
				}
				reportBuff.append(MReportMaker.reportMake(dataForms[i], subDataList, tmpItemNumList, tmpItemNameList,
						tmpItemBNWList, tmpItemTypeList, tmpItemExprList, tmpInItemNum, tmpTitleRowCount,
						tableRowNumList[i], Integer.parseInt(tableTypesList[i]), MReport.HTML));
				stData = stData + tableColNumList[i];
			}
                        /* subtotal 값을 계산하지 않도록 수정 2015.6.16 */
//			int totView = 0;
//			for (int cp = 0; cp < (tableColNumList[i]); cp++) {
//				subTotDataList[cp] = totDataList[stTotData + cp];
//				if (!subTotDataList[cp].equals(" "))
//					totView = 1;
//			}

//			if (tableRowNumList[i] > 1 && totView == 1) {
//				reportBuff.append(MReportMaker.reportMake(dataForms[i], subTotDataList, tmpItemNumList,
//						tmpItemNameList, tmpItemBNWList, tmpItemTypeList, tmpItemExprList, tmpInItemNum,
//						tmpTitleRowCount, tableRowNumList[i], MTable.DYNATOTLINE, MReport.HTML));
//			}
			reportBuff.append(tailForms[i]);

			tablePosition = tp;
		}
		return tableNum > 0 ? HtmlUtil.getTableList(reportBuff)[tableNum - 1] : reportBuff.toString();
	}

	/**
	 * @param totDoc
	 * @param reportList
	 * @return
	 */
	public static String toHTML(TotDoc totDoc, List<TotReport> reportList) {
		return toHTML(totDoc, reportList, -1, false);
	}

	/**
	 * @param totDoc
	 * @param reportList
	 * @param tableNum
	 *            start from 1
	 * @return
	 */
	public static String toHTML(TotDoc totDoc, List<TotReport> reportList, int tableNum) {
		return toHTML(totDoc, reportList, tableNum, false);
	}

	/**
	 * @param totDoc
	 * @param reportList
	 * @param removeTitle
	 * @return
	 */
	public static String toHTML(TotDoc totDoc, List<TotReport> reportList, boolean removeTitle) {
		return toHTML(totDoc, reportList, -1, removeTitle);
	}

	// FIXME: evil moumi method
	/**
	 * @param totDoc
	 * @param reportList
	 * @param tableNum
	 *            start from 1
	 * @param removeTitle
	 * @return
	 */
	public static String toHTML(TotDoc totDoc, List<TotReport> reportList, int tableNum, boolean removeTitle) {
		// actionType 값이 view 이면 <br> 붙이고 그외에는 붙이지 않고 가져옴
		// dataType 값이 onlyData 이면 data 만 가져옴, 그외에는 title 와 data 붙여서 가져옴
        //System.out.println("reportList 사이즈:::::"+reportList.size());

		TotTable totTable = totDoc.getTotTables().iterator().next();
		String[] tableTypesList = totTable.getTypes().split(",");

		StringBuilder allDatas = new StringBuilder();
		StringBuilder allTotDatas = new StringBuilder();
		for (int ad = 0; ad < tableTypesList.length; ad++) {
			for (int rc = 0; rc < reportList.size(); rc++) {
				LOG.debug("reportList.get({}): {}", rc, reportList.get(rc));
				LOG.debug("reportList.get({}).getData(): {}", rc, reportList.get(rc).getData());
				String[] adl = reportList.get(rc).getData().split(TotReport.TABLE_DELIMITER);
				String[] atdl = reportList.get(rc).getTotData().split(TotReport.TABLE_DELIMITER);

				if (!allDatas.toString().equals("")) {
					if (rc == 0) {
						allDatas.append(TotReport.TABLE_DELIMITER);
						allDatas.append(adl[ad]);
					} else {
						allDatas.append(TotReport.ROW_DELIMITER);
						allDatas.append(adl[ad]);
					}
				} else
					allDatas.append(adl[ad]);

				if (!allTotDatas.toString().equals("")) {
					if (rc == 0) {
						allTotDatas.append(TotReport.TABLE_DELIMITER);
						allTotDatas.append(atdl[ad]);
					} else {
						allTotDatas.append(TotReport.ROW_DELIMITER);
						allTotDatas.append(atdl[ad]);
					}
				} else
					allTotDatas.append(atdl[ad]);
			}
		}

		int[] tableColNumList = MReportData.getColNumList(allDatas.toString());
		int[] tableRowNumList = MReportData.getRowNumList(allDatas.toString());

		String[] tableRowList = new String[tableRowNumList.length];
		for (int tr = 0; tr < tableRowNumList.length; tr++)
			tableRowList[tr] = Integer.toString(tableRowNumList[tr]);

		int inItemCount = 0;
		for (int tc = 0; tc < tableColNumList.length; tc++) {
			inItemCount = inItemCount + tableColNumList[tc];
                //System.out.println("tableColNumList:::::"+tableColNumList[tc]);
		}

		ItemList itemList = new ItemList();
                //v2. 6.SQL 삽입 : DO형식이므로 해결책에 따른 prepare SQL 문으로 변경할 수 없음
		itemList.executeQuery(totDoc.getId());
                //================
		String[] tmpdataList = MReportData.getDataArray(allDatas.toString());
		String[] allDataList = MReportData.getTotalDataList(0, inItemCount, tableColNumList, tableRowList,itemList.getTypeList(), itemList.getExprList(), tmpdataList, itemList.getNameList());

		StringBuilder reportBuff = new StringBuilder();

		String[] titleForms = new String[tableRowNumList.length];
		String[] dataForms = new String[tableRowNumList.length];
		String[] tailForms = new String[tableRowNumList.length];
		String[] subForm = new String[tableRowNumList.length];
		String Form = totDoc.getForm();
		int stTABLE = 0;
		int edTABLE = 0;

		int here = 0;
		for (int i = 0; i < tableRowNumList.length; i++) {
			if (Form.indexOf("</table>", here) < 0)
				break;
			subForm[i] = MReport.geteExtractTable(Form, here);
			here = Form.indexOf("</table>", here) + 8;
		}

		subForm = MReport.geteExtractTable(Form);
		int tablePosition = 0;
		int tp = 0;
		reportBuff = new StringBuilder();

		for (int i = 0; i < tableRowNumList.length; i++) {
			for (tp = tablePosition; tp < itemList.getTableNumList().length; tp++) {
				if ((i + 1) < itemList.getTableNumList()[tp])
					break;
			}

			int[] tmpItemNumList = new int[tp - tablePosition];
			String[] tmpItemNameList = new String[tp - tablePosition];
			int[] tmpItemBNWList = new int[tp - tablePosition];
			int[] tmpItemTypeList = new int[tp - tablePosition];
			String[] tmpItemExprList = new String[tp - tablePosition];
			int[] tmpItemRowList = new int[tp - tablePosition];

			for (int in = 0, t = tablePosition; t < tp; in++, t++) {
				tmpItemNumList[in] = itemList.getNumList()[t];
				tmpItemNameList[in] = itemList.getNameList()[t];
				tmpItemBNWList[in] = itemList.getBNWList()[t];
				tmpItemTypeList[in] = itemList.getTypeList()[t];
				tmpItemExprList[in] = itemList.getExprList()[t];
				tmpItemRowList[in] = itemList.getRecordNumList()[t];
			}
			int tmpInItemNum = 0;
			int tmpIN = 0;
			for (int a = 0; a < tmpItemTypeList.length; a++) {
				if (tmpItemTypeList[a] != 0) { // MItem.TITLE == 0
					tmpIN = a;
					break;
				}
			}
			for (int a = 0; a < tmpItemRowList.length; a++) {
				if (tmpItemRowList[a] < tmpItemRowList[tmpIN])
					tmpInItemNum++;
				else
					break;
			}

			int tmpTitleRowCount = 0;
			if (tmpInItemNum > 0) {
				tmpTitleRowCount = tmpItemRowList[tmpInItemNum - 1] - tmpItemRowList[0] + 1;
			}

			String[] subDataList = new String[tableColNumList[i]];
			int stData = 0;
//			int stTotData = 0;
			for (int c = 0; c < i; c++) {
				stData = stData + (tableColNumList[c] * tableRowNumList[c]);
//				stTotData = stTotData + tableColNumList[c];
			}

			MTableAnalysis tbAnalysis = new MTableAnalysis(subForm[i], tmpItemTypeList);

			titleForms[i] = tbAnalysis.getTitleForm();
			dataForms[i] = tbAnalysis.getDataForm();
			tailForms[i] = tbAnalysis.getTailForm();

			for (int a = 0; a < tableRowNumList.length; a++) {
				tableRowNumList[a] = 1;
			}

			if (removeTitle) {
				stTABLE = titleForms[i].indexOf("<table");
				edTABLE = titleForms[i].indexOf("<tr", stTABLE);

				if (edTABLE > 0) {
					reportBuff.append(titleForms[i].substring(stTABLE, edTABLE));
				} else {
					reportBuff.append(titleForms[i]);
				}
			} else {
				reportBuff.append(titleForms[i]);
			}

			for (int r = 0; r < tableRowNumList[i]; r++) {
				for (int cp = 0; cp < (tableColNumList[i]); cp++) {
					subDataList[cp] = allDataList[stData + cp];

                    //System.out.println(":::배열찍기:::"+subDataList[cp]);
				}
				reportBuff.append(MReportMaker.reportMake(dataForms[i], subDataList, tmpItemNumList, tmpItemNameList,
						tmpItemBNWList, tmpItemTypeList, tmpItemExprList, tmpInItemNum, tmpTitleRowCount,
						tableRowNumList[i], Integer.parseInt(tableTypesList[i]), MReport.HTML));
				stData = stData + tableColNumList[i];
			}
			reportBuff.append(tailForms[i]);
			tablePosition = tp;
		}
		return tableNum > 0 ? HtmlUtil.getTableList(reportBuff)[tableNum - 1] : reportBuff.toString();
	}
}
