package com.ced.sip.contract.util.alertFile;



import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;

public class WordTemplate {

    private XWPFDocument document;

    public WordTemplate(InputStream inputStream) throws IOException {
        document = new XWPFDocument(inputStream);
    }

    public void replaceTag(Map<String, Object> map) {
        for (Entry<String, Object> item : map.entrySet()) {
            if (item.getKey().equals("String")) {// 鐩爣涓烘枃鏈�
                Map<String, String> tempMap = (Map<String, String>) item.getValue();
                replaceParagraphs(tempMap);
                replaceTables(tempMap);
            } else if (item.getKey().equals("Table")) {// 鐩爣涓鸿〃鏍�
                replaceKeyToTables((Map<String, Object>) item.getValue());
            }

        }

    }

    public void write(OutputStream outputStream) throws IOException {
        document.write(outputStream);
    }

    /**
     * 鏇挎崲娈佃惤閲岀殑淇℃伅顒�
     * 
     * @param map
     */
    private void replaceParagraphs(Map<String, String> map) {
        List<XWPFParagraph> allXWPFParagraphs = document.getParagraphs();
        for (XWPFParagraph XwpfParagrapg : allXWPFParagraphs) {
            XWPFParagraphHandler XwpfParagrapgUtils = new XWPFParagraphHandler(XwpfParagrapg);
            XwpfParagrapgUtils.replaceAll(map);
        }
    }

    /**
     * 鏇挎崲琛ㄦ牸閲岀殑淇℃伅顒�
     * 
     * @param map
     */
    private void replaceTables(Map<String, String> map) {
        List<XWPFTable> xwpfTables = document.getTables();
        for (XWPFTable xwpfTable : xwpfTables) {
            XWPFTableHandler xwpfTableUtils = new XWPFTableHandler(xwpfTable);
            xwpfTableUtils.replace(map);
        }
    }

    /**
     * 鏇挎崲琛ㄦ牸
     *
     * @author huangdongkui
     * @param map
     */
    public void replaceKeyToTables(Map<String, Object> param) {
        List<XWPFParagraph> paragraphList = document.getParagraphs();
        if (paragraphList != null && paragraphList.size() > 0) {
            for (XWPFParagraph paragraph : paragraphList) {
                String text = paragraph.getParagraphText();
                //System.out.println(text);
                for (Entry<String, Object> entry : param.entrySet()) {
                    String key = entry.getKey();
                    if (text.indexOf(key) != -1) {

                        Object value = entry.getValue();
                        if (value instanceof List) {// 琛ㄦ牸
                            text = text.replace(key, "");

                            XWPFTable tableOne = document.insertNewTbl(paragraph.getCTP().newCursor());
                            int rowLength=0;
                            //娣诲姞鍒�
                            for (int col = 1; col < ((Map<String, String>) ((List) value).get(0)).entrySet().size(); col++) {
                                tableOne.addNewCol();
                            }

                            // 濉厖鍒楀ご
                            XWPFTableRow crow = tableOne.createRow();
                            rowLength++;
                            int k = 0;
                            for (Entry<String, String> col : ((Map<String, String>) ((List) value).get(0)).entrySet()) {
                                String skey = col.getKey();
                                    crow.getCell(k).setText(skey);
                                    k++;
                            }

                            for (int i = 1; i < ((List) value).size(); i++) {
                                // 娣诲姞琛�
                                XWPFTableRow rrow = tableOne.createRow();
                                rowLength++;
                                int j = 0;
                                for (Entry<String, String> col : ((Map<String, String>) ((List) value).get(i)).entrySet()) {
                                    String sValue = col.getValue();
                                        rrow.getCell(j).setText(sValue);

                                        j++;
                                }

                            }

                            tableOne.removeRow(0);
                            rowLength=rowLength-1;
                            setTableWidthAndHAlign(tableOne, "10000", STJc.CENTER);
                            System.out.println(rowLength);
                            mergeCellsHorizontal(tableOne,rowLength,0,6);
                            mergeCellsHorizontal(tableOne,rowLength,7,8);
                        }
                        List<XWPFRun> runs = paragraph.getRuns();

                        for (XWPFRun xwpfrun : runs) {
                            xwpfrun.setText("", 0);
                        }

                    }
                }
            }
        }
    }

    public void setTableWidthAndHAlign(XWPFTable table, String width, STJc.Enum enumValue) {
        CTTblPr tblPr = getTableCTTblPr(table);
        CTTblWidth tblWidth = tblPr.isSetTblW() ? tblPr.getTblW() : tblPr.addNewTblW();
        if (enumValue != null) {
            CTJc cTJc = tblPr.addNewJc();
            cTJc.setVal(enumValue);
        }

        tblWidth.setW(new BigInteger(width));
        tblWidth.setType(STTblWidth.DXA);

    }

	/**
	 * @Description: 跨列合并
	 */
	public  void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {
        for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {
            XWPFTableCell cell = table.getRow(row).getCell(cellIndex);
            if ( cellIndex == fromCell ) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
	
	/**
	 * @Description: 跨行合并
	 * @see http://stackoverflow.com/questions/24907541/row-span-with-xwpftable
	 */
    public  void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            if ( rowIndex == fromRow ) {
                // The first merged cell is set with RESTART merge value
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);
            } else {
                // Cells which join (merge) the first one, are set with CONTINUE
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);
            }
        }
    }
    /**
     * @Description: 寰楀埌Table鐨凜TTblPr,涓嶅瓨鍦ㄥ垯鏂板缓
     */
    public CTTblPr getTableCTTblPr(XWPFTable table) {
        CTTbl ttbl = table.getCTTbl();
        CTTblPr tblPr = ttbl.getTblPr() == null ? ttbl.addNewTblPr() : ttbl.getTblPr();
        return tblPr;
    }

}
