package cn.hmsoft.ltc.controller;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.sql.SQLException;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ResourceBundle;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import cn.hmsoft.ltc.common.constants.LtContext;
import cn.hmsoft.ltc.common.constants.SysConst;
import cn.hmsoft.ltc.common.constants.SysConst.PaperStageEnum;
import cn.hmsoft.ltc.common.util.DialogUtil;
import cn.hmsoft.ltc.common.util.DocUtil;
import cn.hmsoft.ltc.common.util.POIUtil;
import cn.hmsoft.ltc.common.util.StageManager;
import cn.hmsoft.ltc.model.CourseQuestion;
import cn.hmsoft.ltc.model.DetailTable;
import cn.hmsoft.ltc.model.QuestionType;
import cn.hmsoft.ltc.model.Subject;
import cn.hmsoft.ltc.model.TestPaper;
import cn.hmsoft.ltc.model.Users;
import cn.hmsoft.ltc.service.iface.CourseQuestionService;
import cn.hmsoft.ltc.service.iface.DetailTableService;
import cn.hmsoft.ltc.service.iface.QuestionTypeService;
import cn.hmsoft.ltc.service.iface.SubjectOptionServie;
import cn.hmsoft.ltc.service.iface.SubjectService;
import cn.hmsoft.ltc.service.iface.TestPaperService;
import cn.hmsoft.ltc.service.iface.UserService;
import cn.hmsoft.ltc.service.impl.CourseQuestionServiceImpl;
import cn.hmsoft.ltc.service.impl.DetailTableServiceImpl;
import cn.hmsoft.ltc.service.impl.QuestionTypeServiceImpl;
import cn.hmsoft.ltc.service.impl.SubjectOptionServieImpl;
import cn.hmsoft.ltc.service.impl.SubjectServiceImpl;
import cn.hmsoft.ltc.service.impl.TestPaperServiceImpl;
import cn.hmsoft.ltc.service.impl.UserServiceImpl;
import de.felixroske.jfxsupport.FXMLController;
import de.felixroske.jfxsupport.GUIState;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Screen;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

/**
 * 细目表控制器
 * @author zq
 *
 */
@FXMLController
public class DetailTableController implements Initializable {
    @FXML
    public Button detailSaveBtn;
    @FXML
    public Button editSubjectBtn;
	@FXML
	public Button exportBtn; //导出（导出试卷、答案、题卡）
    @FXML
    public WebView webView;
    @FXML
    public WebEngine webEngine;
	private UserService userService = new UserServiceImpl();
    private SubjectService subjectService = new SubjectServiceImpl();//题目
    private SubjectOptionServie subjectOptionServie = new SubjectOptionServieImpl();//题目选项
    private DetailTableService detailTableService = new DetailTableServiceImpl(); //细目表
    private QuestionTypeService questionTypeService = new QuestionTypeServiceImpl();//题型
	private CourseQuestionService courseQuestionService = new CourseQuestionServiceImpl();//课程题型O
	public TestPaperService testPaperService = new TestPaperServiceImpl();  //试卷管理
	private static final Logger LOGGER = Logger.getLogger(DetailTableController.class);
	
	@Override
	public void initialize(URL location, ResourceBundle resources) {
		StageManager.CONTROLLER.put("detailTableController", this);
		webEngine = webView.getEngine();
	    webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
	    	@SuppressWarnings({ "unused", "rawtypes" })
			@Override
	        public void changed(ObservableValue ov, State oldState, State newState) {
	    		if (newState == Worker.State.SUCCEEDED) {
	            	JSObject win = (JSObject) webEngine.executeScript("window");
					String cqJson = getPaperQuestionJsons();
					webEngine.executeScript("loadInitData('" + LtContext.CURR_PAPER.getKeyChapters() + "','" + LtContext.CURR_PAPER.getChapterNumber() + "','" + cqJson +"');");
					//如果有选择的课程，则查询出之前保存的明细
					TestPaper selectTestPaper = LtContext.CURR_PAPER;
					if (selectTestPaper != null && selectTestPaper.getId() != -1) {
						freshDetailTable(selectTestPaper.getPaperNo());
					}
	            }
	        }
	    });
	    webEngine.load(getClass().getResource("/templates/Detail.html").toExternalForm());
	}

	private String getPaperQuestionJsons() {
		try {
			List<CourseQuestion>  cqList = courseQuestionService.findCourseQuestion(LtContext.CURR_PAPER.getCourseId());
			LtContext.CURR_PAPER.setQuesTypeNum(cqList.size());
			return JSON.toJSONString(cqList);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return "";
	}
	
	/**
	 * 课程对应的题型 关联信息.
	 * @param courseId
	 * @return
	 */
	private Map<Integer, CourseQuestion> getCourseQuesMap(Integer courseId) {
		Map<Integer, CourseQuestion> map = new HashMap<Integer, CourseQuestion>();
		try {
			List<CourseQuestion> cqList = courseQuestionService.findCourseQuestion(LtContext.CURR_PAPER.getCourseId());
			for (CourseQuestion cq : cqList) {
				map.put(cq.getQuesTypeId(), cq);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	 * 保存细目表
	 * 生成word文档明细：100 1,2,3 200 4,5,6,7 300 8,9 400 10,其中 100,200,300,400是大题word名.
	 * 
	 * @param event
	 */
	@FXML
	public void saveTableFunc(ActionEvent event) {
		// 课程编号不能为空
		TestPaper currPaper = LtContext.CURR_PAPER;
		String str = (String)webEngine.executeScript("getPageData();");
		String keyChapters = (String)webEngine.executeScript("getKeyChapters();");
		List<DetailTable> tableList = JSON.parseArray(str, DetailTable.class);
		if (tableList.size() == 0) {
			DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.WARNING, "提示", "请选择题型并设置细目表!");
			return;
		}
		boolean existErr = this.checkDetailTableValid(tableList, keyChapters);
		if (!existErr) {
			//更新试卷表的重点章节
			LtContext.CURR_PAPER.setKeyChapters(keyChapters);//更新缓存对象
			this.testPaperService.updateTestPaperKeyChapter(currPaper.getPaperNo(), keyChapters);
			Map<String,Integer> chapterDistMap = this.getSubjectChapterMap(currPaper.getPaperNo());
			//准备试卷目录
			File quesDir = this.preparePaperDir(currPaper);
			//创建大题型 对应的word
			Map<Integer, CourseQuestion> cqMap = this.getCourseQuesMap(currPaper.getCourseId());
			//细目表是否调整过
			boolean changed = false;
			//创建或更新细目表
			Integer baseOrd = 0;
			List<DetailTable> toBeUpdateList = new ArrayList<DetailTable>();
			for (DetailTable table : tableList) {
				if (table.getQuestionTypeId() > 0) {
					table.setPaperNo(currPaper.getPaperNo());
					table.setCourseCode(currPaper.getCourseCode());
					table.setCourseName(currPaper.getCourseName());
					table.setCourseId(currPaper.getCourseId());
					if (table.getId() != null && table.getId() > 0) {
						//删除题目后再创
						boolean hasChange = this.isModified(currPaper, table, chapterDistMap, cqMap, quesDir);
						if (hasChange) {
							//加入待修改细目表
							toBeUpdateList.add(table);
							if (!changed) {
								changed = hasChange;
							}
						}
					} else {
						//保存细目表
						detailTableService.insertDetailTable(table);
						//创建细目表对应的题目框架
						try {
							baseOrd = this.createTableSubjectOrDocx(table, currPaper, cqMap, quesDir, baseOrd, true, true);
						} catch (Exception e) {
							LOGGER.error(e);
						}
					}
				}
			}
			//修改细目表后 所有文档 重新生成****************************
			if (changed) {
				//删除subject
				try {
					if (DialogUtil.confirm("细目表修改后，对应题型会对已经编辑的题目做清空处理，请谨慎修改细目表。确定保存？", GUIState.getStage())) {
						//备份之前的文档 合并到 bak 目录
						this.bakupPaper(currPaper);
						
						for (DetailTable table : toBeUpdateList) {
							//更新有修改的题型对应细目表
							detailTableService.updateDetailTable(table);
							//删除指定题型对应的所有的subject
							List<Subject> subjectList = this.subjectService.findSubjectList(currPaper.getPaperNo(), table.getQuestionTypeId());
							final Map<Integer, Integer> map = this.getChapterMap(table, subjectList.get(0).getOrd());
							for (Subject subject : subjectList) {
								subject.setChapter(String.valueOf(map.get(subject.getOrd())));
								this.subjectService.updateSubject(subject);
							}
						}
						//清理并重新创建docx
						//this.cleanAndReCreateDocx(quesDir, currPaper, cqMap, toBeUpdateList);
						
						this.updatePaperStatus(currPaper, PaperStageEnum.DT_DONE.ordinal());
						//刷新最新数据到前端
						this.freshDetailTable(currPaper.getPaperNo());
						DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.INFORMATION, "提示", "保存成功!");
					} else {
						//刷新显示之前保存的细目表
						this.freshDetailTable(currPaper.getPaperNo());
					}
				} catch (Exception e) {
					DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.INFORMATION, "错误", e.getMessage());
					LOGGER.error(e);
				}
			} else {
				this.updatePaperStatus(currPaper, PaperStageEnum.DT_DONE.ordinal());
				this.freshDetailTable(currPaper.getPaperNo());
				DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.INFORMATION, "提示", "保存成功!");
			}
		}
	}

	private Map<Integer, Integer> getChapterMap(DetailTable table, int startOrd) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		Class<DetailTable> CLAZZ = DetailTable.class;
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		int baseOrd = startOrd;
		for (int m=0; m<=SysConst.MAX_CHAPTERS; m++) {
			Object objNums = CLAZZ.getMethod("getTx" + m + "Nums", null).invoke(table, null);
			if (objNums != null) {
				Integer txNums = Integer.valueOf(objNums.toString());
				for (int i=1; i<=txNums; i++) {
					map.put(baseOrd, m);
					baseOrd++;
				}
			}
		}
		return map;
	}
	
	//备份试卷到bak目录
	private void bakupPaper(TestPaper currPaper) {
		try {
			String paprePrifix = LtContext.CURR_PAPER.getPaperNo().substring(0, LtContext.CURR_PAPER.getPaperNo().length() - 1);
			String basePath = System.getProperty("user.dir") + File.separator + "papers" + File.separator + paprePrifix + File.separator + LtContext.CURR_PAPER.getPaperNo() + File.separator;
			List<CourseQuestion> cqList = this.courseQuestionService.findCourseQuestion(LtContext.CURR_PAPER.getCourseId());
			int bigQs = 0;
			int smQs = 0;
			bigQs = cqList.size();
			for (CourseQuestion cq : cqList) {
				smQs += cq.getQuesNums();
			}
			String paperAB = LtContext.CURR_PAPER.getPaperNo().substring(LtContext.CURR_PAPER.getPaperNo().length()-1, LtContext.CURR_PAPER.getPaperNo().length());
			
			//生成试卷头docx
			String headDocx = basePath + "ques" + File.separator + "0.docx";
			DocUtil.genPaperHeaderWord("header.ftl", headDocx, bigQs, smQs, LtContext.CURR_PAPER.getCourseCode(), LtContext.CURR_PAPER.getCourseName(), LtContext.CURR_PAPER.getPaperNo());
			//合并生成试卷文档--到备份目录
			String strCopyFolderArg = basePath + "ques";//试题目录
			String outDocArg = basePath + "bak" + File.separator + LtContext.CURR_PAPER.getPaperNo() + ".docx";
			Map<Integer, QuestionType> quesMap = this.subjectService.getQuestionTypeMap();
			POIUtil.mergeDoc(POIUtil.getSrcDocxArr(quesMap, strCopyFolderArg, cqList), outDocArg, LtContext.CURR_PAPER.getCourseCode(), 
					LtContext.CURR_PAPER.getCourseName(), paperAB);
		} catch (Exception e) {
			DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.ERROR, "错误", e.getMessage());
			LOGGER.error(e);
		}
	}
	
	private void updatePaperStatus(TestPaper currPaper, int status) {
		//修改试卷状态为-细目表编辑完成-修改试卷状态后 课程题型关联就不能再编辑了
		try {
			this.testPaperService.updateTestPaper(currPaper.getPaperNo(), status);
			MainPaneController mainController = (MainPaneController)StageManager.CONTROLLER.get("mainPaneController");
			mainController.selectPaperTable();
		} catch (SQLException e) {
			LOGGER.error(e);
		}
	}

	@Deprecated
	private void cleanAndReCreateDocx(File quesDir, TestPaper currPaper, Map<Integer, CourseQuestion> cqMap, List<DetailTable> tableList) {
		//删除之前的docx
		for (File f : quesDir.listFiles()) {
			try {
				f.deleteOnExit();
			} catch(Exception e) {
				LOGGER.error(e);
			}
		}
		//重新创建docx
		int baseOrd = 0;
		for (DetailTable table : tableList) {
			if (table.getQuestionTypeId() > 0) {
				try {
					baseOrd = this.createTableSubjectOrDocx(table, currPaper, cqMap, quesDir, baseOrd, true, true);//只创建每个题目对应的文档
				} catch (Exception e) {
					LOGGER.error(e);
				}
			}
		}
	}
		
	private boolean checkDetailTableValid(List<DetailTable> tableList, String keyChapters) {
		boolean existErr = false;
		Double totalScore = 0.0;
		for (int i=0; i<tableList.size(); i++) {
			DetailTable table = tableList.get(i);
			if (table.getQuestionTypeId() > 0) {
				//校验前端数据
				if (table.getItemScore() == 0) {
					existErr = true;
					DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.WARNING, "提示", "请录入小题分!");
					break;
				}
				int rowTotal = this.getRowQuestionNums(table);
				if (rowTotal != table.getQuesNums()) {//大于课程题型映射里面指定数量报错
					existErr = true;
					DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.WARNING, "提示", "第" + (i+1) + "行题量数必须为" + table.getQuesNums());
					break;
				}
				if (StringUtils.isNotEmpty(keyChapters)) {
					String[] arr = keyChapters.split(",");
					for (String chapter : arr) {
						try {
							Method m1 = DetailTable.class.getMethod("getTx" + chapter + "Nums", null);
							Method m2 = DetailTable.class.getMethod("getItemScore", null);
							Object nums = m1.invoke(table, null);
							Object score = m2.invoke(table, null);
							totalScore += (Integer.valueOf(nums.toString()) * Double.valueOf(score.toString()));
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
		if (StringUtils.isNotEmpty(keyChapters) && totalScore < 60) {
			existErr = true;
			DialogUtil.showAlertDialog(GUIState.getStage(), AlertType.ERROR, "错误", "重点章节总分不能低于60!");
		}
		//验证重点章节 题目 分数必须>=60
		return existErr;
	}

	private File preparePaperDir(TestPaper currPaper) {
		//历史保存
		File quesDir = null;
		try {
			List<DetailTable> oldList = detailTableService.selectDetailTable(currPaper.getPaperNo());
			String baseDir = System.getProperty("user.dir") + File.separator + "papers" + File.separator;
			String paperPrefix = currPaper.getPaperNo().substring(0, currPaper.getPaperNo().length() - 1);//下面有AB卷目录
			if (oldList == null || oldList.size() == 0) {
				//创建试卷总目录
				File paperDir = new File(baseDir + paperPrefix + File.separator + currPaper.getPaperNo());
				if (!paperDir.exists()) {
					paperDir.mkdirs();
				}
				quesDir = new File(paperDir.getAbsolutePath() + File.separator + "ques");//存放了 题型和答案
				File qsDir = new File(paperDir.getAbsolutePath() + File.separator + "qs");//存放了 试题
				File asDir = new File(paperDir.getAbsolutePath() + File.separator + "as");//存放了 答案
				File bakDir = new File(paperDir.getAbsolutePath() + File.separator + "bak");//存放备份试卷
				FileUtils.deleteDirectory(quesDir);
				FileUtils.deleteDirectory(qsDir);
				FileUtils.deleteDirectory(asDir);
				FileUtils.deleteDirectory(bakDir);
				quesDir.mkdir();
				qsDir.mkdir();
				asDir.mkdir();
				bakDir.mkdir();
				//创建试卷空文档,答案空文档-并写入 试卷头
				String paperDocPath = paperDir.getAbsolutePath() + File.separator + currPaper.getPaperNo() + ".docx";
				String answerDocPath = paperDir.getAbsolutePath() + File.separator + currPaper.getPaperNo() + "N.docx";
				String bakPaperPath = bakDir.getAbsolutePath() + File.separator + currPaper.getPaperNo() + ".docx";
				String emptyDocx = System.getProperty("user.dir") + File.separator + "resources" + File.separator + "word-factory" + File.separator + "empty.docx";
				FileUtils.copyFile(new File(emptyDocx), new File(paperDocPath));//生成空的word-具有xml格式
				FileUtils.copyFile(new File(emptyDocx), new File(answerDocPath));//生成空的word-具有xml格式
				FileUtils.copyFile(new File(emptyDocx), new File(bakPaperPath));//生成空的备份word-具有xml格式
			} else {
				quesDir = new File(baseDir + currPaper.getPaperNo().substring(0, currPaper.getPaperNo().length() - 1) + File.separator +  currPaper.getPaperNo() + File.separator + "ques");
			}
		} catch (Exception e1) {
			LOGGER.error(e1);
		}
		return quesDir;
	}
	
	//按照题目类型分组 存放题目.
	private Map<String,Integer> getSubjectChapterMap(String paperNo) {
		Map<String,Integer> map = new HashMap<String, Integer>();
		try {
			return this.subjectService.findSubjectChapterDist(paperNo);
		} catch (SQLException e) {
			LOGGER.error(e);
		}
		return map;
	}
	
	//获取每行用户输入的题目数
	private int getRowQuestionNums(DetailTable table) {
		int total = 0;
		total += table.getTx0Nums();
		total += table.getTx1Nums();
		total += table.getTx2Nums();
		total += table.getTx3Nums();
		total += table.getTx4Nums();
		total += table.getTx5Nums();
		total += table.getTx6Nums();
		total += table.getTx7Nums();
		total += table.getTx8Nums();
		total += table.getTx9Nums();
		total += table.getTx10Nums();
		total += table.getTx11Nums();
		total += table.getTx12Nums();
		total += table.getTx13Nums();
		total += table.getTx14Nums();
		total += table.getTx15Nums();
		total += table.getTx16Nums();
		total += table.getTx17Nums();
		total += table.getTx18Nums();
		total += table.getTx19Nums();
		total += table.getTx20Nums();
		total += table.getTx21Nums();
		total += table.getTx22Nums();
		total += table.getTx23Nums();
		total += table.getTx24Nums();
		total += table.getTx25Nums();
		return total;
	}
	
	//试卷题目存在时修改对应改变了章节的题目-避免全部删除
	private boolean isModified(TestPaper paper, DetailTable table, Map<String,Integer> chapterDistMap, Map<Integer, CourseQuestion> cqMap, File quesDir) {
		if ((table.getTx1Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_1") && chapterDistMap.get(table.getQuestionTypeId() + "_1") != null)
				|| (table.getTx2Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_2") && chapterDistMap.get(table.getQuestionTypeId() + "_2") != null)
				|| (table.getTx3Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_3") && chapterDistMap.get(table.getQuestionTypeId() + "_3") != null)
				|| (table.getTx4Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_4") && chapterDistMap.get(table.getQuestionTypeId() + "_4") != null)
				|| (table.getTx5Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_5") && chapterDistMap.get(table.getQuestionTypeId() + "_5") != null)
				|| (table.getTx6Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_6") && chapterDistMap.get(table.getQuestionTypeId() + "_6") != null)
				|| (table.getTx7Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_7") && chapterDistMap.get(table.getQuestionTypeId() + "_7") != null)
				|| (table.getTx8Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_8") && chapterDistMap.get(table.getQuestionTypeId() + "_8") != null)
				|| (table.getTx9Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_9") && chapterDistMap.get(table.getQuestionTypeId() + "_9") != null)
				|| (table.getTx10Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_10") && chapterDistMap.get(table.getQuestionTypeId() + "_10") != null)
				|| (table.getTx11Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_11") && chapterDistMap.get(table.getQuestionTypeId() + "_11") != null)
				|| (table.getTx12Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_12") && chapterDistMap.get(table.getQuestionTypeId() + "_12") != null)
				|| (table.getTx13Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_13") && chapterDistMap.get(table.getQuestionTypeId() + "_13") != null)
				|| (table.getTx14Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_14") && chapterDistMap.get(table.getQuestionTypeId() + "_14") != null)
				|| (table.getTx15Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_15") && chapterDistMap.get(table.getQuestionTypeId() + "_15") != null)
				|| (table.getTx16Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_16") && chapterDistMap.get(table.getQuestionTypeId() + "_16") != null)
				|| (table.getTx17Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_17") && chapterDistMap.get(table.getQuestionTypeId() + "_17") != null)
				|| (table.getTx18Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_18") && chapterDistMap.get(table.getQuestionTypeId() + "_18") != null)
				|| (table.getTx19Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_19") && chapterDistMap.get(table.getQuestionTypeId() + "_19") != null)
				|| (table.getTx20Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_20") && chapterDistMap.get(table.getQuestionTypeId() + "_20") != null)
				|| (table.getTx21Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_21") && chapterDistMap.get(table.getQuestionTypeId() + "_21") != null)
				|| (table.getTx22Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_22") && chapterDistMap.get(table.getQuestionTypeId() + "_22") != null)
				|| (table.getTx23Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_23") && chapterDistMap.get(table.getQuestionTypeId() + "_23") != null)
				|| (table.getTx24Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_24") && chapterDistMap.get(table.getQuestionTypeId() + "_24") != null)
				|| (table.getTx25Nums() != chapterDistMap.get(table.getQuestionTypeId() + "_25") && chapterDistMap.get(table.getQuestionTypeId() + "_25") != null)
				) {
			return true;
		}
		return false;
	}
	
	private void createBigQuestionInfo(File quesDir, CourseQuestion cq) {
		NumberFormat format = NumberFormat.getInstance();
		Map<Integer, String> map = new HashMap<Integer, String>();
		map.put(1, "一、");map.put(2, "二、");map.put(3, "三、");map.put(4, "四、");map.put(5, "五、");map.put(6, "六、");map.put(7, "七、");
		map.put(8, "八、");map.put(9, "九、");map.put(10, "十、");map.put(11, "十一、");map.put(12, "十二、");
		String bigCaption = map.get(cq.getOrd()) + cq.getQuesTypeName();;
		
		String docPath = quesDir.getAbsolutePath() + File.separator + (cq.getOrd() * 100) + ".docx";
		//创建大题描述
		DocUtil.genBigQsWord("bigQus.ftl", docPath, cq.getQuesNums(), format.format(cq.getScore()), format.format(cq.getQuesNums() * cq.getScore()), bigCaption, cq.getQuideText());
	}
	
	//之前没创建过题目，直接创建
	private Integer createTableSubjectOrDocx(DetailTable table, TestPaper paper, Map<Integer, CourseQuestion> cqMap, File quesDir, Integer baseOrd,
			boolean blnCreateRecord, boolean blnCreateDocx) throws Exception {
		CourseQuestion cq = cqMap.get(table.getQuestionTypeId());
		if (blnCreateDocx) {
			//创建该题型的-大题描述
			createBigQuestionInfo(quesDir, cq);
		}
		
		Class<DetailTable> CLAZZ = DetailTable.class;
		for (int m=0; m<=SysConst.MAX_CHAPTERS; m++) {
			Object objNums = CLAZZ.getMethod("getTx" + m + "Nums", null).invoke(table, null);
			if (objNums != null) {
				Integer txNums = Integer.valueOf(objNums.toString());
				for (int i=1; i<=txNums; i++) {
					if (blnCreateRecord) {
						this.createSubjectDbRecord(table, m + "", baseOrd);
					}
					if (blnCreateDocx) {
						this.createSubjectDocx(quesDir, cq, m + "", baseOrd);
					}
					baseOrd ++;
				}
			}
		}
		return baseOrd;
	}
	
	//创建word 试题信息
	private void createSubjectDocx(File quesDir, CourseQuestion cq, String chapters, Integer baseOrd) {
		String docPath = quesDir.getAbsolutePath() + File.separator + (baseOrd + 1) + ".docx";
		//准备写入的内容
		String qsNo = "";
		if (cq.getQuesTypeId() == LtContext.TYPE_SINGLE_SELECT_ID || "单项选择题".equals(cq.getQuesTypeName())) {
			//qsNo = (baseOrd + 1) + ".";
			qsNo = (baseOrd + 1) + "";
			DocUtil.genSmSingleSelect("smSingleSelect.ftl", docPath, qsNo);
		} else if (cq.getQuesTypeId() == LtContext.TYPE_MULTI_SELECT_ID || "多项选择题".equals(cq.getQuesTypeName())) {
			qsNo = (baseOrd + 1) + "";
			DocUtil.genSmMultiSelect("smMultiSelect.ftl", docPath, qsNo);
		} else {
			qsNo = (baseOrd + 1) + "";
			DocUtil.genSmOther("smQsOther.ftl", docPath, qsNo);
		}
	}
	//创建DB 试题信息
	private void createSubjectDbRecord(DetailTable table, String chapters, int baseOrd)
			throws SQLException {
		Subject subject = new Subject();
		subject.setCourseId(table.getCourseId());
		subject.setQuestionTypeId(table.getQuestionTypeId());
		subject.setScore(table.getItemScore());
		subject.setTestPaperId(table.getPaperNo());
		subject.setChapter(chapters);//题目所属章节
		subject.setOrd(baseOrd + 1);
		subject.setAnswer((baseOrd + 1) + ".docx");//暂时把题目对应的文档名称存这个字段!
		this.subjectService.insertSubject(subject);
	}
	
	/**
	 * 试卷编辑中导出word--查询已保存的导出
	 * @param event
	 * @throws SQLException 
	 */
	/*public void doExportFunc() throws SQLException {
		TestPaper select = LtContext.CURR_PAPER;
		List<DetailTable> tableList = detailTableService.selectDetailTable(select.getPaperNo());
		String savePath = System.getProperty("user.dir") + File.separator + "papers" + File.separator;
		exportPaperLogic(select, tableList, savePath);
	}*/
	
	/**
	 * 导出细目表.
	 */
	public void doExpDtFunction() {

	}
	
	/**
	 * 导出word--从webview获取数据
	 * @param event
	 */
	/*public void exportFunc(ActionEvent event) {
		TestPaper select = LtContext.CURR_PAPER;
		String str = (String)webEngine.executeScript("getPageData();");
		List<DetailTable> tableList = JSON.parseArray(str, DetailTable.class);
		String savePath = System.getProperty("user.dir") + File.separator + "papers" + File.separator;
		exportPaperLogic(select, tableList, savePath);
	}*/

	/*private void exportPaperLogic(TestPaper select, List<DetailTable> tableList, String savePath) {
		List<Subject> allSubList = new ArrayList<Subject>();
		//所有题型map
		Map<Integer, QuestionType> qsMap = this.getQuestionTypeMap();
		//所有的选项map
		Map<Integer, List<SubjectOption>> optionMap = this.getSubjectOptionMap();
		int bigPrefix = 1;
		for (DetailTable table : tableList) {
			try {
				List<Subject> subList = subjectService.findSubjectList(select.getPaperNo(), table.getQuestionTypeId());
				for (Subject subject : subList) {
					List<SubjectOption> optionList = optionMap.get(subject.getSubjectId());
					//int ques = this.getQuestions(table);
					if (optionList == null) {
						optionList = new ArrayList<SubjectOption>();
					} else {
						if (optionList.size() > ques) {
							optionList = optionList.subList(0, ques);//只要细目表配置的题目数，多余的题目不要  ?
						}
					}
					subject.setOptions(optionList);
					subject.setSubjectNo(String.valueOf(bigPrefix));
					subject.setQuestionSum(subList.size());//大类对应的题目数,eg：单项选择题大类包括几个选择题
					subject.setQuestionScores(subList.size() * subject.getScore());//大类题目的总分
					subject.setSortNo(DocUtil.getQuestionPrefix(bigPrefix));//大类题目前序号,一二三
					subject.setTypeCaption(qsMap.get(subject.getQuestionTypeId()) != null ? qsMap.get(subject.getQuestionTypeId()).getName() : "");
				}
				allSubList.addAll(subList);
			} catch (SQLException e) {
				e.printStackTrace();
			}
			bigPrefix++;
		}
		//选择目录导出
		this.selectDirAndSave(allSubList, select.getCourseCode(), select.getCourseName(), select.getPaperNo(), savePath);
	}*/
	
	private void selectDirAndSave(List<Subject> allSubList, String courseCode, String courseName, String paperNo, String savePath) {
		try {
			Users user = userService.selectUserByCourseCode(courseCode);
			List<DetailTable> tableList = detailTableService.selectDetailTable(LtContext.CURR_PAPER.getPaperNo());//细目表信息
			File fDir = new File(savePath);
			if (!fDir.exists()) {
				fDir.mkdirs();
			}
			
			Alert confirm = new Alert(Alert.AlertType.CONFIRMATION,
					"", 
					new ButtonType("通用卡", ButtonData.YES),
	                new ButtonType("专用卡", ButtonData.NO),
	                new ButtonType("取消", ButtonData.CANCEL_CLOSE));
			confirm.setTitle("请选择");
			confirm.setHeaderText("答题卡制作说明");
			confirm.initOwner(GUIState.getStage());
			Optional<ButtonType> btnType = confirm.showAndWait();
			if (btnType.get().getButtonData().equals(ButtonData.YES)) {//通用卡
				DocUtil.expQuestionGenWord("paper-nomal.ftl", savePath, allSubList, courseCode, courseName, paperNo);//试卷
				DocUtil.expAnswerGenWord(savePath, allSubList, courseCode, courseName, paperNo);//答案
				DocUtil.expPrintCard(savePath, courseCode, courseName, paperNo, "通用答题卡");
				DocUtil.expQuestionGenWordCover(savePath, courseCode, courseName, paperNo,user); //命题纸封面
				DocUtil.expAnswerGenCover(savePath, courseCode, courseName, paperNo,user); //答题纸封面
				DocUtil.expSelfAuditItemList(savePath,paperNo,user); //自考省级命题自审项目表 导出
				DocUtil.expPaperDetailTable(savePath, courseCode, courseName, paperNo,user,tableList); //导出细目表
			} else if (btnType.get().getButtonData().equals(ButtonData.NO)) {//专用卡
				DocUtil.expQuestionGenWord("paper-special.ftl", savePath, allSubList, courseCode, courseName, paperNo);
				DocUtil.expAnswerGenWord(savePath, allSubList, courseCode, courseName, paperNo);
				DocUtil.expPrintCard(savePath, courseCode, courseName, paperNo, "专用答题卡");
				DocUtil.expQuestionGenWordCover(savePath, courseCode, courseName, paperNo,user); //命题纸封面
				DocUtil.expAnswerGenCover(savePath, courseCode, courseName, paperNo,user); //答题纸封面
				DocUtil.expSelfAuditItemList(savePath,paperNo,user); //自考省级命题自审项目表 导出
				DocUtil.expPaperDetailTable(savePath, courseCode, courseName, paperNo,user,tableList); //导出细目表
			} else if (btnType.get().getButtonData().equals(ButtonData.CANCEL_CLOSE)) {
				
			}
		} catch(Exception e) {
			LOGGER.error(e);
		}
	}
	
	private void freshDetailTable(String testPaperId) {
		//查询
		List<DetailTable> tableList;
		try {
			tableList = detailTableService.selectDetailTable(testPaperId);
			webEngine.executeScript("loadDetailTable('" + JSON.toJSONString(tableList) +"');");
		} catch (SQLException e) {
			LOGGER.error(e);
		}
	}
	
	//删除题型后 刷新下拉框
	public void freshQuestionDelete(Integer id) {
		webEngine.executeScript("deleteQuestion("+ id +");");
	}
	//增加题型后 刷新下拉框
	public void freshQuestionAdd(QuestionType questionType) {
		String json = JSON.toJSONString(questionType);
		webEngine.executeScript("addQuestion('"+ json +"');");
	}
	
	public void goEditSubjectFunc(ActionEvent event) {
		((Node) (event.getSource())).getScene().getWindow().hide();
		try {
			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/view/SubjectMainView.fxml"));
			Parent root = fxmlLoader.load();
			Stage stage = new Stage();
			stage.setResizable(false);
			stage.setTitle("(" + LtContext.CURR_PAPER.getCourseCode() + ") " + LtContext.CURR_PAPER.getCourseName() + "-" + LtContext.CURR_PAPER.getPaperNo());
			stage.setScene(new Scene(root));
			//stage.setAlwaysOnTop(true);
			stage.setMaximized(false);
			Rectangle2D screen = Screen.getPrimary().getVisualBounds();
			stage.setX(screen.getMinX());
			stage.setY(screen.getMinY());
			stage.setWidth(screen.getWidth());
			stage.setHeight(screen.getHeight());
			stage.show();
		} catch (IOException e) {
			LOGGER.error(e);
		}
	}
}
