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



import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;

public class XWPFParagraphHandler {
	
	private XWPFParagraph paragraph;
	
	private List<XWPFRun> allXWPFRuns;
	//鎵�鏈塺un鐨凷tring鍚堝苟鍚庣殑鍐呭
	private StringBuffer context ;
	//闀垮害涓巆ontext瀵瑰簲鐨凴unChar闆嗗悎
	List<RunChar> runChars ;
	
	public XWPFParagraphHandler(XWPFParagraph paragraph){
		this.paragraph = paragraph;
		initParameter();
	}
	
	/**
	 * 鍒濆鍖栧悇鍙傛暟
	 */
	private void initParameter(){
		context = new StringBuffer();
		runChars = new ArrayList<XWPFParagraphHandler.RunChar>();
		allXWPFRuns = new ArrayList<XWPFRun>();
		setXWPFRun();
	}
	
	
	/**
	 * 璁剧疆XWPFRun鐩稿叧鐨勫弬鏁�
	 * @param run
	 * @throws Exception
	 */
	private void setXWPFRun() {
		
		allXWPFRuns = paragraph.getRuns();
		if(allXWPFRuns == null || allXWPFRuns.size() == 0){
			return;
		}else{
			for (XWPFRun run : allXWPFRuns) {
				int testPosition = run.getTextPosition();
				String text = run.getText(testPosition);
				if(text == null || text.length() == 0){
					return;
				}
				
				this.context.append(text);
				for(int i = 0 ; i < text.length() ; i++){
					runChars.add(new RunChar(text.charAt(i), run));
				}
			}
		}
		//System.out.println(context.toString());
	}
	
	/**
	 * 鑾峰彇鎵�鏈夌殑鏂囨湰鍐呭
	 * @return
	 */
	public String getString(){
		return context.toString();
	}
	
	/**
	 * 鍒ゆ柇鏄惁鍖呭惈鎸囧畾鐨勫唴瀹�
	 * @param key
	 * @return
	 */
	public boolean contains(String key){
		return context.indexOf(key) >= 0 ? true : false;
	}
	
	/**
	 * 鎵�鏈夊尮閰嶇殑鍊兼浛鎹负瀵瑰簲鐨勫��
	 * @param key(鍖归厤妯℃澘涓殑${key})
	 * @param value 鏇挎崲鍚庣殑鍊�
	 * @return
	 */
	public boolean replaceAll(String key,String value){
		boolean replaceSuccess = false;
		key = "{" + key + "}";
		while(replace(key, value)){
			replaceSuccess = true;
		}
		return replaceSuccess;
	}
	
	/**
	 * 鎵�鏈夊尮閰嶇殑鍊兼浛鎹负瀵瑰簲鐨勫��(key鍖归厤妯℃澘涓殑${key})
	 * @param param 瑕佹浛鎹㈢殑key-value闆嗗悎
	 * @return
	 */
	public boolean replaceAll(Map<String,String> param){
		Set<Entry<String, String>> entrys = param.entrySet();
		boolean replaceSuccess = false;
		String value="";
		for (Entry<String, String> entry : entrys) {
			String key = entry.getKey();
			if(entry.getValue()!=null) value=entry.getValue().toString();
			boolean currSuccessReplace = replaceAll(key,value);
			replaceSuccess = replaceSuccess?replaceSuccess:currSuccessReplace;
		}
		return replaceSuccess;
	}
	
	/**
	 * 灏嗙涓�涓尮閰嶅埌鐨勫�兼浛鎻涗负瀵瑰簲鐨勫��
	 * @param key 
	 * @param value
	 * @return
	 */
	private boolean replace(String key,String value){
		if(contains(key)){
			/*
			 * 1:寰楀甫key瀵瑰簲鐨勫紑濮嬪拰缁撴潫涓嬫爣
			 */
			int startIndex = context.indexOf(key);
			int endIndex = startIndex+key.length();
			/*
			 * 2:鑾峰彇绗竴涓尮閰嶇殑XWPFRun
			 */
			RunChar startRunChar = runChars.get(startIndex);
			XWPFRun startRun = startRunChar.getRun();
			/*
			 * 3:灏嗗尮閰嶇殑key娓呯┖
			 */
			runChars.subList(startIndex, endIndex).clear();
			/*
			 * 4:灏唙alue璁剧疆鍒皊tartRun涓�
			 */
			List<RunChar> addRunChar = new ArrayList<XWPFParagraphHandler.RunChar>();
			for(int i = 0 ; i < value.length() ; i++){
				addRunChar.add(new RunChar(value.charAt(i), startRun));
			}
			runChars.addAll(startIndex, addRunChar);
			resetRunContext(runChars);
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 閲嶆柊璁剧疆鍏叡鐨勫弬鏁�
	 * @param newRunChars
	 */
	private void resetRunContext(List<RunChar> newRunChars){
		/*
		 * 鐢熸垚鏂扮殑XWPFRun涓嶤ontext鐨勫搴斿叧绯�
		 */
		HashMap<XWPFRun, StringBuffer> newRunContext = new HashMap<XWPFRun, StringBuffer>();
		//閲嶈context
		context = new StringBuffer();
		XWPFParagraph paragraphasBreak = null;
		
		for(RunChar runChar : newRunChars){
			StringBuffer newRunText ;
			if(newRunContext.containsKey(runChar.getRun())){
				newRunText = newRunContext.get(runChar.getRun());
			}else{
				newRunText = new StringBuffer();
			}
			context.append(runChar.getValue());
			newRunText.append(runChar.getValue());
			newRunContext.put(runChar.getRun(), newRunText);
		}
		
		/*
		 * 閬嶅巻鏃х殑runContext,鏇挎崲context
		 * 骞堕噸鏂拌缃畆un鐨則ext,濡傛灉涓嶅尮閰�,text璁剧疆涓�""
		 */
		for(XWPFRun run : allXWPFRuns){
			if(newRunContext.containsKey(run)){
				String newContext = newRunContext.get(run).toString();
				
				if (newContext.toString().contains("<br>")) {
                    paragraphasBreak = paragraph;
                }
				
				XWPFRunHandler.setText(run,newContext);
			}else{
				XWPFRunHandler.setText(run,"");
			}
		}
		
		//瑙ｆ瀽澶勭悊娈佃惤涓璡n鐨勬崲琛�
		if (paragraphasBreak != null) {
	            
	            String[] str = paragraphasBreak.getText().split("<br>");
	    
	            int i = 0;
	            for (String string : str) {

	                XWPFRun rn = paragraphasBreak.getRun(paragraphasBreak.getRuns().get(0).getCTR());
	                if (i >= 1) {
	                    rn.getCTR().addNewTab();
	                }

	                rn.setText(string);


	                rn.getCTR().addNewCr();
	                i++;

	                paragraphasBreak.addRun(rn);

	                CTPPr pPPr = paragraphasBreak.getCTP().getPPr();
	                CTSpacing pSpacing = pPPr.getSpacing() != null ? pPPr
	                        .getSpacing() : pPPr.addNewSpacing();

	                pSpacing.setLine(new BigInteger("200"));
	                
	            }
	        
	            
	            paragraphasBreak.getRuns().get(0).setText("", 0);
	    
	        }
	}
	
	/**
	 * 瀹炰綋绫�:瀛樺偍瀛楄妭涓嶺WPFRun瀵硅薄鐨勫搴斿叧绯�
	 * @author JianQiu
	 */
	class RunChar{
		/**
		 * 瀛楄妭
		 */
		private char value;
		/**
		 * 瀵瑰簲鐨刋WPFRun
		 */
		private XWPFRun run;
		public RunChar(char value,XWPFRun run){
			this.setValue(value);
			this.setRun(run);
		}
		public char getValue() {
			return value;
		}
		public void setValue(char value) {
			this.value = value;
		}
		public XWPFRun getRun() {
			return run;
		}
		public void setRun(XWPFRun run) {
			this.run = run;
		}
		
	}
}
